宏作为 pgf 解析器的参数

宏作为 pgf 解析器的参数

作为对该问题的继续回答: 使用 xcolor 调整字距

首先尝试定义整个单词的字距调整宏,第一个字母带颜色,不带括号:(
以程序员风格而不是 TeX 风格,使用pgf 解析器)。我第一次只设置了几个重音。
(这个宏我用于教会斯拉夫语)

我不知道在这种情况下如何使用宏作为参数:
\cuParse \SomeMacros无法正常工作,mb 整个参数宏都被视为首字母?
有人能帮忙吗?

梅威瑟:

\documentclass{article}
\usepackage{polyglossia}
\usepackage{fontspec}
\setmainfont{CMU Serif}
\usepackage{xcolor}
\usepackage{pgf}
\usepgfmodule{parser}

% from egreg's answer
% https://tex.stackexchange.com/questions/567220/kerning-with-xcolor
\newcommand{\kerncolor}[4]{%
  % #1 = color, #2 = before, #3 = colored part, #4 = after
  \sbox0{#2#3}\sbox2{\mbox{#2}\mbox{#3}}%
  \dimen0=\dimexpr\wd0-\wd2\relax
  \sbox0{#3#4}\sbox2{\mbox{#3}\mbox{#4}}%
  \dimen2=\dimexpr\wd0-\wd2\relax
  #2\kern\dimen0 \textcolor{#1}{#3}\kern\dimen2 #4%
}
%------------------------------------------
\def\cuFirstLetter{}
\def\cuFirstSub{}
\def\cuSndSub{}
\def\cuSndLetter{}
\def\cuTail{}
\def\TailFinal{}

\futurelet\pgfspace{ }
%------------------------------------------
\pgfparserdefunknown{cuw}{initial}{%
  \edef\cuFirstLetter{\pgfparserletter}%
  \pgfparserswitch{second symbol}}
%------------------------------------------
\pgfparserdefunknown{cuw}{second symbol}{%
  \edef\cuSndLetter{\pgfparserletter}%
  \pgfparserswitch{letters}}
\newcommand{\SetCUWFirstCuAccent}[1]{%
  \pgfparserdef{cuw}{second symbol}{the letter #1}{%
    \edef\cuFirstSub{#1}%
    \pgfparserswitch{subs}}}
%Some general accents
\SetCUWFirstCuAccent{̀}% COMBINING GRAVE ACCENT (U+0300) /вария
\SetCUWFirstCuAccent{́}% COMBINING ACUTE ACCENT (U+0301) /оксия 
\SetCUWFirstCuAccent{̈}% Combining Diaeresis (U+0308)
\SetCUWFirstCuAccent{̋}% Combining Double Acute Accent (U+030B)
\SetCUWFirstCuAccent{̏}% Combining Double Grave Accent (U+030F)
%Some church-slavonic accents:    
\SetCUWFirstCuAccent{҃}% Combining Cyrillic Titlo (U+0483) /титло 
\SetCUWFirstCuAccent{҆}% Combining Cyrillic Psili Pneumata (U+0486) /звательце
\SetCUWFirstCuAccent{ⷭ}% с под покрытие
\SetCUWFirstCuAccent{ⷣ}% д-титло 
%------------------------------------------
\pgfparserdef{cuw}{subs}{\meaning\pgfspace}{%
  \edef\TailFinal{\ }
  \pgfparserswitch{final}}
\pgfparserdefunknown{cuw}{subs}{%
  \edef\cuSndLetter{\pgfparserletter}%
  \pgfparserswitch{letters}}
\newcommand{\SetCUWSecondCuAccent}[1]{%
  \pgfparserdef{cuw}{subs}{the letter #1}{%
    \edef\cuSndSub{#1}}}
%Some general accents
\SetCUWSecondCuAccent{́}% COMBINING ACUTE ACCENT (U+0301) /оксия
\SetCUWSecondCuAccent{̀}% COMBINING GRAVE ACCENT (U+0300) /вария 
%Some church-slavonic accents:
\SetCUWSecondCuAccent{҇}% Combining Cyrillic Pokrytie (U+0487) /покрытие
%------------------------------------------
\pgfparserdefunknown{cuw}{letters}{%
  \let\savedTail\cuTail%
  \edef\cuTail{\savedTail\pgfparserletter}}
\pgfparserdef{cuw}{letters}{\meaning\pgfspace}{%
  \edef\TailFinal{\ }
  \pgfparserswitch{final}}
%------------------------------------------
\pgfparserdeffinal{cuw}{\kerncolor{red}{}{\cuFirstLetter\cuFirstSub\cuSndSub}{\cuSndLetter}\cuTail\TailFinal}%
\pgfparserset{cuw/silent=true}%
%------------------------------------------
\newcommand{\cuParse}[1]{%
  \def\cuFirstLetter{}%
  \def\cuFirstSub{}%
  \def\cuSndSub{}%
  \def\cuSndLetter{}%
  \def\cuTail{}%
  \def\cuTailFinal{}%
  \pgfparserparse{cuw}#1%
}

\newcommand{\TEST}{VAR}

\begin{document}

\textcolor{red}{Á}VE <- \textit{without kerning}

\cuParse ÁVE 

\cuParse ÀVE

\cuParse Ä́h

\cuParse \TEST test

\end{document}

在此处输入图片描述

答案1

下面的代码会改变你的代码,这样在解析器的初始状态下,它会检查第一个标记是否是一个不带参数的宏。如果是,则展开宏并将结果存储到 中\pgfparserletter, 会重新插入 的内容\pgfparserreinsert

这样,第一个标记将被扩展,并且解析器将检查结果。如果第一个标记是包含macro:->其替换项的宏,则对没有参数的宏的测试将失败(这似乎不太可能,因此测试应该没问题,但可以创建更强大的测试)。

与原始代码相比,唯一的变化是添加了\CuIfMacro\CuIfMacroHelper(进行测试),以及更改了的定义\pgfparserunknown{cuw}{initial}

\documentclass{article}
\usepackage{polyglossia}
\usepackage{fontspec}
\setmainfont{CMU Serif}
\usepackage{xcolor}
\usepackage{pgf}
\usepgfmodule{parser}

% from egreg's answer
% https://tex.stackexchange.com/questions/567220/kerning-with-xcolor
\newcommand{\kerncolor}[4]{%
  % #1 = color, #2 = before, #3 = colored part, #4 = after
  \sbox0{#2#3}\sbox2{\mbox{#2}\mbox{#3}}%
  \dimen0=\dimexpr\wd0-\wd2\relax
  \sbox0{#3#4}\sbox2{\mbox{#3}\mbox{#4}}%
  \dimen2=\dimexpr\wd0-\wd2\relax
  #2\kern\dimen0 \textcolor{#1}{#3}\kern\dimen2 #4%
}
%------------------------------------------
\def\cuFirstLetter{}
\def\cuFirstSub{}
\def\cuSndSub{}
\def\cuSndLetter{}
\def\cuTail{}
\def\TailFinal{}

\futurelet\pgfspace{ }
\makeatletter
\edef\CuIfMacro
  {%
    \unexpanded{\expandafter\CuIfMacroHelper\meaning\pgfparsertoken}%
    \unexpanded{\CuMark\@firstoftwo}%
    \detokenize{macro:->}%
    \unexpanded{\CuMark\@secondoftwo\CuStop}%
  }
\edef\CuIfMacroHelper{\unexpanded{\def\CuIfMacroHelper#1}\detokenize{macro:->}}%
\CuIfMacroHelper#2\CuMark#3#4\CuStop{#3}%
\makeatother
%------------------------------------------
\pgfparserdefunknown{cuw}{initial}{%
  \CuIfMacro
    {%
      \edef\pgfparserletter
        {\unexpanded\expandafter\expandafter\expandafter{\pgfparserletter}}%
      \pgfparserreinsert
    }%
    {\edef\cuFirstLetter{\pgfparserletter}\pgfparserswitch{second symbol}}%
  }
%------------------------------------------
\pgfparserdefunknown{cuw}{second symbol}{%
  \edef\cuSndLetter{\pgfparserletter}%
  \pgfparserswitch{letters}}
\newcommand{\SetCUWFirstCuAccent}[1]{%
  \pgfparserdef{cuw}{second symbol}{the letter #1}{%
    \edef\cuFirstSub{#1}%
    \pgfparserswitch{subs}}}
%Some general accents
\SetCUWFirstCuAccent{̀}% COMBINING GRAVE ACCENT (U+0300) /вария
\SetCUWFirstCuAccent{́}% COMBINING ACUTE ACCENT (U+0301) /оксия 
\SetCUWFirstCuAccent{̈}% Combining Diaeresis (U+0308)
\SetCUWFirstCuAccent{̋}% Combining Double Acute Accent (U+030B)
\SetCUWFirstCuAccent{̏}% Combining Double Grave Accent (U+030F)
%Some church-slavonic accents:    
\SetCUWFirstCuAccent{҃}% Combining Cyrillic Titlo (U+0483) /титло 
\SetCUWFirstCuAccent{҆}% Combining Cyrillic Psili Pneumata (U+0486) /звательце
\SetCUWFirstCuAccent{ⷭ}% с под покрытие
\SetCUWFirstCuAccent{ⷣ}% д-титло 
%------------------------------------------
\pgfparserdef{cuw}{subs}{\meaning\pgfspace}{%
  \edef\TailFinal{\ }
  \pgfparserswitch{final}}
\pgfparserdefunknown{cuw}{subs}{%
  \edef\cuSndLetter{\pgfparserletter}%
  \pgfparserswitch{letters}}
\newcommand{\SetCUWSecondCuAccent}[1]{%
  \pgfparserdef{cuw}{subs}{the letter #1}{%
    \edef\cuSndSub{#1}}}
%Some general accents
\SetCUWSecondCuAccent{́}% COMBINING ACUTE ACCENT (U+0301) /оксия
\SetCUWSecondCuAccent{̀}% COMBINING GRAVE ACCENT (U+0300) /вария 
%Some church-slavonic accents:
\SetCUWSecondCuAccent{҇}% Combining Cyrillic Pokrytie (U+0487) /покрытие
%------------------------------------------
\pgfparserdefunknown{cuw}{letters}{%
  \let\savedTail\cuTail%
  \edef\cuTail{\savedTail\pgfparserletter}}
\pgfparserdef{cuw}{letters}{\meaning\pgfspace}{%
  \edef\TailFinal{\ }
  \pgfparserswitch{final}}
%------------------------------------------
\pgfparserdeffinal{cuw}{\kerncolor{red}{}{\cuFirstLetter\cuFirstSub\cuSndSub}{\cuSndLetter}\cuTail\TailFinal}%
\pgfparserset{cuw/silent=true}%
%------------------------------------------
\newcommand{\cuParse}[1]{%
  \def\cuFirstLetter{}%
  \def\cuFirstSub{}%
  \def\cuSndSub{}%
  \def\cuSndLetter{}%
  \def\cuTail{}%
  \def\cuTailFinal{}%
  \pgfparserparse{cuw}#1%
}

\newcommand{\TEST}{VAR}

\begin{document}

\textcolor{red}{Á}VE <- \textit{without kerning}

\cuParse ÁVE 

\cuParse ÀVE

\cuParse Ä́h

\cuParse \TEST test 

\end{document}

在此处输入图片描述

相关内容