5

Greetings from Switzerland,

(I apologise for this poorly worded question)

Is it possible to create a command "root" (e.g. \law, with a fixed structure as detailed below, never used in the document itself) and subsequently create other "subcommands" (e.g. \lawbueg, \lawbuev, \lawkbueg) depending on my needs?

Here is a MWE:

\documentclass{article}
\usepackage{xstring}
\usepackage{xifthen}
\usepackage{xparse}

\DeclareDocumentCommand\law{ m m g g}{% 
    {Art.~#2%
        \IfNoValueF {#3} {%
            \IfInteger{#3}%
            {~Abs. #3}%
            {~lit. #3}%
        }%
        \IfNoValueF {#4} {%
            \IfInteger{#4}%
            {~Ziff. #4}%
            {~lit. #4}%
        }%
        ~#1}%
    }

% law-command "generator"
\newcommand[2]{\createlaw}{<unsure how to proceed here>}
   % #1 needs to be stuck right after \law and before the first {, in order to create a new separate command every time I use \createlaw
   % #2 this argument needs to correspond to #1 in \law above

%Examples:
%\createlaw{bueg}{BüG}
%\createlaw{kbueg}{KBüG}


\begin{document}

Hello, I'm \lawbueg{21}{2}{b}, and I'm \lawkbueg{43}{1}.

\end{document}

I'd be grateful for any help.

3 Answers 3

4

Here is a way that works for this MWE but I don't really know if it works for you (for your real needs):

\documentclass{article}
\usepackage{xstring}
\usepackage{xifthen}
\usepackage{xparse}

\DeclareDocumentCommand\law{ m m g g}{% 
    {Art.~#2%
        \IfNoValueF {#3} {%
            \IfInteger{#3}%
            {~Abs. #3}%
            {~lit. #3}%
        }%
        \IfNoValueF {#4} {%
            \IfInteger{#4}%
            {~Ziff. #4}%
            {~lit. #4}%
        }%
        ~#1}%
    }

% law-command "generator"
\newcommand{\createlaw}[2]{%
\edef\temp{\law{#2}}
\expandafter\expandafter\expandafter\global\expandafter\let\csname law#1\endcsname\temp
}
   % #1 needs to be stuck right after \law and before the first {, in order to create a new separate command every time I use \createlaw
   % #2 this argument needs to correspond to #1 in \law above

%Examples:
\createlaw{bueg}{BüG}
\createlaw{kbueg}{KBüG}


\begin{document}

Hello, I'm \lawbueg{21}{2}{b}, and I'm \lawkbueg{43}{1}.

\end{document}

Output:

Hello, I’m Art. 21 Abs. 2 lit. b BG, and I’m Art. 43 Abs. 1 KBG.

2
  • 1
    Add \usepackage[utf8]{inputenc} for not losing characters like I did :P
    – koleygr
    Aug 25, 2019 at 13:58
  • Seems to work fine, I was unsure on how to use \csname (as seen in other Q&As), thanks a lot! Aug 25, 2019 at 14:26
7

I would avoid the g argument type. Anyway, here's a solution that also implements \IfIntegerTF in place of \IfInteger of xstring.

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand\law{ m m g g}{%
  Art.~#2%
  \IfNoValueF{#3}{%
    \IfIntegerTF{#3}%
      {~Abs. #3}%
      {~lit. #3}%
  }%
  \IfNoValueF{#4}{%
    \IfIntegerTF{#4}%
      {~Ziff. #4}%
      {~lit. #4}%
    }%
  ~#1%
}

\ExplSyntaxOn
% law-command "generator"
\NewDocumentCommand{\createlaw}{mm}
 {
   % creates \law#1
   % #2 is the first argument to \law
   \cs_new_protected:cpn { law#1 } { \law{#2} }
 }
\NewDocumentCommand{\IfIntegerTF}{mmm}
 {% [\+\-]? is zero or one sign; \d+ is one or more digits
  \regex_match:nnTF { \A [\+\-]? \d+ \Z } { #1 } { #2 } { #3 }
 }
\ExplSyntaxOff

\createlaw{bueg}{BüG}
\createlaw{kbueg}{KBüG}

\begin{document}

Hello, I'm \lawbueg{21}{2}{b}, and I'm \lawkbueg{43}{1}.

\end{document}

enter image description here

3
  • Thanks for this alternative! Why would you avoid the g-argument type? Aug 26, 2019 at 17:09
  • 1
    @ArcheinvonDrakenov It is a foreign syntax to LaTeX.
    – egreg
    Aug 26, 2019 at 17:10
  • After copying your solution as is (no editing, trying once with xstringe, once without), it doesn't seem to work unfortunately (all commands are "undefined control sequences)... might it be due to a conflict with another package? Aug 26, 2019 at 17:25
2
\documentclass{article}
\csname @ifundefined\endcsname{XeTeXrevision}{%
  \csname @ifundefined\endcsname{luatexversion}{%
    \usepackage[utf8]{inputenc}%
  }{}%
}{}%
\usepackage{xstring}
\usepackage{xifthen}
\usepackage{xparse}

% The periods in your commands do _not_ denote sentence endings.
% Thus something needs to be done for avoiding the spacefactor-thingie
% with punctuation-marks -- see TeXBook, Chapter 12: Glue:
%
% | Abbreviations present problems too. For example, the short story in
% | Chapter 6  referred to Mr. `Droofnats'; TeX must be told somehow that
% | the period after `Mr.' or `Mrs.' or `Prof.' or `Dr.' or `Rt. Hon.'
% | etc., doesn't count as a sentence-ending full stop.
% | [...]

\DeclareDocumentCommand\law{ m m g g}{% 
  Art.~#2%
  \IfNoValueF {#3} {%
    \IfInteger{#3}%
              { Abs.~#3}%
              { lit.~#3}%
  }%
  \IfNoValueF {#4} {%
    \IfInteger{#4}%
              { Ziff.~#4}%
              { lit.~#4}%
  } %
  #1%
}


% law-command "generator"
\newcommand\createlaw[2]{%
  \expandafter\DeclareDocumentCommand\csname law#1\endcsname{}{\law{#2}}%
}%


%Examples:
\createlaw{bueg}{BüG}
\createlaw{kbueg}{KBüG}

\begin{document}

Hello, I'm \lawbueg{21}{2}{b}, and I'm \lawkbueg{43}{1}.

\end{document}
4
  • Thanks for the tip regarding the tilde, I wasn't sure if having a space after the } on the line immediately before #1 in \law was stable enough when I first typed the command. And you're absolutely right, "Art./Abs./lit. ..." should be considered as an unbreakable block, but breakable between Art. and Abs. for example. Aug 26, 2019 at 20:38
  • 1
    Horizontal space with "linebreak instead of horizontal space" allowed versus horizontal space with "linebreak instead of horizontal space" not allowed is one issue. Another issue is whether a horiz. space is allowed to shrink/stretch depending on the space-factor of the preceding character. With so-called non-french spacing punctuation-marks like periods usually cause the horiz. space to be large: This way larger horizontal spaces are achieved between sentences. But the horizontal space to be that large is not desired when the period doesn't denote the end of a sentence but an abbreviation. Aug 27, 2019 at 17:27
  • 1
    About "I wasn't sure if having a space after the } on the line immediately before #1 in \law was stable enough": After the closing curly brace (La)TeX's reading-apparatus is in state M (Middle of a line). (The story about the reading-apparatus is told in TeXbook Chapter 8: The Characters You Type.) In this state a space/a character in the input that has category code 10 (space) will be tokenized as space token (where a line-break instead of insertion of horizontal glue is allowed). In case you are interested in the full story, don't hesitate to start another thread. ;-) Aug 27, 2019 at 17:41
  • 1
    Usually ~ inserts a non-breaking space which leads to insertion of horizontal glue like an ordinary space character when the space-factor is 1000. When using expl3 with \ExplSyntaxOn, things are changed: The space-character has category-code 9 (ignored) and the tilde has category code 10 (space). This means: With \ExplSyntaxOn space-characters that occur in the input will be ignored and thus not yield any token at all. A tilde ~ that occurs in the input will yield insertion of a space-token into the token-stream where a line-break instead of insertion of horizontal glue is allowed. Aug 27, 2019 at 18:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .