summaryrefslogtreecommitdiff
path: root/macros/plain/contrib/pitex/verbatim.ptx
blob: a4e2a7ed2b350c78a3060f6996228bfc725fbae7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
% Verbatim facilities.
\newcatcodetable\verbcatcodes{\\\{\}\$\&\#\^\_\~\%=12,\ \^^M=13}

\def\verb#1{%
  \def\ptx@verb##1#1{\ptx@verb_punc{}{##1}\egroup}%
  \bgroup
  \catcodetable\verbcatcodes
  \iffcommand\codefont\codefont
  \ptx@verb
  }

% Hack to prevent French spacing before punctuation. I should find
% something better (attributes marking material to be left alone when
% the French punctuation kicks in in the "kerning" callback).
\def\ptx@verb_punc#1#2{%
  \ifelseif{%
    {\ifcontains:{#2}} {\splitstringat:{#2}{\ptx@verb_glue{#1}:}}
    {\ifcontains;{#2}} {\splitstringat;{#2}{\ptx@verb_glue{#1};}}
    {\ifcontains!{#2}} {\splitstringat!{#2}{\ptx@verb_glue{#1}!}}
    {\ifcontains?{#2}} {\splitstringat?{#2}{\ptx@verb_glue{#1}?}}
     \iftrue           {#1#2}}%
  }
\def\ptx@verb_glue#1#2#3#4{%
  \ptx@verb_punc{#1#3\kern0pt#2}{#4}%
  }

\bgroup
\setcatcodes{\ \^^M=13}%
\gdef {\quitvmode\spacecs}%
\gdef^^M{\quitvmode\par}%
\egroup

\def\tcode#1{{\codefont#1}}
\long\def\com#1{%
  \bgroup
    \codefont
    \string#1%
  \egroup
  \antigobblespace
  }
\freedef\arg{{\codefont\it<#1>}\iffnext\spacechar{\kern.2ex }}
\freedef\barg{{\codefont\char"007B\relax\arg{#1}\char"007D\relax}}
\freedef\oarg{{\codefont[\arg{#1}]}}

\luacode
pitex.verbatims = {}
local function prepare_verbatim (chunk, name)
	return function (str)
    if not str:match("^%s*\noexpand\\" .. chunk .. "/") then
      table.insert(pitex.verbatims[name], str)
      return "%"
    else
      pitex.callback.remove("process_verbatim", "process_input_buffer")
      return "\noexpand\\usecs{ptx@inner_verbatimstop:" .. chunk .. "}"
    end
  end
end

function install_verbatim (chunk, regime, name)
	pitex.verbatims[name] = { regime = regime }
  pitex.callback.process_verbatim = prepare_verbatim(chunk, name)
  pitex.callback.register("process_input_buffer", "process_verbatim")
end

function do_verbatim(name, exec)
	if exec then
    tex.print(pitex.verbatims[name])
  else
    tex.print(pitex.verbatims[name].regime, pitex.verbatims[name])
  end
end
\luacode/

\def\ptx@verbatim_last{}

\def\newverbatim#1{%
  \ifnext[
    {\ptx@newverbatim#1}
    {\ptx@newverbatim#1[\verbcatcodes]}%
  }

\long\def\ptx@newverbatim#1[#2]#3#4{%
  \edef#1{%
    \bgroup\primunexpanded{#3}%
    \bgroup\primunexpanded{\setcatcodes{\^^M=12}}%
    \noexpand\ptx@verbatim{\commandtoname#1}{#2}}%
  \defcs{ptx@inner_verbatimstop:\commandtoname#1}{#4\egroup}%
  }

\bgroup
\setcatcodes{\^^M=12}%
\gdef\ptx@verbatim#1^^M{%
  \egroup%
  \ptx@verbatim_prepare#1\relax%
  }%
\egroup

\def\ptx@verbatim_prepare#1#2{%
  \ifnext[
    {\ptx@verbatim_do{#1}{#2}}
    {\ptx@verbatim_do{#1}{#2}[last]}%
  }

\def\ptx@verbatim_do#1#2[#3]{%
  \gdef\ptx@verbatim_last{#3}%
  \directlua{install_verbatim("#1", \the#2, "#3")}%
  }

\newverbatim\verbatim{}
                     {\codefont\parindent0pt %\hsize=\maxdimen
                      \directlua{pitex.callback.close("french_punctuation", "kerning")}\relax
                      \vskip\baselineskip\printverbatim\relax
                      \directlua{pitex.callback.open("french_punctuation", "kerning")}
                      \vskip\baselineskip\removenextindent}

\def\doverbatim{%
  \ifnext[
    {\ptx@doverbatim{true}}
    {\ptx@doverbatim{true}[\ptx@verbatim_last]}%
  }
\def\printverbatim{%
  \ifnext[
    {\ptx@doverbatim{nil}}
    {\ptx@doverbatim{nil}[\ptx@verbatim_last]}%
  }
\def\ptx@doverbatim#1[#2]{%
  \directlua{do_verbatim("#2", #1)}%
  }