2

I have made a file (macro_file.tex) that contains my homemade macros to use in another file (my_document.tex). In my_document.tex, I input macro_file.tex in the preamble in order to use the macros while writing. Some of the commands in macro_file.tex should not be accessible in my_document.tex because they should only be used by other macros in macro_file.tex.

Is that (easily) possible?

5
  • 2
    One can use grouping to limit the extent to which the results of macros are accessible to other parts of the code; one can also use, within style files, the \makeatletter macro-naming convention (@ in macro names) to somewhat restrict accidental use in the primary document. However, I don't know of a way to guarantee the macro itself inaccessible to the main document. Dec 4, 2017 at 11:49
  • Untested: you may be able to obfusciate macro names by generating a random string, rename all 'private' macros by appending the private string (like '\MymacroWoRSQe'), in other macros replace calls to the internal macros with the new names using xpatch, and finally undefining the random string. This will make it harder to access the macros from the main document. Question is: why do you want to restrict access?
    – Marijn
    Dec 4, 2017 at 13:30
  • @Marijn: I want to restrict access because the users of my macro file should only use some of the macros, not the "auxiliary" macros.
    – Thomas
    Dec 5, 2017 at 15:00
  • @Thomas the easiest solution is probably to tell your users not to call these macros (i.e., write this down in your documentation). If they still want to do it then it is at their own risk.
    – Marijn
    Dec 6, 2017 at 14:20
  • Side note: some languages (e.g. Python) have no true private variables too, only conventions and "don't-call-this" documentation.
    – user202729
    Jan 22, 2022 at 0:16

1 Answer 1

1

You can use special catcodes in your macro_file.tex. For example you could issue \catcode`$=11\relax at top of your file, and use $ as a letter in all your internal macro names. At end of file \catcode`$=3\relax of course.

Then you have public macros (not using $ in their names) which use private macros (using $ in their names) and it requires deliberate action to access directly these private macros.

(one could imagine some very complicated scheme where your private macros would refuse to work except if some sets of flags are set, but it would always be possible to recreate artificially the validation, simply by looking at what your public macros do).

By the way, notice that the above is exactly what TeX/LaTeX does with the @ letter ... but after twenty years people know about \makeatletter and the trick is not as efficient ;-)

The choice of $ may cause syntax highlighting in your TeX aware editor go crazy... LaTeX3 and other packages use _ and : as private letters. You can also use ^ or ? for example which will not put your TeX aware editor in confused state.


cont. from comment. As said above TeX/LaTeX uses @ as private letter. As a continuation of this, you could use ^^@ as private letter. It is TeX input for ascii code 0, and in LaTeX by default the NULL byte (or the ^^@) is invalid and causes a failed build.

Casual user will not immediately know that the \catcode0=11\relax in your file is in anyway related to usage of ^^@ in your private macro names

\catcode0=11\relax
....
\def\my^^@private^^@macro{...}
\newcommand\publicmacro{\my^^@private^^@macro...}
...
\catcode0=15\relax % default LaTeX's config

(you should actually reset \catcode0 to its original, not force 15 which is "invalid status").

This way is thus slightly more challenging for user than @ for which \makeatletter is available. It would not help here.

1
  • you can even use even more devious obfuscating. LaTeX has the NULL byte catcode set to invalid. So if you say \catcode0=11\relax at top of your file (and \catcode0=15\relax at end, you can use ^^@ in your macro names such as\my^^@macro. Standard user will not have a clue about ^^@ being TeX input for ascii code 0. You can also define all your private macros to contain a space in their names, \@namedef{my macro with space}{...} and then use them via \@nameuse. But again this can be replicated.
    – user4686
    Dec 8, 2017 at 10:20

You must log in to answer this question.

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