Prefigure "macros" via XSL

26 views
Skip to first unread message

Andrew Scholer

unread,
Oct 3, 2025, 11:39:49 AMOct 3
to prete...@googlegroups.com

Mostly for David, but possibly of interest to anyone using Prefigure to make complex diagrams.

I am interested in making "macros" to simplify authoring repeated combinations of Prefigure primitives. The approach I came up with is to author the macros as xml elements like <author:variable> in the "raw" source for a diagram and use XSLT to transform that raw diagram into a processed version that contains only valid Prefig elements.

Two simple examples of the approach are here:
https://github.com/ascholerChemeketa/prefigure-macro-playground

While this can be done by an author (simply run a transformation on a directory of raw diagrams to produce the ones in the directory you have prefix process), I have suggested to David that it might be nice to integrate this as an optional step. Perhaps in the prefig publisher file, one could specify the XSL file(s) to apply to the source documents before prefig itself parses the document.

Advantages of this approach:
  • Minimal changes to prefig. And minimal future support work (vs trying to develop a custom macro language).
  • Target is prefigure. Because macros are preprocessed, the macro writer just needs to understand prefigure syntax to generate correct output. One could imagine an alternate "macro" system that was applied later in the build process by extending the existing python code to augment the transformation from prefigure XML to SVG. Anyone authoring macros in that system would need to understand the SVG syntax.
  • Can leverage definitions by either intentionally ignoring them (passing them through unmodified for prefig to deal with), or by parsing the values out of strings. The sample above uses a definition `xBase` that gets "passed through" the macro.

Disadvantages:
  • Most authors don't know XSL (yet!). But anyone doing a book's worth of diagrams with similar elements would probably have the motivation to cobble together a "macro" from examples.
  • Does not play nicely with <repeat>. The only way I can see this working would be to have the XSL try to implement the repeat logic, but that would be tricky for something like <repeat parameter="center in centers">. So any repetition needs to be handled by the macro. If I wanted to draw an "array" by repeating my "variable" element, I would need to write an array macro that drew all the variables and not just use a <repeat> around my variable in the raw source.

Andrew Scholer
Computer Science Instructor / Program Chair
Chemeketa Community College
Office hour info: https://computerscience.chemeketa.edu/people/andrew-scholer/

David Austin

unread,
Oct 5, 2025, 10:07:33 AMOct 5
to prete...@googlegroups.com
Thanks for putting this demonstration together, Andrew.  This shouldn't be too hard to implement on my end, and I'd like to provide this support.  

In your examples, you import a second stylesheet, which raises a question about where everything will live.  As you know, when building diagrams in a PreTeXt document, everything gets copied over into a temporary directory so any relative pathnames, like the ones in your examples, will most likely break.  We talked last week about using xi:include to load a stylesheet so I'm concerned about relative imports.  I can also imagine treating a stylesheet as "external data" that gets copied over into the temporary build directory, which may be more straightforward.  I'm wondering if you have thoughts about this and how best to support the authoring experience.

I'll be at drop-in tomorrow, if it's easier to talk this through together.

--
You received this message because you are subscribed to the Google Groups "PreTeXt development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pretext-dev...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/pretext-dev/CACm44N--NZ%2BsPZYdTPTBKq1DZGP8Ozq377-dKE%3D5PAWOV_pBNQ%40mail.gmail.com.

David Austin

unread,
Oct 6, 2025, 9:45:22 PMOct 6
to prete...@googlegroups.com
This is most likely for Andrew or Rob:  

I have added an element to PreFigure that will read in an XSL stylesheet and transform the source before compiling.  It's working well in the standalone version of PreFigure, but within a PreTeXt document, the application of the extract-prefigure stylesheet fails, seemingly due to a namespace issue.

The PreFigure source is in its own namespace, and Andrew's example includes a second namespace for elements that are meant to be transformed.  So the #diagram element in the original source looks like this:

<diagram dimensions="(300,200)"
         margins="5"
         xmlns="https://prefigure.org"
         xmlns:author="http://example.org">

Later on, there is an element 

        <author:variable name="x"
                         value="10"
                         anchor="(xBase, 30)"/>

When included in a PreTeXt document, this element is included in the extracted PreFigure source as

        <author:variable name="x" value="10" anchor="(xBase, 30)" ="root-3"/>

Note the final attribute, which does not have a name to the left of the equal sign.  I'm not sure why the extraction script adds this nameless attribute, but if I remove the "author" namespace, then the extraction proceeds smoothly (but PreFigure, naturally, does not properly apply the stylesheet).

Any thoughts?

David

Andrew Scholer

unread,
Oct 7, 2025, 1:24:22 AMOct 7
to prete...@googlegroups.com
This template is related to the issue (pretext-assembly.xml:2148):
<xsl:template match="pf:*|xhtml:*" mode="id-attribute">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" mode="id-attribute"/>
    </xsl:copy>
</xsl:template>

That applies the id-attribute template with no parameters. That template looks like:

<xsl:template match="*" mode="id-attribute">
    <xsl:param name="parent-id"  select="'root'"/>
    <xsl:param name="attr-name"  select="''"/>
    ...

The attr-name is thus empty which is an invalid name for the attribute.

I am thinking maybe that original template should just apply to attributes and not nodes???

Andrew

David Austin

unread,
Oct 7, 2025, 7:21:14 AMOct 7
to prete...@googlegroups.com
Thanks for investigating, Andrew.  I'm not so great with XSL, but everything built cleanly when I removed "|node()" from that apply-templates element.

Also, I see that at line 2058 of pretext-assembly.xsl, in case others are following along:  https://github.com/PreTeXtBook/pretext/blob/39ec765dbc7c283dd483d1eb515f4d780cc097b5/xsl/pretext-assembly.xsl#L2058

David

Rob Beezer

unread,
Oct 9, 2025, 12:48:32 PMOct 9
to prete...@googlegroups.com
Been off-duty for a while, but have been following this discussion. Sorry to be
so late to the party.

Being able to easily make multiple similar diagram elements, each with a twist
(variable), is definitely a very worthwhile feature.

I feel that some sort of XML declaration, which might be part of a
pre-processing phase, that creates the necessary elements (as legal PreFigure
code) would be the best approach. Maybe it is an expansion of PreFigure's
#repeat (which I have yet to experimrent with). Even if it is maybe not
complete or robust enough to handle every possibility.

One of our unwritten goals is to "not repeat the mistakes of LaTeX". The
ability to define macros in LaTeX, and the fact that LaTeX is a programming
language, are major contributors to many of the shortcomings of LaTeX, and
PreTeXt is a reaction to that.

Elements defined on a per-author basis, even in some sort of namespace, sounds
like a minefield to me. Requiring XSL from an author in order to render a
document sounds even more dangerous (and very LaTeX-like). There is no way to
guarantee that new elements will be handled properly throughout the various
PreTeXt stylesheets (witness the latest difficulty here with the preprocessor,
which I will study next).

Yes, we allow "extra XSL" via some limited support. I would understand this to
be alternate interpretations of existing elements, or the use of additional
attributes to influence behavior (I'm looking at you, Sean F). I have
additional elemements in my FCLA source, since the book was designed before
PreTeXt was. Right now, these are preventing me from building and updating,
since the additional XSL is broken. And I sort of understand the internals of
PreTeXt.

Without experimenting, I can't wrap my head around the neccessary namespace
declarations and stylesheet imports to make this happen.

And I can't say I have a great idea about how to make some sort of "for loop"
construction that can employ variables to produce multiple PreFigure elements.
But I'd like to suggest this route as being a better long-term solution, and so
worth more effort.

Rob

Rob Beezer

unread,
Oct 9, 2025, 1:00:36 PMOct 9
to prete...@googlegroups.com
On 10/6/25 18:45, David Austin wrote:
> I have added an element to PreFigure that will read in an XSL stylesheet and
> transform the source before compiling.  It's working well in the standalone
> version of PreFigure, but within a PreTeXt document, the application of the
> extract-prefigure stylesheet fails, seemingly due to a namespace issue.

Not sure where to begin here. This mode makes "ID" attributes on elements. I
think there are three such attributes (we might only really need two), but they
all use the same scheme, hence some generality afforded by parameters and we get
consistency.

The particular template in question is matching items from non-PreTeXt
namespaces, namely (X)HTML and PreFigure. So if I was to also guess about
adjustments needed for these experiments, I might add "author:*" to the match.
Which then requires coordination between this stylesheet and others that employ
an "author" prefix.

Perhaps the mode="id-attribute" could be improved. But I think it works just
fine right now.

My second guess is that this is just the tip of the iceberg if we are to
introduce a namespace for arbitrary new elements.

Rob

David W. Farmer

unread,
Oct 10, 2025, 8:52:39 AMOct 10
to prete...@googlegroups.com

One of the aspects of LaTeX which was not totally terrible
is how it (wants you to) handle macros, vs how that is done in
practice or how it is in plain TeX.

Suppose the only author option for macros was to use
\newcommand{\cmmd}[numargs]{thedefinition in terms of #1, #2, ...}
in a straightforward way, and only in the preamble.

Then it is not difficult to preprocess (i.e., expand) all of
those into a source document with no special author macros.

In particular, the author is not allowed to define or change a
macro in the middle of the document, and you cannot use \renewcommand.
And you can't do crazy plain TeX definitions.

Something like that is "repeating what LaTeX almost got right",
as opposed to repeating a mistake.

The syntax for declaring a macro is not so important, as long
as it is straightforward for the author to understand the pattern.
In particular, we dictate the syntax and what is allowed.
This will somewhat decrease the flexibility, but I am guessing it can do
most of what is wanted. And to my non-XSL-aware eye, seems not too bad to
maintain and maybe not too easy to abuse?

Regards,

David


David Austin

unread,
Oct 10, 2025, 4:41:59 PMOct 10
to prete...@googlegroups.com
Thanks for all of these comments.  This is an interesting discussion, and I'm hoping we can continue in person Monday at drop-in.

David

--
You received this message because you are subscribed to the Google Groups "PreTeXt development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pretext-dev...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages