Ein erweiterbarer Befehl, der einem Argument eine Zeichenfolge hinzufügt, wenn die Zeichenfolge fehlt

Ein erweiterbarer Befehl, der einem Argument eine Zeichenfolge hinzufügt, wenn die Zeichenfolge fehlt

Ich möchte einen erweiterbaren Befehl schreiben, der eine Zeichenfolge S1 am Anfang einer anderen Zeichenfolge S2 hinzufügt, wenn S2 nicht mit S1 beginnt, um sicherzustellen, dass meine Zeichenfolge immer mit S1 beginnt.

Ich habe derzeit diesen Code, der auf dem xstring-Paket basiert

\NewDocumentCommand\forcebeginwith{m m}{%
    \edef\expandedstring{#1}%
    \edef\expandedbeginning{#2}%
    \IfBeginWith{
        \expandedstring % String
    }{
        \expandedbeginning % Beginning
    }{
        \expandedstring % String
    }{
        \expandedbeginning\expandedstring % Beginning + String
    }
}

Zum Beispiel :

\forcebeginwith{fancycolor}{fancy} % fancycolor
\forcebeginwith{color}{fancy} % fancycolor

Frage:Ich möchte diesen Befehl in einen erweiterbaren Befehl umwandeln NewExpandableDocumentCommand, habe aber keine Ahnung, wie das geht (ich möchte, dass der resultierende Code mit Latex-Versionen funktioniert, die beispielsweise 5 Jahre alt sind, daher möchte ich superaktuelle Befehle/Pakete vermeiden).

Antwort1

Der Befehl \forcebeginwithwird mit definiert \NewExpandableDocumentCommand. Der Test wird mit durchgeführt \str_if_eq:eeTF. Der Befehl \forcebeginwithkann \edefwie im folgenden Beispiel verwendet werden.

Bildbeschreibung hier eingeben

\documentclass[border=6pt,varwidth]{standalone}
\ExplSyntaxOn
\NewExpandableDocumentCommand { \forcebeginwith } { m m }
  {
    \str_if_eq:eeTF {#2} { \str_range:nnn {#1} { 1 } { \str_count:n {#2} } }
      {#1}
      { #2#1 }
  }
\ExplSyntaxOff
\begin{document}
\forcebeginwith{fancycolor}{fancy}\\% fancycolor
\forcebeginwith{color}{fancy}\\% fancycolor
\edef\testA{\forcebeginwith{LaTeX}{La}}\testA\\
\edef\testB{\forcebeginwith{TeX}{La}}\testB
\end{document}

Antwort2

Wenn Sie verwenden pdflatex, können Sie dies mit tun

\documentclass{article}

\newcommand{\forcebeginwith}[2]{%
  \ifnum\pdfmatch{^#2}{#1}=0 #2\fi#1%
}

\begin{document}

\forcebeginwith{fancycolor}{fancy}% fancycolor

\forcebeginwith{color}{fancy}% fancycolor

\edef\testA{\forcebeginwith{LaTeX}{La}}\testA

\edef\testB{\forcebeginwith{TeX}{La}}\testB

\end{document}

Bildbeschreibung hier eingeben

Ich habe es bis TeX Live 2012 getestet.

Antwort3

Wenn nur TeX-Grundelemente verwendet werden, sollte der Code folgendermaßen aussehen:

\def\forcebeginwith#1#2{\fbwA .#1\end .#2\end{#1}{#2}}
\def\fbwA #1#2\end #3#4\end #5#6{%
   \ifx #1#3%
      \ifx \end#4\end #5% S2 is included at the start of S1, print S1 only
      \else 
          \ifx \end#2\end {#5} shorter than {#6}, something wrong%
          \else \fbwB {#2\end #4\end {#5}{#6}}%
          \fi
      \fi
   \else #6#5% S2 isn't inluded at the start of S1, print S2S1.
   \fi
}
\def\fbwB #1\fi\fi#2\fi{\fi\fi\fi \fbwA #1}

% test:

\message{\forcebeginwith{fancycolor}{fancy}}

\message{\forcebeginwith{color}{fancy}}

\bye

Beachten Sie, dass TeX nicht mit „Strings“ arbeitet, es gibt nur Token-Listen.

Antwort4

Die folgende, auf LuaLaTeX basierende Lösung definiert ein Benutzermakro namens \forcebeginwith. Es sollte mit Versionen des LaTeX-Kernels funktionieren, die deutlich älter als ein Jahrzehnt sind, da sich die Eigenschaften des \directluaPrimitivs seit seinem ersten Erscheinen nicht wirklich geändert haben. Da \directluaerweiterbar ist, ist auch erweiterbar \forcebeginwith. Beachten Sie, dass die Argumente von \forcebeginwithnicht ASCII-codiert sein müssen; sie können stattdessen UTF8-codiert sein.

Bildbeschreibung hier eingeben

% !TEX program = lualatex
\documentclass{article} % or some other suitable document class
\directlua{% Define the Lua function 'forcebeginwith':
   function forcebeginwith ( s1 , s2 )
      if unicode.utf8.sub ( s1 , 1 , unicode.utf8.len ( s2 ) ) == s2 then
         return ( s1 )
      else
         return ( s2..s1 )
      end
   end
}
\newcommand\forcebeginwith[2]{%
   \directlua{ tex.sprint ( forcebeginwith ( "#1" , "#2" ) ) }}

\newcommand\Za{color}
\newcommand\Zb{fancy}

\begin{document}
\obeylines % just for this document
\forcebeginwith{fancycolor}{fancy}
\forcebeginwith{color}{fancy}

\smallskip
% Demonstrate that '\forcebeginwith' is expandable
\forcebeginwith{\Zb\Za}{\Zb}
\forcebeginwith{\Za}{\Zb}
\end{document}

verwandte Informationen