LuaLaTeX:仅在文本中替换字符串(不在代码和命令中)

LuaLaTeX:仅在文本中替换字符串(不在代码和命令中)

您可以使用 Lua 代码执行字符串替换gsub(参见这个答案)。\AtBeginDocument您可以将函数的范围限制在文档中。但是,是否也可以将函数仅应用于文本而不应用于命令,以便以下示例可以正常工作?

% !TEX TS-program = lualatex
\documentclass{article}
\newcommand*{\dark}[1]{\textbf{#1}}
\usepackage{luacode}
\begin{luacode}
function replace_dark_with_bright ( s )
  s = s:gsub ( "dark", "bright" )
  return s
end
\end{luacode}
\AtBeginDocument{%
  \directlua{luatexbase.add_to_callback (
    "process_input_buffer", replace_dark_with_bright, "replace_dark_with_bright" )}}
\begin{document}
Always look on the dark side of life.
To \dark{emphasize} a word.
\end{document}

是否可以使用字体功能将整个字符串替换为其他字符串,或者它是否始终必须是至少一个方向上的单个字形(如ligaturemultiple)?由于字体功能替换仅适用于文本(而不适用于命令),因此这将是一个解决方案。

编辑

更具体地说明我正在尝试做的事情:

这个想法是使用 Lua 字符串操作来实现某些连字符的自动断开,而不影响字距调整或连字点。

这种类型的解决方案,如下面的代码所示,原则上似乎是可行的:

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{fontspec}
\usepackage{luacode}

\begin{luacode}

fonts.handlers.otf.addfeature{
    name = "ligkern",
    type = "kern",
    data = {
        ["f_f"] = { ["l"] =  50 },
        ["f"] = { ["l"] =  50 },
    },
}

function lig_parse ( s )

    function no_fl_lig ( text )
        s = s:gsub ( text, text:gsub ( "fl", "fL" ) )
    end

    function keep_fl_lig ( text )
        s = s:gsub ( text:gsub ( "fl", "fL" ), text )
    end

    local c = [===[\char]===]
    local ffl = c .. "64260"
    local fl = c .. "64258"
    local ff = c .. "64256"

    no_fl_lig ( "flich" )
    keep_fl_lig ( "flicht" )
    no_fl_lig ( "öpflicht" )

    no_fl_lig ( "griffl" )

    s = s:gsub ( "ffl", ffl )
    s = s:gsub ( "fl", fl )
    s = s:gsub ( "fL", "fl" )
    s = s:gsub ( "ff", ff )

    return s

end

\end{luacode}

\setmainfont{Latin Modern Roman}[
    Ligatures = {NoCommon, NoDiscretionary},
    RawFeature =+ ligkern
]

\AtBeginDocument{%
    \directlua{luatexbase.add_to_callback
    ("process_input_buffer", lig_parse, "make and break ligatures")}%
}

\begin{document}

\noindent Die vortrefflichen Pflichten\\
des begrifflosen Knoepfflers\\
sind unerschöpflichtief.

\end{document}

在此处输入图片描述

但是,如果文档中有一个(例如)\sffamily,这当然会导致问题。当然,可以将此类命令添加到替换中。但我认为,如果替换首先只应用于文本,那么这将是一个更干净的解决方案。

答案1

我不确定我是否理解你的主要目的是什么。如果是将“暗”改为“亮”,同时保持\dark原样,我建议用两个模式替换单个搜索模式dark"([^\\])dark"^dark,在两个gsub语句中。

在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}
\newcommand*{\dark}[1]{\textbf{#1}}
\usepackage{luacode}
\begin{luacode}
function replace_dark_with_bright ( s )
  s = s:gsub ( "([^\\])dark", "%1bright" ) 
  s = s:gsub ( "^dark" , "bright" )
  return s
end
\end{luacode}
\AtBeginDocument{\directlua{luatexbase.add_to_callback (
    "process_input_buffer", replace_dark_with_bright, "replace_dark_with_bright" )}}
\begin{document}
Always look on the dark side of life.
To \dark{emphasize} a word.

dark is the day
\end{document}

相关内容