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.

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.

| improve this answer | |
  • 1
    Add \usepackage[utf8]{inputenc} for not losing characters like I did :P – koleygr Aug 25 '19 at 13:58
  • Seems to work fine, I was unsure on how to use \csname (as seen in other Q&As), thanks a lot! – Archein von Drakenov Aug 25 '19 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

| improve this answer | |
  • Thanks for this alternative! Why would you avoid the g-argument type? – Archein von Drakenov Aug 26 '19 at 17:09
  • 1
    @ArcheinvonDrakenov It is a foreign syntax to LaTeX. – egreg Aug 26 '19 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? – Archein von Drakenov Aug 26 '19 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}
| improve this answer | |
  • 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. – Archein von Drakenov Aug 26 '19 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. – Ulrich Diez Aug 27 '19 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. ;-) – Ulrich Diez Aug 27 '19 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. – Ulrich Diez Aug 27 '19 at 18:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.