需要 Tex 宏来显示 mercurial 关键字

需要 Tex 宏来显示 mercurial 关键字

我在乳胶文档中有一些 mercurial 关键字,希望进行处理。

\documentclass[12pt]{article}
% This macro is an example based on the Tex FAQ:  
% https://texfaq.org/FAQ-RCS
% We define \hgDate and \hgRevision macros.
\def\hg$#1: #2 ${\expandafter\def\csname hg#1\endcsname{#1: #2 }}

% This is what will be in the preamble if keyword expansion is turned on.
\hg$Revision: 123 $     % this is auto expanded by hg - do not change 
\hg$Date: 2015-01-08 $  % this is auto expanded by hg - do not change

% But ... if keyword expansion is turned off or not set the above will 
% be like the two lines below. Note: commented out as this does not work yet.
% \hg$Revision$    
% \hg$Date$ 
\begin{document}

Minimal example of plain tex macro to process mercurial keyword expansions.
If \verb+\hg$Date$+ exists in the preamble then we wish the macro 
\verb+\hgDate+ to display ``Date: None''. If \verb+\hg$Date: 2014-11-10 $+
exists in the preamble then we wish the macro \verb+\hgDate+ to display 
``Date: 2014-11-10''. Similarly for \verb+\hg$Revision$+. 

This doc is \hgRevision and \hgDate 
\end{document}

上述代码适用于 $Date xx $ 和 $Revision 12 $,但不适用于 $Date$ 或 $Revision$,因为它没有第二个参数。

有 svn latex 包,但它们使用的关键字格式与 mercurial 不同,因此不适用于日期。我希望使用一个简单的 TeX 宏,因为我的 latex 文档被 Windows 和 Mac 用户使用,我只想在顶部添加一个简短的 tex 宏,而不是用户必须安装新的 latex 包。以下是我的一些明显错误的尝试。

这次尝试测试第二个参数是否为空:

\def\foo{}%
\def\hg$#1: #2 $%
{\expandafter\def\csname hg#1\endcsname%
{\if\foo#2\foo #1: None\else #1: #2\fi}%
}
%\hg$Revision$  
\hg$Revision: 123 $   
\hg$Date: 2015-01-08 $ 
\hgDate \hspace{2ex} \hgRevision

此尝试测试第二个参数是否为空:

\def\hg$#1: #2 ${\expandafter\def\csname hg#1\endcsname%
{#1: \def\temp{#2\unskip}%
\ifx\temp\empty
  None
\else 
  #2
\fi}%
}
%\hg$Revision$  
\hg$Revision: 123 $   
\hg$Date: 2015-01-08 $ 
\hgDate \hspace{2ex} \hgRevision

这次尝试使用 detokenize 来查看参数 2 是否为空:

