我很兴奋此代码由用户 @egreg 提供当您将鼠标悬停在某个字符上时,我将使用它来显示汉字笔画顺序的图像。
我根据自己的使用情况稍微修改了一下代码,最终得到了这样的效果(注意我使用了字体韩王凯MediumChuIn_wp010-08.ttf,因此需要下载如果有人希望使用字体):
\documentclass[a6paper,12pt]{scrbook}
\usepackage{fontspec}
\setmainfont{HanWangKaiMediumChuIn_wp010-08}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% tooltips with LaTeX
%
% optimized for Adobe Reader (visible on mouse-over)
% usage: \tooltip[<link colour>]{<link text>}[<tip box colour>]{<tip text>}
% non-draggable version:
% usage: \tooltip*[<link colour>]{<link text>}[<tip box colour>]{<tip text>}
%
% for Evince (visible on click, not draggable)
% usage: \tooltip**[<link colour>]{<link text>}[<tip box colour>]{<tip text>}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{pdfbase}[2017/03/16]
\usepackage{xparse,ocgbase}
\usepackage{xcolor,calc}
\usepackage{tikz}
\usetikzlibrary{calc}
\ExplSyntaxOn
\let\tpPdfLink\pbs_pdflink:nn
\let\tpPdfAnnot\pbs_pdfannot:nnnn\let\tpPdfLastAnn\pbs_pdflastann:
\let\tpAppendToFields\pbs_appendtofields:n
\def\tpPdfXform{\pbs_pdfxform:nnnnn{1}{1}{}{}}
\let\tpPdfLastXform\pbs_pdflastxform:
\ExplSyntaxOff
\makeatletter
\NewDocumentCommand{\tooltip}{ssO{blue}mO{yellow!20}m}{{%
\leavevmode%
\IfBooleanT{#1}{%
\ocgbase@new@ocg{tipOCG.\thetcnt}{%
/Print<</PrintState/OFF>>/Export<</ExportState/OFF>>%
}{false}%
\xdef\tpTipOcg{\ocgbase@last@ocg}%
}%
\tpPdfLink{%
\IfBooleanTF{#2}{%
/Subtype/Link/Border [0 0 0]/A <</S/SetOCGState/State [/Toggle \tpTipOcg]>>
}{%
/Subtype/Screen%
\IfBooleanTF{#1}{%
/AA<<%
/E<</S/SetOCGState/State [/ON \tpTipOcg]>>%
/X<</S/SetOCGState/State [/OFF \tpTipOcg]>>%
>>%
}{
/AA<<%
/E<</S/JavaScript/JS(%
var fd=this.getField('tip.\thetcnt');%
\IfBooleanF{#1}{%
if(typeof(click\thetcnt)=='undefined'){%
var click\thetcnt=false;%
var fdor\thetcnt=fd.rect;var dragging\thetcnt=false;%
}%
}%
if(fd.display==display.hidden){%
fd.delay=true;fd.display=display.visible;fd.delay=false;%
}%
this.dirty=false;%
)>>%
/X<</S/JavaScript/JS(%
if(!click\thetcnt&&!dragging\thetcnt){fd.display=display.hidden;}%
if(!dragging\thetcnt){click\thetcnt=false;}%
this.dirty=false;%
)>>%
/U<</S/JavaScript/JS(click\thetcnt=true;this.dirty=false;)>>%
/PC<</S/JavaScript/JS (%
var fd=this.getField('tip.\thetcnt');%
try{fd.rect=fdor\thetcnt;}catch(e){}%
fd.display=display.hidden;this.dirty=false;%
)>>%
/PO<</S/JavaScript/JS(this.dirty=false;)>>%
>>%
}
}%
}{{\color{#3}#4}}%
\sbox\tiptext{\fcolorbox{black}{#5}{#6}}%
\edef\twd{\the\wd\tiptext}%
\edef\tht{\the\ht\tiptext}%
\edef\tdp{\the\dp\tiptext}%
\tpPdfXform{\tiptext}%
%tip box placed at top left page corner
\begin{tikzpicture}[remember picture,overlay]
\node [inner sep=0pt, anchor=base] at (current page.north west) {%
\raisebox{-\tht}[0pt][0pt]{%
\tpPdfAnnot{\twd}{\tht}{\tdp}{%
/Subtype/Widget/FT/Btn/T (tip.\thetcnt)%
/AP<</N \tpPdfLastXform>>%
/MK<</TP 1/I \tpPdfLastXform/IF<</S/A/FB true/A [0.0 0.0]>>>>%
\IfBooleanTF{#1}{%
/Ff 65537/OC \tpTipOcg%
}{%
/Ff 65536/F 3%
/AA <<%
/U <<%
/S/JavaScript/JS(%
var fd=event.target;%
var mX=this.mouseX;var mY=this.mouseY;%
var drag=function(){%
var nX=this.mouseX;var nY=this.mouseY;%
var dX=nX-mX;var dY=nY-mY;%
var fdr=fd.rect;%
fdr[0]+=dX;fdr[1]+=dY;fdr[2]+=dX;fdr[3]+=dY;%
fd.rect=fdr;mX=nX;mY=nY;%
};%
if(!dragging\thetcnt){%
dragging\thetcnt=true;Int=app.setInterval("drag()",1);%
}%
else{app.clearInterval(Int);dragging\thetcnt=false;}%
this.dirty=false;%
)%
>>%
>>%
}%
}%
\tpAppendToFields{\tpPdfLastAnn}%
}%
};
\end{tikzpicture}
\stepcounter{tcnt}%
}}
\makeatother
\newsavebox\tiptext\newcounter{tcnt}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ExplSyntaxOn
\NewDocumentCommand{\tooltips}{sO{}m+O{}}
{
\tl_map_inline:nn { #3 }
{
\IfBooleanTF{#1}{\tooltip*}{\tooltip*}{##1}{\includegraphics[#2]{images/##1}}#4
}
}
\ExplSyntaxOff
\begin{document}
\tooltips[scale=1]{高一生}
\end{document}
另请注意:请务必编译两次。
但是,代码旨在查找与角色同名的图像。例如,如果将鼠标悬停在角色上高
,代码当前会查找图像高.png
(在文件夹 images 中)。
现在,它被设计用于处理大量的汉字。事实上,我有成千上万个这样的汉字所需的图像。不幸的是,这些图像没有命名,例如高.png
,甚至没有U+9AD8.png
(统一坐标系统该角色),但现在被命名为B0AA.png
,这是Big-5该字符的编码。
因此,我有两个选择可以使该代码可行。
- 或者,我必须批量将每个人的名字转换
.png
成各自的中文字符(例如B0AA.png
转换成高.png
)。但我不知道该怎么做。有没有办法用 Tex 来做到这一点? - 或者。我怎样才能修改上面的代码,以便代码能够将每个字符“转换”
\tooltips[scale=1]{高一生}
为Big-5编码,但仅在寻找每个字符的相应图像时(因此\tooltips[scale=1]{高一生}
仍然会显示高一生
但分别寻找图像B0AA.png
、A440.png
和A5CD.png
)。
有人能提供解决方案吗?
请注意,我有一个。TXT文件可以用作转换表,因为它列出了所有必要的字符:
UCS Big5
UCS Big5
UCS Big5
... ...
对于 M(尚未)WE 示例的目的,可以使用以下最小。TXT文件,其中包含统一坐标系统(左)和Big5(右)代码高一生:
U+9AD8 B0AA
U+4E00 A440
U+751F A5CD
顺便说一句,如果你想使用我正在使用的图像,你可以在以下网址找到它们:
http://stroke-order.learningweb.moe.edu.tw/words/B0AA.png
在 http://stroke-order.learningweb.moe.edu.tw/words/A440.png
以及 http://stroke-order.learningweb.moe.edu.tw/words/A5光盘.png
也就是说,对于高一生。务必将它们放在名为“图片“ 在您的主.tex文件。
最后,此代码应该生成.pdf要查看的文件Adobe Acrobat 阅读器。我不需要受特定编译方法的约束,但我成功编译此代码的唯一方法是使用LuaLaTeX
。根据@David Carlisle 的这个回答,XeTeX
可能是另一种选择,但我不知道我必须做出哪些细微的改变。
答案1
在这两个选项中,更好的解决方案可能是重命名所有文件(例如重命名B0AA.png
为高.png
),假设您处理这些文件的所有工具都能够处理此类文件名,并且假设您可以轻松地阅读和区分这些文件名。但 TeX 不是此类文件系统操作的好工具。
另一种选择在 TeX 中是可行的:当您在 TeX 中指定文件名时,您可以将每个字符转换为其 Big5 编码,从而解决问题。这种编程即使在 TeX 宏中也是可行的,但是当您使用 LuaTeX 时,它会变得容易得多。
Lua 本身不理解 Unicode;UTF-8 编码的字节字符串对 Lua 来说只是一个字节字符串。但这不是问题;下面我用 Lua 编写了一个简单的 UTF-8 解码器。
以下 Lua 和 TeX 文件定义了一个宏\bigfive
,您可以键入它\bigfive{高}
,它将扩展(等效于)B0AA
为该字符的 Big5 编码。Lua 代码可以放在文件中.tex
,但我更喜欢将其放在一个单独的文件中big5.lua
(例如):
function ucsFromChar(s)
-- UTF-8 decoder. Given a valid UTF-8-encoded character s, returns the number (codepoint) it encodes.
-- A stricter version is at https://gist.github.com/shreevatsa/6aef61aafd4ccfe2149ddacdc5c5855d
local n = string.byte(s, 1)
if n < 128 then return n end -- Starts with a 0
if n < 224 then -- Starts with 110, so get remaining 5 bits, then 6 bits from next byte
return (n - 192) * 64 + string.byte(s, 2) - 128
elseif n < 240 then -- Starts with 1110, so get remaining 4 bits, then 6 bits each from next 2 bytes
return ((n - 224) * 64 + string.byte(s, 2) - 128) * 64 + string.byte(s, 3) - 128
else -- Starts with 11110, so get remaining 3 bits, then 6 bits each from next 3 bytes
return (((n - 240) * 64 + string.byte(s, 2) - 128) * 64 + string.byte(s, 3) - 128) * 64 + string.byte(s, 4) - 128
end
end
map = nil -- Populated and used by getMap() below.
function getMap()
-- Returns map from a file containing a space-separated key-value pair per line.
if map ~= nil then return map end
map = {}
for line in io.open('map.txt', 'r'):lines() do
local key = nil
for s in string.gmatch(line, "%S+") do
if key ~= nil then map[key] = s else key = s end
end
end
return map
end
function big5FromChar(s)
local u = string.upper(string.format('U+%x', ucsFromChar(s)))
-- return getMap()[u]
local v = getMap()[u]
if v ~= nil then return v else return s end
end
这假设(如问题所述)您有一个map.txt
包含如下行的文件:
U+9AD8 B0AA
U+4E00 A440
U+751F A5CD
这样,.tex
文件就可以只是:
\documentclass{article}
\usepackage{fontspec}
\setmainfont{AppleGothic}
\directlua{dofile('big5.lua')}
\newcommand{\bigfive}[1]{\directlua{tex.sprint(big5FromChar('#1'))}}
\begin{document}
Anywhere in my document I can use the \verb+\bigfive+ macro.
For example, 高 is \bigfive{高} in big5.
\end{document}
上述代码生成: