Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add f:resource() for adding resources from XSLT #2062

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

xworld21
Copy link
Contributor

@xworld21 xworld21 commented Apr 1, 2023

Fix #2060: implement a function f:resource() that copies the desired file and returns the relative path in the site directory. This is meant to be used in XSLT as e.g.

<link rel="stylesheet" href="{f:resource('theme.css')}"/>

It is just a thin layer over copyResource and for instance accepts an extra argument for the mime type, which triggers the usual special behaviour for Javascript and CSS.

Incidentally, f:resource() can in principle shift the entire ltx:resource mechanism from Perl to XSLT: if the templates for ltx:resource call f:resource(), then the special code @resnodes = $doc->findnodes('//ltx:resource[@src]') in process becomes redundant.

Note that register_function is called once for every document being processed, because it needs to capture the variable $doc. This seems to be fine for LibXSLT, and probably the indended use, since there is no unregister_function.

@xworld21 xworld21 force-pushed the xslt-require-resource branch 2 times, most recently from e56c19c to 32054c0 Compare April 2, 2023 11:26
@xworld21
Copy link
Contributor Author

xworld21 commented Apr 2, 2023

Just realised I could make it quite simpler, after reading more carefully the documentation of XML::LibXML::NodeList.

Right now, you cannot quite call f:resource() from within exsl:document(), because the returned URIs are always relative to $doc. exsl:document() is broken anyway, but, should you decide to merge #1951 or some variation thereof, I can update this PR with the correct URIs. Of course the code will get a tad longer in that case.

@brucemiller
Copy link
Owner

Using perl extension functions in the XSLT makes me a bit leary (I may have had problems with them in the past?), and I'm trying not to be too tied to libxslt. Is there a difficuilty getting the appropriate ltx:resource into the documents?

@xworld21
Copy link
Contributor Author

Is there a difficuilty getting the appropriate ltx:resource into the documents?

I see two difficulties, (1) a stylesheet cannot generate <ltx:resource> as it gets called too late in the process, (2) I want the stylesheet to generate the corresponding e.g. <link rel="favicon"> and so it needs to know the correct relative URL. Item (2) is probably manageable within the current code, but I don't know how to do (1).

@brucemiller
Copy link
Owner

I guess that you case (1) is really the question I was asking: What are the scenarios where you'd not have been able to add ltx:resource to the XML document before the XSLT sees it, as opposed to not knowing until the XSLT?

@xworld21
Copy link
Contributor Author

What are the scenarios where you'd not have been able to add ltx:resource to the XML document before the XSLT sees it, as opposed to not knowing until the XSLT?

Ah, I see, good question. My concern is about my BookML users who still use latexml and latexmlpost directly. For them, I need to have all additional CSS resources added during the latexml phase, which is time consuming, and one has to compile the XML file again to change styles. Postprocessing would be the ideal phase for those bits.

Another hack in BookML is that I have to fudge the mime type with additional info, like ;bmllocation=body&bmlname=example, to stop the standard processing (which would add links and scripts to the head) and do other stuff. f:resource() would make this natural. Coupled with #1951, it makes XSLT a lot more powerful, with little code.

Still, modifying the XML file between the phases is not impossible and the mime type hack is reliable enough, it just needs to happen outside of the LaTeXML workflow.

@brucemiller
Copy link
Owner

All else equal, the idea is a nice one. The main problem is that I have circumstances where the same stylesheets have to work under different XSLT (eg. saxon). So, I'm fishing for some not-quite-as-elegant solutions.

At least the common stuff, css and javascript, you can specify on the latexmlpost command line as many as you'd like; and there is --icon=favicon.ico option for favicon, as well. Perhaps there are some generalizations to apply here?

@xworld21
Copy link
Contributor Author

xworld21 commented Aug 6, 2023

The main problem is that I have circumstances where the same stylesheets have to work under different XSLT (eg. saxon). So, I'm fishing for some not-quite-as-elegant solutions.

Interesting, that's a tricky one. How does saxon deal with <ltx:resource> in this workflow? I suppose you simply assume that @src points at the (already copied) resource.

In practice: let me add a dummy <func:function name="f:resource"> implementation that simply returns its argument unchanged (like e.g. f:url). Then the stylesheets remain valid in all settings, and f:resource gains special behaviour only with latexmlpost. Is that equivalent to <ltx:resource> now (meaning: if we replace the special perl code for <ltx:resource> with f:resource, would it behave exactly the same)?

@brucemiller
Copy link
Owner

Interesting, so now if one inadvertently uses f:resource in the "wrong" xslt engine, rather than an error, we'll silently get different behavior? Hmm, brownie points for cleverness, but I'm still kinda worried.

@xworld21
Copy link
Contributor Author

xworld21 commented Aug 9, 2023

now if one inadvertently uses f:resource in the "wrong" xslt engine, rather than an error, we'll silently get different behavior

Yeah, the code is simple, but finding the right semantics not so much. It could be:

  1. f:resource() is a declaration: the postprocessor is completely responsible for it
  2. f:resource() is an imperative command (better named f:copy-resource() in that case): it should return an error or a warning if it's not implemented by the postprocessor

Approach 1. is virtually equivalent to <ltx:resource> (which is handled in perl, not XSLT), but: reading <ltx:resource> is trivial, whereas one must run the stylesheet to determine the arguments of f:resource(). That makes it harder to implement outside of latexmlpost.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

allow XSLT stylesheets to declare additional resources to be copied over
2 participants