\def\hg$#1: #2 $%
{\expandafter\def\csname hg#1\endcsname%
{#1: \if\relax\detokenize{#2}\relax yy\else xx\fi}%
}
%\hg$Revision$  
\hg$Revision: 123 $  
\hg$Date: 2015-01-08 $ 
\hgDate \hspace{2ex} \hgRevision

如果没有第二个参数,则每个方法都会失败。也许我应该尝试删除 $ 或更改其 catcode?更可能的是,我需要更好地理解 TeX!

谢谢

答案1

我发现它的使用xparseexpl3功能很方便,可以避免复杂的情况。

\documentclass[12pt]{article}

\usepackage{xparse}

\NewDocumentCommand{\hg}{>{\SplitArgument{1}{:}}r$$}
 {%
  \processhg#1%
 }

\ExplSyntaxOn
\NewDocumentCommand{\processhg}{mm}
 {
  \IfNoValueTF{#2}
  {\hg_define_hg:nn { #1 } { None } }
  {\hg_define_hg:nn { #1 } { #2 } }
 }

\cs_new_protected:Nn \hg_define_hg:nn
 {
  \cs_gset:cpx {hg#1}{ \tl_trim_spaces:n { #2 } }
 }
\ExplSyntaxOff

% This is what will be in the preamble if keyword expansion is turned on.
\hg$Revision: 123 $     % this is auto expanded by hg - do not change 
\hg$Date: 2015-01-08 $  % this is auto expanded by hg - do not change

\begin{document}

Revision: \hgRevision; Date: \hgDate.

Now we emulate calling the macros without parameters

\hg$Revision$    
\hg$Date$ 

Revision: \hgRevision; Date: \hgDate.

\end{document}

该宏\hg有一个由$符号分隔的参数。该参数在冒号处被分成两部分,但如果没有找到冒号,则第二个参数将接收一个特殊值,使测试\IfNoValueTF为真。

拆分参数仍由 表示,#1并传递给第二个宏进行处理。这反过来会使用适当的参数(None如果没有冒号)调用内部函数。

在此处输入图片描述

答案2

如果我不采用任何包装,这将是以下风格的东西。它假设类似于$name$$name:<space>stuff<space>$。如果空格是可选的,则代码必须进行相应的调整,这并不难(对于TeX精通 宏语言的人来说!)。

\documentclass[12pt]{article}

\makeatletter
\def\hg #1{\def\hg $##1${\hg@ ##1:#1#1:\hg@}}
\hg { }
\def\hg@ #1: #2 :#3\hg@{\if\relax\detokenize{#2}\relax
    \@namedef{hg#1}{#1: None}%
    \else
    \@namedef{hg#1}{#1: #2}%
    \fi
}
\makeatother

% This is what will be in the preamble if keyword expansion is turned on.
\hg$Revision: 123 $     % this is auto expanded by hg - do not change 
\hg$Date: 2015-01-08 $  % this is auto expanded by hg - do not change

% \hg$Revision$    
% \hg$Date$ 
\begin{document}

Minimal example of plain tex macro to process mercurial keyword expansions.
If \verb+\hg$Date$+ exists in the preamble then we wish the macro 
\verb+\hgDate+ to display ``Date: None''. If \verb+\hg$Date: 2014-11-10 $+
exists in the preamble then we wish the macro \verb+\hgDate+ to display 
``Date: 2014-11-10''. Similarly for \verb+\hg$Revision$+. 

This doc is \hgRevision{} and \hgDate.


\hg$Revision$    
\hg$Date$ 
This doc is \hgRevision{} and \hgDate.
\end{document}

mercurial 标签

答案3

如果输入模式是 或 ,则
\hg$⟨name⟩$

\hg$⟨name⟩:⟨space⟩⟨stuff⟩⟨space⟩$

  • ⟨姓名⟩不包含以空格结尾的冒号(序列:)并且
  • ⟨东西⟩不包含以冒号结尾的空格(序列:

,您可以尝试使用分隔参数。

但请注意,在 之间的所有内容$...$和 的其他所有内容都用一层花括号括起来⟨姓名⟩其余部分用一层花括号括起来⟨东西⟩如果存在的话,将会被剥离。

\documentclass[12pt]{article}

\makeatletter
\def\hg $#1${\hg@ #1: {None/Default} :\hg@}
\def\hg@ #1: #2 :#3\hg@{\@namedef{hg#1}{#1: #2}}
\makeatother

\begin{document}

Calls to \verb|\hgRevision|/\verb|\hgDate| are nested between parentheses so you can see if spaces slipped in.

\bigskip

\par \textbf{Revision/Date empty:}

\hg$Revision$    
\hg$Date$ 

\par (\hgRevision)
\par (\hgDate)

\par \textbf{Without whatsoever surrounding curly braces:}

\hg$Revision: 123 $
\hg$Date: 2015-01-08 $

\par (\hgRevision)
\par (\hgDate)

\par \textbf{With surrounding curly braces that get stripped off:}

\hg${{Revision}: {123} }$
\hg${{Date}: {2015-01-08} }$

\par (\hgRevision)
\par (\hgDate)

\end{document}

在此处输入图片描述

如果由于某种原因您希望防止剥离括号,则可以拆分机制,以便每个分隔参数在前面添加某些内容后由另一个宏处理:

\documentclass[12pt]{article}

\makeatletter
\def\hg${\hg@.}
\def\hg@#1${\hg@@#1: {None/Default} :\hg@@}
%\def\hg@#1${\hg@@#1: None/Default :\hg@@}
\def\hg@@#1: {\expandafter\hg@@i\expandafter{\hg@@gobbledot#1}.}
\def\hg@@i#1#2 :{\expandafter\hg@@ii\expandafter{\hg@@gobbledot#2}{#1}}
\def\hg@@ii#1#2#3\hg@@{\@namedef{hg#2}{#2: #1}}
\def\hg@@gobbledot.{}
\makeatother

\begin{document}

Calls to \verb|\hgRevision|/\verb|\hgDate| are nested between parentheses so you can see if spaces slipped in.

\bigskip

\par \textbf{Revision/Date empty:}

\hg$Revision$    
\hg$Date$ 

\par (\hgRevision)
\par (\hgDate)
\par {\tt\frenchspacing\string\hgRevision=\meaning\hgRevision}
\par {\tt\frenchspacing\string\hgDate=\meaning\hgDate}

\par \textbf{Without whatsoever surrounding curly braces:}

\hg$Revision: 123 $
\hg$Date: 2015-01-08 $

\par (\hgRevision)
\par (\hgDate)
\par {\tt\frenchspacing\string\hgRevision=\meaning\hgRevision}
\par {\tt\frenchspacing\string\hgDate=\meaning\hgDate}

\par \textbf{With surrounding curly braces that do not get stripped off:}

\hg$Revision: {123} $
\hg$Date: {2015-01-08} $

\par (\hgRevision)
\par (\hgDate)
\par {\tt\frenchspacing\string\hgRevision=\meaning\hgRevision}
\par {\tt\frenchspacing\string\hgDate=\meaning\hgDate}

\hg${Revision}: {123} $
\hg${Date}: {2015-01-08} $

\par (\csname hg{Revision}\endcsname)
\par (\csname hg{Date}\endcsname)
\par {\tt\frenchspacing\expandafter\string\csname hg{Revision}\endcsname=\expandafter\meaning\csname hg{Revision}\endcsname}
\par {\tt\frenchspacing\expandafter\string\csname hg{Date}\endcsname=\expandafter\meaning\csname hg{Date}\endcsname}

\hg${{Revision}: {123} }$
\hg${{Date}: {2015-01-08} }$

\par (\csname hg{{Revision}: {123} }\endcsname)
\par (\csname hg{{Date}: {2015-01-08} }\endcsname)
\par {\tt\frenchspacing\expandafter\string\csname hg{{Revision}: {123} }\endcsname=\expandafter\meaning\csname hg{{Revision}: {123} }\endcsname}
\par {\tt\frenchspacing\expandafter\string\csname hg{{Date}: {2015-01-08} }\endcsname=\expandafter\meaning\csname hg{{Date}: {2015-01-08} }\endcsname}

\end{document}

在此处输入图片描述

相关内容