Latex3: 记录 xparse 的“逐字”参数类型的代码,记录如何重现 \verb

创建于 2020-06-25  ·  43评论  ·  资料来源: latex3/latex3

fontenc装载有其T1选项, \NewDocumentCommand与逐字参数吞噬第一-如果其内容中包含-- (不考虑使用的分隔符):

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xparse}
\NewDocumentCommand {\myverb} { v } {#1}
\begin{document}
\ttfamily
\verb|--all|

\myverb{-all}

\myverb{--all}

\myverb{---all}
\end{document}

image

bug documentation xparse

最有用的评论

无论讨论的结果如何,记录在
xparse.pdf 如何使用 \NewDocumentCommand 重现动词的行为。

所有43条评论

您看到的是打字机字体中的--连字。 如果你写\texttt{--}你也会看到一个破折号,但如果你从 PDF 复制,你会看到它确实是一个破折号。 您可以通过将抓取的参数提供给\showtokens或使用\@noligs (LaTeX 在\verb来让--打印-- ):

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xparse}
\makeatletter
% \NewDocumentCommand {\myverb} { v } { \showtokens{#1} }
\NewDocumentCommand {\myverb} { v } {#1}
\begin{document}
\makeatletter
\ttfamily \<strong i="13">@noligs</strong>
-- and \verb|--all|

- and \myverb{-all}

-- and \myverb{--all}

--- and \myverb{---all}
\end{document}

test

但是 xparse 中的 v 应该是逐字逐字的(不是吗?),而在 LaTeX 中,这意味着打字机的连字被压制,所以我认为 v 也应该这样做。

它只是逐字抓取(这里的逐字相当于\let\do\<strong i="5">@makeother</strong> \dospecials )。 \@noligs可以添加到用于扫描参数的 catcode 设置中。 另一方面,这将插入活动标记,其中(理论上)只有 catcode-other 标记,因此如果参数用于排版以外的其他内容,则可能会出现问题。

也许某种方式允许命令添加自己的 catcode 设置,例如:

\NewDocumentCommand {\myverb} { v{\@noligs} } {#1}

@FrankMittelbach我同意 PhelypeOleinik 的观点,即“逐字逐句”的意思是“获取用户逐字记录的任何内容”。 <hyphen hyphen><endash>连字与其说是“获取参数的错误”,不如说是一种“字体功能”。 此外, \ttfamily并不意味着“等宽字体 = 没有任何连字”。 一些等宽字体可以用作身体类型(不只是代码),所以连字符连字应该在这样的情况下被抑制。

但是\NewDocumentCommand {\myverb} { v } {#1}\myverb{--all}应该表现得像\verb|--all|吗?

@dbitouze - 不是真的。 \verb 有两个部分——参数抓取和格式化。 \NewDocumentCommand 中的“v”设置仅适用于前者。

@Phelype — 除非我遗漏了什么,否则您的建议仅此而已吗?:

\NewDocumentCommand {\myverb} { v } { {\<strong i="9">@noligs</strong> #1} }

在这种情况下,我认为没有必要。 所以回到@dbitouze ,复制 \verb 的方法是这样的:

\makeatletter
\NewDocumentCommand {\myverb} { v } { {\@noligs\ttfamily #1} }
\makeatother

2020 年 6 月 25 日星期四 08:22,Denis Bitouzé [email protected]
写道:

但不是 \NewDocumentCommand {\myverb} { v } {#1}\myverb{--all} 应该
表现得像 \verb|--all|?

不完全是,因为v只是解析参数,然后读取
逐字逐字,动词还以非标准等宽字体排版内容
抑制连字的设置。
所以而不是仅仅用#1排版当前字体中的参数
需要做

\verbatim@font\<strong i="19">@noligs</strong>
\language\l<strong i="20">@nohyphenation</strong>

除了 \ @noligs需要
\ defverbatim@nolig@list {\do`\do\<\do>\do\,\do\'\do-}
处于活动状态,因此我们可以考虑让 v 将它们设置为活动状态。 或者
提供围绕扫描令牌的包装器来安排 \ @noligs可以工作
这里

您收到此消息是因为您订阅了此线程。
直接回复本邮件,在GitHub上查看
https://github.com/latex3/latex3/issues/756#issuecomment-649302149 ,或
退订
https://github.com/notifications/unsubscribe-auth/AAJVYAVLBB4ABB3DD5TETRDRYL3MPANCNFSM4OHMH74A
.

@dbitouze不,相似之处仅在于可以分隔参数的方式:您可以使用 \myverb!abc!。 结果记录为

这将导致抓取的参数由类别代码 12(“其他”)和 13(“活动”)的标记组成,除了空格,它们被赋予类别代码 10(“空格”)。

参数解析器只读取一个参数,它不会排版它。 并且向其中添加字体命令或其他命令,甚至对其进行预处理以默认应用\@noligs都是没有意义的:还有其他方法可以抑制连字。 使用 luatex 可能会应用Ligatures=Resetall而使用 pdflatex 可以使用\pdfnoligatures和稍微不同的字体:

~~~~
\RequirePackage{fix-cm}
\documentclass{文章}
\usepackage[T1]{fontenc}
\usepackage{xfp,xparse}

\makeatletter
\NewDocumentCommand {\myverb} { v } {{\fontsize{\fpeval{\ f@size+0.0001 }}{\normalbaselineskip}\selectfont\pdfnoligatures\font #1}}
\makeatother

\begin{文档}
- 全部

动词|--all|

\myverb{-all}

\myverb{--all}

\myverb{---all}

\脚注大小
--all \myverb{--all}

\tt家庭
- 全部

动词|--all|

\myverb{-all}

\myverb{--all}

\myverb{---all}

\脚注大小
--all \myverb{--all}

\end{文档}
~~~~

@phelype——除非我遗漏了什么,你的建议不就是这样吗?:
\NewDocumentCommand {\myverb} { v } { {\ @noligs #1} }

@wspr有点,但不是: \@noligs- (以及其他一堆)的catcode更改为 13,然后将其定义为\def-{\leavevmode\kern\z@\char`-} :作为 catcode 更改,它必须在参数被抓取之前完成(除非我们正在考虑\scantokens ),因此我的建议是允许对v使用“catcode setup”参数(尽管它必须是可选的: \NewDocumentCommand {\myverb} { v[\@noligs] } {#1} )。

谢谢@phelype——我已经有一段时间没有查看那个宏了:)
在那种情况下,我喜欢 setup 参数的想法……即使在这种情况下,其他方法也可以禁用连字。

我们在 arg 规范中没有可选数据,所以它需要一个新字母( w ?)

或者对v -type 的重大更改

我宁愿投票给V (匹配我们有 o 和 O 以及 d 和 D)然后考虑进行重大更改。

我们在 arg 规范中没有可选数据,所以它需要一个新字母( w ?)

不能加一个吗?

或者,因为我们有oO{} ,所以有vV{}似乎很自然。 当然,争论意味着不同的事情......

恕我直言,如果应该为 v-type 自定义 catcodes,那么使用 cctab 代码是有意义的,而不是像\@noligs这样的任意命令。 然后命令的读取将只设置 catcodes 和活动字符的定义,然后应该在宏体中完成。

@u-fischer 所以我最好以l3cctab在 ...

目前,我不知道l3cctab是如何工作的以及它如何对当前问题有所帮助,但我真的很感兴趣:)

我的观点是语义上v是“逐字逐句”的,而这里需要的不是。 重要的是,您必须担心分隔字符是否被 catcode 表或其他任何内容更改。 此外,我们一直坚持大写字母 -> 小写字母的一些可选参数变体。 所以我会说像c{<table>} (= 'catcode') 这样的东西是正确的。

如果可以的话,我会在今天或明天整理cctab东西,这样我们就可以讨论了。

@dbitouze catcode表是一种为所有字符(*)设置一组“固定” \c_document_cctab用于普通代码, \c_initex_cctab用于 IniTeX 等。这个想法比一个更清晰、更可靠-逐一设置。

  • 在 XeTeX 中,我们没有必要的原语,所以我只能以合理的性能覆盖 0 到 255 个字符。

@josephwright (题外话)在我看来,您想添加脚注,但 Markdown 不知道。

在输出期间抑制一组已知的连字也可以通过使用\tl_replace_all:Nnn并用不会形成连字的东西替换有问题的字符来完成。

@Skillmon好点:可以采用逐字逐句的材料并替换标记。 由于一切都是严格逐字逐句的,这可能比担心 catcode 设置更容易。

无论讨论的结果如何,记录在
xparse.pdf 如何使用 \NewDocumentCommand 重现动词的行为。

@josephwright根据要替换的令牌数量,使用\tl_replace_all:Nnn方法时性能会差很多。

另外,您如何知道哪些字符(以非常大的字体)需要替换?

进一步:对于许多脚本(非欧洲)来说,排版“使用等宽字体逐字逐句”意味着什么?

@car222222在非常大的字体中,您将字体特征作为抑制它们的唯一合理方法,LaTeX 无法知道字体中可能存在的所有连字。 但至少可以轻松覆盖支持 LaTeX2e 的字符(它只是一个\tl_map_function:NN\tl_replace_all:Nnn )。

进一步:AFAIK 对于某些非欧洲文字,某些等宽字体中有双倍行距符号。

我建议只将每个字符包装在一个 hbox 中。 它似乎工作
相当不错,但我没有进行广泛的测试。

\RequirePackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\myverb}{v}{\texttt{\str_map_ function:nN {#1}\ hbox:n }}
\ExplSyntaxOff
\documentclass{文章}
\usepackage[T1]{fontenc}
\begin{文档}
动词|a--b ---c ``<''|

\myverb|a--b ---c ``<''|
\end{文档}

我建议只将每个字符包装在一个 hbox 中。 它似乎工作得相当好,但我没有进行广泛的测试。

试试|a--bgrüße ---c ``<''|

好的,第二次尝试( v arg 保持活动字符不变):在所有非活动字符之前插入\kern 0pt\relax

\RequirePackage{xparse}
\ExplSyntaxOn
\tl_new:N \l__myverb_tl
\cs_new:Npn \__myverb:n #1
  {
    \token_if_active:NF #1 { \kern 0pt\relax }
    \exp_not:n {#1}
  }
\NewDocumentCommand { \myverb } { v }
  {
    \tl_set:Nn \l__myverb_tl {#1}
    \tl_replace_all:Nnn \l__myverb_tl { ~ } { { ~ } }
    \group_begin:
      \use:c { verbatim<strong i="8">@font</strong> }
      \use:x { \tl_map_function:NN \l__myverb_tl \__myverb:n }
    \group_end:
  }
\ExplSyntaxOff
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\begin{document}
\verb|a--bgrüße ----c ``<''|

\myverb|a--bgrüße ----c ``<''|
\end{document}

好的,第二次尝试( v arg 保持活动字符不变):

但不是所有人。 例如,这里的报价无效:

~~~~
\documentclass{文章}
\usepackage[ngerman]{babel}
\begin{文档}
“一个

\ExplSyntaxOn
\NewDocumentCommand { \myverb } { mv }
{
\tl_analysis_显示:n {#1}
\tl_analysis_显示:n {#2}
}
\ExplSyntaxOff

\myverb{"a}|"a|
\end{文档}
~~~~

~~~~
令牌列表包含令牌:

" (活动字符=宏:->活动@prefix "active@char" )
a(字母a)。
}

l.29 \myverb{"a}|"a|

?
令牌列表包含令牌:

“ (人物 ”)
a(字符a)。
}
~~~~

@u-fischer 但是在“逐字文本”中需要这两个输出中的哪一个?

在我看来,“非活动”案例就像 LaTeX 过去所说的“逐字逐句”一样。

但也许有些人期望输出是,例如,ä 在其他人看来并不像“逐字逐句”。

正如我多次写过的那样:在可打印的 7 位 ASCII 之外,“逐字逐句”是什么意思?

@car222222我的例子是关于输入而不是输出。 我不输出任何东西,只分析 xparse 抓取的参数的样子。 从文档中,我希望参数让活动字符保持原样,并将所有其他标记转换为 catcode 12,将空格转换为 catcode 10。但是正如一些测试表明我的期望是错误的:使用 babel 设置的活动字符也转换为 catcode 12因为参数解析器包含一个 \dospecial。

另一个问题:这个v类型的参数应该将连续的空格折叠成一个标记(使用 catcode 10),还是“逐字”保留空格数? 究竟应该如何“逐字逐句”(我认为手册中现在没有明确定义)?

@u-fischer 输入/输出 ?? 但是你回答了我隐含的问题。

您想保持活动的“但我认为逐字记录应该产生非活动的”,这样就不会输出 ä 字形。

当我说“我认为”时,我的意思是这就是我期望从 TeX/LaTeX 中“逐字逐句”的原始(40 年前)概念得出的结论。

也许这个概念+定义需要改变,但究竟是什么?

或者正如@RuixiZhang42所说:21 世纪的逐字逐字如何?

有趣的动词*|YZ| (有两个连续的制表符)给出一个空格
因为动词会更改空格的代码而不是制表符的代码。

我同意 v-type(以及“+v”)参数现在还没有明确定义。 会不会
以下有意义,使用catcode表?

  • 将 catcode 13(活动)分配给空格和其他一些(例如`\^^M?)。

  • 为所有其他字节 0-127(在 pdfTeX 中)、0-255(在 XeTeX 中,
    upTeX、pTeX) 或 0-1114111 (LuaTeX)。

  • 在 pdfTeX 中,将 catcode 13(活动)赋予字节 128-255。

也许最好保留一些东西作为 catcode 11(字母)?

你想保持活跃的“

不,我没有那样说。 我只是写道,我希望在阅读文档后会发生这种情况。 这仅意味着文档需要改进。

但我认为逐字记录应该产生非活动的“,这样就不能输出ä字形。

您也可以使用活动的"获得"a作为输出:您只需要在本地给它一个合适的定义。

@u-fischer 你可以得到“a as output with an active”

当然可以,但我不知道“逐字模式”是否需要这样的定制? 也许应该?

回到问题:'verbatim' 是什么意思,无论是读取输入标记列表还是输出(包括什么字体、什么连字、字距调整、其他字体功能等)。

也许是这样的(仅用于可打印 ASCII 的输入):
没有删除字符或更改字符代码,大多数的catcode变为12,除了以下更改为(或保持在)13,。 . . .
加上以下不可打印的 ascii,它们也变成了 catcode 13 标记: . . .

必须自定义环境以处理任何 7 位 ACSII 字符的输出(文本表示),这些字符可能通过上述过程在内部被证明是 catcode 13 标记。

[与原版有点不同,但仍像原版一样仅涵盖ASCII输入。]

@blefloch写道:在 pdfTeX 中,将

即使没有使用 inputenc,您也会这样做吗? 你会给他们什么样的定义?

我不确定是否有人对 utf-8 inputenc 输入到逐字模式有很多想法。 这会得到支持吗,这意味着什么?

我不确定是否有人对 utf-8 inputenc 输入到逐字模式有很多想法。 这会得到支持吗,这意味着什么?

支持它,至少对于 T1 编码。 对于希腊语或类似的,你必须重新定义verbatim@font

~~~
\documentclass{文章}
\usepackage[LGR,T1]{fontenc}
\begin{文档}
动词|grüße € |

\makeatletter
\ defverbatim@font {\ttfamily}
字体编码{LGR}\selectfont
动词|Γειά σου Κόσμε|
\end{文档}
~~~

image

关于逐字论证应该做什么的可能建议。 我倾向于选项 1,但我可能会遗漏某些方面。

  1. 将 catcodes 从 0 更新为 255(在任何引擎中),保持 catcodes 11、12、13(字母/其他/活动)不变,将 catcode 10(空格)更改为 catcode 13(活动),并将所有其他 catcodes 更改为 12(其他) . 然后应用\@noligs的 catcode 更改,即激活\verbatim@nolig@list 。 然后获取参数:这仅给出了 catcodes 11、12、13 的结果。 对于不想要活动字符的用户来说,很容易将其转换回字符串。 对于那些想要 inputenc 或 babel-shorthand 支持的人,所有活动字符都被保留了下来。 它还支持连字抑制。

  2. 使用可由用户更改的 catcode 表\l_xparse_verbatim_cctab 。 这很难与可能更改文档中间的 babel 快捷方式保持同步。 这对于包编写者来说也很笨拙,因为他们需要一个包装函数来在解析逐字参数之前更改\l_xparse_verbatim_cctab

  3. 2. 的变体,其中 cctab 作为参数v (可选参数,或新字母)给出。 同样,这不能与 babel 速记和对\verbatim@nolig@list更改保持同步。

此页面是否有帮助?
0 / 5 - 0 等级