cwebmac.tex 版本 3.67 --- 2006 年 7 月
以下 Lua 代码使用 将字符串从 UTF-8 转换为 UTF-16BE tex.write
,它将打印出 catcode 12 的所有内容,除了空格,这是必需的。我们将代码添加到 的顶部cwebmac.tex
:
% from navigator.tex
\catcode`\%=12
\directlua{
local function to8 (...)
local arg, str = {...}, ""
for i, num in ipairs(arg) do
tex.write(string.char(92) .. string.format("%03o", num))
end
end
function toutf16(str)
tex.write(string.char(92) .. "376" .. string.char(92) .. "377")
for c in string.utfvalues(str) do
if c < 0x10000 then
to8(c / 256, c % 256)
else
c = c - 0x10000
local a, b = c / 1024 + 0xD800, c % 1024 + 0xDC00
to8(a / 256, a % 256, b / 256, b % 256)
end
end
end
}
\catcode`\%=14
另外,通过如下编辑来使用新toutf16
功能:cwebmac.tex
--- /usr/share/texlive/texmf-dist/tex/plain/cweb/cwebmac.tex
+++ /usr/local/cwebmac.tex
@@ -474,7 +474,7 @@
\pdfoutline goto name {NOS} count -\secno {\outsecname}
\def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
{\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
- \pdfoutline goto num \the\toksA \expandafter{\the\toksE}}
+ \pdfoutline goto num \the\toksA {\directlua{toutf16("\luaescapestring{\the\toksE}")}}}
\else\ifpdf
\special{pdf: outline -1 << /Title (\outsecname)
/Dest [ @thispage /FitH @ypos ] >>}
@@ -491,7 +491,7 @@
\expandafter\xdef\csname#1\endcsname{\the\countA}}
\def\writebookmarkline#1#2#3#4#5{{%
\let\(=\let \let\)=\let \let\[=\let \let\]=\let \let\/=\let
- \pdfoutline goto num #3 count -\expnumber{chunk#2.#3} {#5}}}
+ \pdfoutline goto num #3 count -\expnumber{chunk#2.#3} {\directlua{toutf16("\luaescapestring{#5}")}}}}
\def\con{\par\vfill\eject % finish the section names
% \ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers
\rightskip 0pt \hyphenpenalty 50 \tolerance 200
在大多数情况下,书签是正确的(顺便问一下,\expandafter
第一次更改是为了什么?)。但在这个大纲中
(
和之前有多余的反斜杠)
。为什么会出现它们?我是否使用了正确的方法来编码 PDF 轮廓?
通过在单独的文件中使用上述 lua 块和以下代码,我们表明该toutf16
函数可以正常工作(即,它不会产生反斜杠):
% ...
\pdfdest num 1 fit
\pdfoutline goto num 1 count 0 {\directlua{toutf16("\luaescapestring{Если файл дан, пробовать открыть *(++argv); continue если неудача}")}}
\bye
相反,当我们通过将其添加到 的顶部来\special{pdf:tounicode UTF8-UCS2}
完成所有操作时,一切都顺利进行:dvipdfmx
cwebmac.tex
\let\oldshipout\shipout
\def\shipout{\global\let\shipout\oldshipout\afterassignment\myboat\setbox255=}
\def\myboat{\aftergroup\myship}
\def\myship{\setbox255=\vbox{\special{pdf:tounicode UTF8-UCS2}\unvbox255}\shipout\box255}
\let\pdf+
编辑有关详细信息和更好的解决方案,请参阅这线。
答案1
toutf16
函数应该改为:
\directlua{
function toutf16(str)
tex.write(string.char(92) .. "376" .. string.char(92) .. "377")
for c in string.utfvalues(str) do
if c < 0x10000 then
tex.write(string.char(92) .. string.format("%03o", c / 256) ..
string.char(92) .. string.format("%03o", c % 256))
else
c = c - 0x10000
local c1 = c / 1024 + 0xD800
local c2 = c % 1024 + 0xDC00
tex.write(string.char(92) .. string.format("%03o", c1 / 256) ..
string.char(92) .. string.format("%03o", c1 % 256) ..
string.char(92) .. string.format("%03o", c2 / 256) ..
string.char(92) .. string.format("%03o", c2 % 256))
end
end
end
}
另外,cwebmac.tex
必须改为如下:
...
\pdfoutline goto name {NOS} count -\secno {\directlua{toutf16("\outsecname")}}
...
\pdfoutline goto num \the\toksA {\directlua{toutf16(string.gsub([[\the\toksE]],string.char(92),""))}}}
...
\pdfoutline goto num #3 count -\expnumber{chunk#2.#3} {\directlua{toutf16(string.gsub([[#5]],string.char(92),""))}}}}
...
此外, 中还有两个错误cwebmac.tex
,在 pdf 模式下使用时会出现。以下是针对这两个错误的修复。
1)这会在每个部分编号后添加额外的空间:
--- /usr/share/texlive/texmf-dist/tex/plain/cweb/cwebmac.tex
+++ cwebmac.tex
@@ -278,7 +278,7 @@
\sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
\noindent{\let\*=\lapstar\bf\secstar.\quad}%
\ifpdftex\smash{\raise\baselineskip\hbox to0pt{%
- \let\*=\empty\pdfdest num \secstar fith}}
+ \let\*=\empty\pdfdest num \secstar fith}}%
\else\ifpdf\smash{\raise\baselineskip\hbox to0pt{%
\let\*=\empty\special{%
pdf: dest (\romannumeral\secstar) [ @thispage /FitH @ypos ]}}}\fi\fi}
2)这将删除所有书签,如果\nosecs
使用:
--- /usr/share/texlive/texmf-dist/tex/plain/cweb/cwebmac.tex
+++ cwebmac.tex
@@ -457,6 +457,7 @@
\def\fin{\par\vfill\eject % this is done when we are ending the index
\ifpagesaved\null\vfill\eject\fi % output a null index column
\if L\lr\else\null\vfill\eject\fi % finish the current page
+ \ifpdftex \makebookmarks \fi
\parfillskip 0pt plus 1fil
\def\grouptitle{NAMES OF THE SECTIONS}
\let\topsecno=\nullsec
@@ -470,7 +471,7 @@
\def\Us{\note{Used in sections}} % crossref for uses of a section
\def\I{\par\hangindent 2em}\let\*=*
\ifacro \def\outsecname{Names of the sections} \let\Xpdf\X
- \ifpdftex \makebookmarks \pdfdest name {NOS} fitb
+ \ifpdftex \pdfdest name {NOS} fitb
\pdfoutline goto name {NOS} count -\secno {\outsecname}
\def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
{\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%