我正在编写一个算法来检测并突出显示同源结构。
这是我当前几乎可以工作(但至少可以编译)的代码:
\documentclass{article}
\usepackage[french]{babel}
\usepackage{kpfonts}
\usepackage{luatexbase}
\usepackage{luacode}
\begin{luacode}
compare_lines = function (line1,line2)
local head1 = line1.head
local head2 = line2.head
local char_count = 0
local word_count = 0
while (head1.id == 37 and head2.id == 37
and head1.char == head2.char) -- identical glyph
or (head1.id == 10 and head2.id == 10) do -- glue
if (head1.id == 37) then -- glyph
char_count = char_count + 1
elseif (head1.id == 10) then -- glue
word_count = word_count + 1
end
head1 = head1.next
head2 = head2.next
end
return char_count,word_count,head1,head2
end
homeoarchy = function ( head )
local cur_line = head
local prev_line -- initiate prev_head
local max_char = 3
local max_word = 1
while head do
if head.id == 0 then -- new line
print("new line")
prev_line = cur_line
cur_line = head
if prev_line.id == 0 then
char_count,word_count,prev_head,cur_head = compare_lines(prev_line,cur_line)
if char_count >= max_char or word_count >= max_word then
w1_prev = node.new("whatsit","pdf_literal")
w1_prev.data = "q 1 0 1 rg"
w1_prev.mode = 1
w2_prev = node.new("whatsit","pdf_literal")
w2_prev.data = "Q"
w2_prev.mode = 1
node.insert_before(prev_line,prev_line.head.next,w1_prev)
node.insert_before(prev_line,prev_head,w2_prev)
w1_cur = node.new("whatsit","pdf_literal")
w1_cur.data = "q 1 0 1 rg"
w1_prev.mode = 1
w2_cur = node.new("whatsit","pdf_literal")
w2_cur.data = "Q"
w2_cur.mode = 1
node.insert_before(cur_line,cur_line.head.next,w1_cur)
node.insert_before(cur_line,cur_head,w2_cur)
print("done placing markers")
end
end
end
head = head.next
end
return true
end
luatexbase.add_to_callback("post_linebreak_filter",homeoarchy,"homeoarchy")
\end{luacode}
\begin{document}
\begin{minipage}{1.7in}
Je suis venu non pour juger le monde, mais pour sauver le monde. Celui qui me rejette
et qui ne re\c coit pas mes
\end{minipage}
\bigskip
\begin{minipage}{1.7in}
Je suis venu non pour juger~le monde, mais pour sauver le monde. Celui qui me rejette
et qui ne re\c coit pas mes
\end{minipage}
\bigskip
\begin{minipage}{1.7in}
Je suis venu non pour juger le monde, mais pour sauver~le monde. Celui qui me rejette
et qui ne re\c coit pas mes
\end{minipage}
\bigskip
\begin{minipage}{1.6in}
Je suis venu non pour juger le monde, mais pour sauver le monde. Celui qui me rejette
et qui ne re\c coit pas mes
\end{minipage}
\bigskip
\begin{minipage}{1.8in}
Je suis venu non pour juger le monde, mais pour sauver le monde. Celui qui me rejette
et qui ne re\c coit pas mes
\end{minipage}
\end{document}
结果:
这里很容易发现两个错误:
- 颜色从“l”之后开始,而不是之前。我尝试了各种组合,从“prev_line.head”到“prev_line.head.next.prev”,但总是出现错误,提示无法在不存在的节点前插入。我很确定“l”节点确实存在。我该如何在它之前插入?
- 文本在第二个彩色单词后停止。所以我已经为单词着色了,但我仍然想要其余的文本...我该怎么做?
答案1
代码中有几个不明显的问题。这真的很棘手!
node.insert_before(prev_line,prev_line.head.next,w1_prev)
。您永远不应该insert_before
在未分配new_head
返回值的情况下使用,因为第二个参数可能是列表的开头,并且在之前插入某些内容将需要一个新的头指针。whatsit
/技巧pdf_literal
并不真正适合运行文本,但不要问我完美的解决方案。我使用 pdftex 的 pdf colorstacks,但它们可能会在很多情况下(vsplit
以及类似情况下)中断。如果您查看生成的 pdf(使用編輯查看它)你会发现文本在 PDF 中,但不可见。
...
1 0 0 1 148.712 674.423 Tm [(jette)-204(et)-205(qui)-205(ne)-204(rec)383<b8>-70(oit)-205(pas)-204(mes)]TJ
1 0 0 1 148.712 652.062 Tm [(J)31(e)-507(suis)-508(v)17(en)15(u)-506(non)-508(pour)-507(ju-)]TJ
1 0 0 1 148.712 640.106 Tm [(g)15(er)-640(le)-641(monde,)-642(mais)-640(pour)]TJ
1 0 0 1 148.712 628.151 Tm [(sa)16(uv)18(er)-363(le)-363(monde.)-363(C)5(el)15(ui)-362(qui)]TJ
1 0 0 1 148.712 616.196 Tm [(me)-453(rejette)-454(et)-453(qui)-454(ne)-453(rec)383<b8>-70(oit)]TJ
1 0 0 1 148.712 604.241 Tm [(pas)-255(mes)]TJ
1 0 0 1 148.712 581.969 Tm [(J)31(e)-301(suis)-301(v)17(en)15(u)-300(non)-301(pour)-301(jug)14(er)]TJ
1 0 0 1 148.712 570.014 Tm [(le)-527(monde,)-527(mais)-527(pour)-527(sa)15(u-)]TJ
1 0 0 1 148.712 558.059 Tm [(v)18(er)-317(le)-318(monde.)-317(C)5(el)15(ui)-317(qui)-317(me)]TJ
1 0 0 1 148.712 546.104 Tm [(rejette)-422(et)-423(qui)-423(ne)-423(rec)383<b8>-70(oit)-422(pas)]TJ
1 0 0 1 148.712 534.149 Tm [(mes)]TJ
1 0 0 1 148.712 514.313 Tm [(J)31(e)-363(suis)-363(v)17(en)15(u)-362(non)-363(pour)-363(ju-)]TJ
1 0 0 1 148.712 502.358 Tm [(g)15(er)-460(le)-460(monde,)-461(mais)-460(pour)]TJ
1 0 0 1 148.712 490.403 Tm [(sa)16(uv)18(er)-729(le)-729(monde.)-732(C)5(el)15(ui)]TJ
...
答案2
以下是对第一个错误的修复:
通过替换node.insert_before(prev_line,prev_line.head.next,w1_prev
,node.insert_after(prev_line.prev,prev_line.prev,w1_prev)
我让它工作了。
第二个但是,我有w1_prev.mode = 1
而不是w1_cur.mode = 1
......