Closed robertbachmann closed 7 months ago
Maybe, it should be better to create a "prefix" for more general usage, like \newpublic
is. For example its name can be \newonly
and we can use \newonly\def\foo
, \newonly\edef\foo
, \newonly\mathchardef\foo
, \newonly\newcount\foo
and we can use \newonly{\long\def}\foo
. This prefix can be created as loadable trick.
Yes, that would work as well!
The only thing I would need that \newonly
would work with both \def
and \sdef
.
I think the following should work:
<h2><a name="newonly"></a>Only define a macro if it is not already defined</h2>
<p CLASS="rmarg">
autoload:<br>\newonly
</p>
<p>
LaTeX has <code>\providecommand{\NAME}{...}</code>
that only defines <code>\NAME</code> if it was not already defined.
We can achieve this in OpTeX by wrapping <code>\def\NAME{...}</code> inside
<code>\isdefined{\NAME}\iffalse ...\fi</code>.
However, this will get verbose if we need to define many macros in this manner.
Therefore, we implement a similar functionality as a prefix macro <code>\newonly</code>.
</p>
<p>Usage examples:</p>
<pre>
\newonly\def\mymacro#1{...}
\newonly\let\myfont=\bf \newonly\let\myfont\bf
\newonly\slet{myfont}{bf}
\newonly{\protected\long\def}\foo#1{...}
\newonly\newtoks\mytoks
</pre>
<p>The implementation:</p>
<pre>
\def\newonly#1#2{\begingroup%
\edef\tmpA{\_noprefix{#2}}%
\edef\tmpB{\string #2}%
\ea\ifcsname\tmpA\endcsname%
\ifx\tmpA\tmpB% #2 has no backslash
\gdef\newonlyA{#1{newonlyB}}\else%
\gdef\newonlyA{#1\newonlyB}\fi%
\else%
\ifx\tmpA\tmpB%
\gdef\newonlyA{#1{#2}}\else%
\gdef\newonlyA{#1#2}\fi%
\fi\endgroup\newonlyA}
</pre>
<p CLASS=datum>(0129) -- Robert Bachmann 2024-02-11<p>
edit: I can prepare a PR in the evening or on monday
\ea\endgroup\newonlyA
and \def
instead \gdef
(4x).\_noprefix
and no single \csstring
? I mean that nobody needs to use \newonly\def\_foo
. Moreower it is bad because \foo
is checked but \_foo
is redefined.\newonly
for this prefix was my first idea. If you can find better name, use it.\def\softdef{\newonly\def}
, \def\softsdef{\newonly\sdef}
should be mentioned in the OpTeX trick too. Thanks for your feedback.
It's a bit hard to find a good name: things I like so far \onlynew
and \onlyifnew
:
LaTeX has \providecommand{\NAME}{...}
that only defines \NAME
if it
was not already defined. We can achieve this in OpTeX by wrapping
\def\NAME{...}
inside \isdefined{\NAME}\iffalse ...\fi
. However,
this will get verbose if we need to define many macros in this manner.
Therefore, we implement a similar functionality as a prefix macro
\onlyifnew
.
Usage examples:
\onlyifnew\def\mymacro#1{...}
\onlyifnew\let\myfont=\bf \onlyifnew\let\myfont\bf
\onlyifnew\slet{myfont}{bf}
\onlyifnew\newtoks\mytoks
\onlyifnew{\protected\long\def}\foo#1{...}
In the last case, it could be useful to define a shortcut such as:
\def\mylpdef{\onlyifnew{\protected\long\def}}
\mylpdef\foo#1{...}
The implementation:
\def\onlyifnew#1#2{\begingroup%
\edef\tmpA{\csstring #2}%
\edef\tmpB{\string #2}%
\ea\ifcsname\tmpA\endcsname%
\ifx\tmpA\tmpB% #2 has no backslash
\def\onlyifnewA{#1{onlyifnewB}}\else%
\def\onlyifnewA{#1\onlyifnewB}\fi%
\else%
\ifx\tmpA\tmpB%
\def\onlyifnewA{#1{#2}}\else%
\def\onlyifnewA{#1#2}\fi%
\fi\ea\endgroup\onlyifnewA}
OK, would you prepare the pull request?
LaTeX has
\providecommand{\NAME}{...}
, that is a shorthand for:(see https://latexref.xyz/_005cprovidecommand.html)
In the past I've used this pattern in OpTeX:
However since I define multiple macros that way (use case explained below), it got way to verbose and I decided to write my own macro
\softdef
and\softsdef
:It's written so that for example
\long\protected\softdef\foo
would also do the right thing.Notes:
\let
so I never looked into that.\providedef
and\providesdef
. I'm currently prefering "soft" since it makes more sense to me, but don't care strongly about the name of the macros.My proposal:
I think I would prefer base since I think autoloading might get confusing:
This case would work:
This case would most likely not work without explicit '\loadtrick\softdef' beforehand:
However if you don't want to have these macros in the base format, it's also fine. I can do '\loadtrick\softdef' beforehand.
Please let me know, so I can prepare a pull-request for option a or b.
Side note: My use case
For the pandoc optex writer I'm using some helper macros. Backgroun: When converting
**xy**
, pandoc does<strong>xy</strong>
for HTML\textbf{xy}
for LaTeX (because the maintainers don't want to use custom macros)So for HTML the user can easily customize with CSS:
For LaTeX he would need to overwrite
\textbf
which might cause some unwanted side effects.For the OpTeX writer I decided¹ against
{\bf xy}
instead I produce\strong{xy}
and provide a default defintion for\strong
at the top of the generated document/document fragment².If the user wants a different style he can simply:
\strong
is just one example. Another example would be[Some marked text]{.mark}
(<mark>
html element) or* * *
(<hr>
)¹ can be added as toggle-able option if someone really needs it ² fragment: Pandoc can generate standalone documents or partial documents (fragments). For TeX these fragments would then be usually included via
\input
.