页面布局控制
ConTeXt 模块参数的获取

抄录(Verbatim)

Garfileo posted @ 2011年1月24日 02:12 in ConTeXt 笔记 with tags luatex ConTeXt MkIV , 7531 阅读

对于程序猿而言,如果使用 ConTeXt 进行文档排版,那么它提供的 type 和 typing 机制在程序代码抄录(程序代码排版)方面较为出色。

type 用于行内的代码抄录,typing 用于行间的代码抄录。它们的简单示例:

\starttext

This is an example \type{Hello world} of C language.

\starttyping
#include <stdio.h>

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

\stoptext

排版输出结果截图如下:

如果希望行间代码带有行号,可以:

\setuptyping[numbering=line]

\starttext

This is an example \type{Hello world} of C language.

\starttyping
#include <stdio.h>

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

\stoptext

排版输出结果截图如下:

如果期望代码行号的字体小一些,可以:

\setuplinenumbering[style=small]
\setuptyping[numbering=line]

\starttext

This is an example \type{Hello world} of C language.

\starttyping
#include <stdio.h>

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

\stoptext

排版输出结果截图如下:

如果要为代码套个外框,可以:

\setuplinenumbering[style=small]
\setuptyping
  [numbering=line,
   before=\startframedtext,
   after=\stopframedtext]

\starttext

This is an example \type{Hello world} of C language.

\starttyping
#include <stdio.h>

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

\stoptext

排版输出结果截图如下:

如果想将代码行号放在框内,可以:

\setuplinenumbering[style=small,location=text]
\setuptyping
  [numbering=line,
   before=\startframedtext,
   after=\stopframedtext]

\starttext

This is an example \type{Hello world} of C language.

\starttyping
#include <stdio.h>

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

\stoptext

排版输出结果截图如下:

如果想显示行内代码抄录中包含的空格符号,可以:

\setuplinenumbering[style=small,location=text]
\setuptype[space=on]
\setuptyping
  [numbering=line,
   before=\startframedtext,
   after=\stopframedtext]

\starttext

This is an example \type{Hello world} of C language.

\starttyping
#include <stdio.h>

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

\stoptext

排版输出结果截图如下:

如果想在抄录环境中使用 ConTeXt 控制序列,可以:

\setuplinenumbering[style=small,location=text]
\setuptype[space=on]
\setuptyping
  [numbering=line,
   before=\startframedtext,
   after=\stopframedtext,
   escape=yes]

\starttext

This is an example \type{Hello world} of C language.

\starttyping
/BTEX\inframed[framecolor=darkred]{\#include <stdio.h>}/ETEX

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

\stoptext

排版输出结果截图如下:

要注意的是,采用 \startframedtext ... \stopframedtext 作为抄录环境的外框,无法跨页显示

如果既要抄录环境的外框,还想跨页,可以:

\definetextbackground
  [verb]
  [frame=on,location=paragraph,
   leftoffset=0.5em,rightoffset=0.5em,
   topoffset=1em,bottomoffset=1em,
   rulethickness=0.75pt]

\setuplinenumbering[style=small,width=1em]
\setuptype[space=on]
\setuptyping
  [numbering=line,
   before={\blank\starttextbackground[verb]},
   after={\stoptextbackground\blank},
   escape=yes]

\starttext

This is an example \type{Hello world} of C language.

\starttyping
/BTEX\inframed[framecolor=darkred]{\#include <stdio.h>}/ETEX

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

\stoptext

排版输出结果截图:

如果将上例中的行号挪到抄录框内并保持它与抄录框左边界保持一定距离,可以:

\definetextbackground
  [verb]
  [frame=on,location=paragraph,
   topoffset=1em,bottomoffset=1em,
   rulethickness=0.75pt]

\setuplinenumbering[style=\hfil\small,width=2em,location=text]
\setuptyping
  [numbering=line,
   before={\blank\starttextbackground[verb]},
   after={\stoptextbackground\blank},
   escape=yes]

\setuptype[space=on]

\starttext

This is an example \type{Hello world} of C language.

\starttyping
/BTEX\inframed[framecolor=darkred]{\#include <stdio.h>}/ETEX

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

\stoptext

排版输出结果截图:

如 果想为抄录环境行号添加 proportional oldstyle 数字效果,那么首先要找到一款支持 onum 与 pnum 特性的 OpenType 字体。ConTeXt Minimals 自带的 texgyrepagella-regular.otf 字体是有这些特效的,可以使用 lcdf-typetools 工具包里的 otfinfo 查看 OpenType 字体特效,例如:

$ otfinfo -f texgyrepagella-regular.otf
aalt	Access All Alternates
c2sc	Small Capitals From Capitals
cpsp	Capital Spacing
dlig	Discretionary Ligatures
frac	Fractions
kern	Kerning
liga	Standard Ligatures
lnum	Lining Figures
onum	Oldstyle Figures
pnum	Proportional Figures
salt	Stylistic Alternates
size	Optical Size
smcp	Small Capitals
ss01	Stylistic Set 1
ss02	Stylistic Set 2
ss03	Stylistic Set 3
ss04	Stylistic Set 4
tnum	Tabular Figures
zero	Slashed Zero

然后,可以在抄录行号中使用 texgyrepagella-regular.otf 字体,如下:

\definetextbackground
  [verb]
  [frame=on,location=paragraph,
   topoffset=1em,bottomoffset=1em,
   rulethickness=0.75pt]

\definefontfeature[oldnum][mode=node,pnum=yes,onum=yes]
\definefontsynonym[pagella][name:texgyrepagellaregular][features=oldnum]
\definefont[OldNum][pagella]

\setuplinenumbering[style=\hfil\OldNum,width=2.5em,location=text]
\setuptyping
  [numbering=line,
   before={\blank\starttextbackground[verb]},
   after={\stoptextbackground\blank},
   escape=yes]

\setuptype[space=on]

\starttext

This is an example \type{Hello world} of C language.

\starttyping
/BTEX\inframed[framecolor=darkred]{\#include <stdio.h>}/ETEX

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping

The plain number: 0123456789.

The old number: {\OldNum 0123456789}

\stoptext

排版输出结果截图如下:

如果要高亮显示抄录文本,现在除了 C 代码有点不好处理之外,MkIV 内置支持 Lua、XML、TeX、MetaPost 代码高亮。例如:

\definetextbackground
  [verb]
  [frame=on,location=paragraph,
    topoffset=1em,bottomoffset=0pt,
    rulethickness=0.75pt,]

\definefontfeature[oldnum][mode=node,pnum=yes,onum=yes]
\definefontsynonym[pagella][name:texgyrepagellaregular][features=oldnum]
\definefont[OldNum][pagella]

\setuplinenumbering[style=\hfil\OldNum,width=2.5em,location=text]
\setuptyping
  [numbering=line,
   before={\blank\starttextbackground[verb]},
   after={\stoptextbackground\blank},
   escape=yes]

\setuptype[space=on]

\starttext

\starttyping[option=xml]
<?xml version="1.0" encoding="UTF-8"?>

<root>
  <title>
    My First XML Document
  </title>
  <para>
    Hello to the wild and wooly world of electronic
    document encoding.  
  </para>
  <note>
    (Okay, so maybe it's not that wild,
    but it can get pretty wooly.)
  </note>
<!-- No simple "Hello World" here -->
  <para>
    This page written by: 
    <ital>(insert your name here)</ital>
  </para>
  <para>
    Copyright 2000 and beyond
  </para>
</root>
\stoptyping

\stoptext

排版结果截图如下:

如果想实现 C 代码抄录高亮显示支持,也不是没有办法,可以用 t-pretty-c 模块来实现。这个模块的意义很二,首先它可以帮助我们实现 C 代码高亮,其次是它表明了 ConTeXt MkIV 的抄录高亮支持第三方实现很容易。看下面的示例:

\usemodule[pretty-c]

\starttext
\starttyping[option=c]
#include <stdio.h>

int 
main (void)
{
        printf ("Hello world!\n");
        return 0;
}
\stoptyping
\stoptext

排版输出结果截图如下:

转载时,希望不要链接文中图片,另外请保留本文原始出处:http://garfileo.is-programmer.com

milksea 说:
2011年2月12日 17:22

再拜。这回我是沙发了吧?

为什么我感到中文的 TeX geeks 都纷纷转向折腾 ConTeXt 了呢?你这么勤奋真是让人羡慕嫉妒吖。

顺便问下那个语法高亮是用 Lua 实现的词法分析么?甚至带部分语法分析?还是只是跟 listings in LaTeX 一样是基于关键字的?
必须承认 TeX 引擎内嵌脚本是个好点子,或者骂一句纯 TeX 编程太坑爹了。

Avatar_small
Garfileo 说:
2011年2月12日 20:22

@_@,稀客阿……

是用 lua 实现的,用的是那个 lpeg 库。

milksea 说:
2011年2月13日 01:51

嗯。前些时候在 stackexchange 看到有人打算用纯 TeX 写正则库,这几天也做了一些 TeX 宏的练习,就觉得 TeX 在这方面太坑爹了。

Avatar_small
views63 说:
2011年2月13日 13:24

那个 t-vim 模块也是代码高亮显示的吧
http://modules.contextgarden.net/vim

Avatar_small
Garfileo 说:
2011年2月13日 20:40

@views63: 那个是在 vim 里实现语法高亮,类似 auctex 那样子。

Avatar_small
views63 说:
2011年2月14日 01:32

@Garfileo:
在页面上看到 This module uses Vim editor's syntax files to syntax highlight verbatim code in ConTeXt
然后又在
http://blog.steamedfish.org/2010/04/07/code-hilighting-in-context/
看到:这个模块是直接调用 vim 来生成语法高亮配置的
所以我一直认为是做语法高亮的。去年试过几次老是报错,就没再去管它了。

Avatar_small
Garfileo 说:
2011年2月14日 02:45

@views63: 嗯,那看来就是了。不用 vim 很多年了,所以带 vim 字样的都被我无视了

milksea 说:
2011年2月14日 18:55

直接调用vim……真威武,那基本上什么语言都可以了,而且效果也应该不错

Avatar_small
云泽雨施 说:
2011年4月23日 10:01

mark,膜拜牛人。。。以前都用lstlisting宏包来产生代码高亮。。。ConTeXt的高亮好漂亮啊,什么时候有空学学。。再次膜拜一下博主,牛人啊,有机会向你好好学习。:)

fda 说:
2012年5月29日 10:31

怎樣在table中使用typing,編譯錯誤

Avatar_small
Garfileo 说:
2012年5月29日 13:03

@fda: 用 \startbuffer[name] ... \stopbuffer 将 typing 环境裹起来,然后在表格中使用 \getbuffer[name]。示例:

\starttext

\startbuffer[test]
\starttyping
\placetable{Caption}
{\bTABLE
\bTR \bTD One \eTD \bTD two \eTD \eTR
\bTR \bTD One \eTD \bTD two \eTD \eTR
\eTABLE}
\stoptyping
\stopbuffer

\placetable{Caption}
{\bTABLE
\bTR \bTD \getbuffer[test] \eTD \bTD two \eTD \eTR
\bTR \bTD One \eTD \bTD two \eTD \eTR
\eTABLE}

\stoptext


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter