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

Provide packages with a way to handle raw content #1092

Closed
alerque opened this issue Oct 19, 2020 · 7 comments · Fixed by #1347 or #1373
Closed

Provide packages with a way to handle raw content #1092

alerque opened this issue Oct 19, 2020 · 7 comments · Fixed by #1347 or #1373
Labels
enhancement Software improvement or feature request modules:packages Issue relates to core or 3rd party packages
Milestone

Comments

@alerque
Copy link
Member

alerque commented Oct 19, 2020

The way the parser works, we currently have to tell the parser ahead of time what tags contain raw content that needs to be passed through to an external handler rather than recursively parsed for more SILE commands. This works great for our builtin \script{} command. It can also be amended quite easily as I've been assuming we would de for math (#220), Lilypond (#435), TikZ (#437), SVG (#1091), etc. if and when any of those things were bundled with SILE.

This does not work out very well for things like @ctrlcctrlv's texmode package (see discussion in #947) that we do not plan to bundle. In fact it means 3rd party packages are at a distinct disadvantage to bundled ones in what they can and can't do.

There is a workaround, but in requires invoking SILE with special arguments:

$ sile -e 'SILE.inputs.TeXlike.passthroughCommands.foo = true' -d foo test.sil

We should either think of a way for packages to inject their requested handling early (I can't think of one other than using two parsing passes) or make a more convenient interface for this and document it for use by 3rd party packages.

@alerque alerque added enhancement Software improvement or feature request modules:packages Issue relates to core or 3rd party packages labels Oct 19, 2020
@Omikhleia
Copy link
Member

Omikhleia commented Mar 11, 2022

(See #675 (comment) for the original context).

Instead of cramming more and more special commands into SILE.inputs.TeXlike.passthroughCommands, maybe a dumb idear, but why don't we modify the parser to accept (besides math and script, admittedly) only one single 'inline-escaping' command, say \inline[format=name, other options]{pass-through stuff}. We then have the pass-through content and the extra options ready to be provided to some package.

Note that since we are at parser level, we could even decide for something that doesn't look as a real SILE command, so it could as well be @inline(name)[other options] or whatever (= think to the 3-backslash escape in Markdown, or the <![CDATA... esacpe in XML) and not necessarily use braces, but perhaps custom begin-end markers (= think to shell script escaping e.g. cat << MEH ... MEH)...

But for the sake of simplicity here, let's admit we may prefer using a SILE-familiar syntax...

Eg.

\svg[src=somefile.svg, width=dimension}

vs.

\inline[format=image/svg+xml, width=dimension]{<svg>....</svg>}

Or even:

\inline[format=base64:image/svg+xml, width=dimension]{PHN2Zz4uLi48L3N2Zz4=}

Another possible use:

\inline[format=text/x-lua]{some Lua code}

(And let's thus have a real verbatim thing, with possibly a package that even does syntax highlighting for the said language)

Packages could "register" a callback function for supported types. Say, from the svg package, SILE.registerInlineHandler("image/svg+xml", function() ... end)

Interestingly, a base64 package in that scheme would not need any user servicing commands, but would register its own function for decoding the content and invoking the next inline handler.

In brief:

  • We just extend the parser with one special all-purpose inlining command. Impact on the parser is quite minimal and well separated from the rest.
  • SILE core just have to provide a fairly simple registration and mapping API.
  • 3rd party packages can thus register their callbacks when loaded, and get invoked back when an inline content needs them to act upon raw content.

Am I missing something?

@alerque
Copy link
Member Author

alerque commented Mar 11, 2022

An interesting idea. Off the top of my head I don't think it would play nice with the XML or other input methods, it would only work with SILE syntax where we define the grammar. As such the ASTs for different inputs would diverge. I'll have to sleep on that though.

Another idea might be just a keyword/macro trigger built into the language that adds/removes "passthrough" mode to specific commands via a callback in the LGEG grammar at runtime:

@passthrough{ftl}

A similar command could be used to disable passthrough mode. This would obviously need to be part of the document before any such tags were encountered.

@alerque
Copy link
Member Author

alerque commented Mar 12, 2022

Links to discussion in PR #675 that veered off into what this issue is about:

@alerque
Copy link
Member Author

alerque commented Mar 12, 2022

Having slept (poorly) on this, one downside I can see to my own previous suggestion about the parser finding a keyword to enable raw modes is that it would be limited to the primary document or segment being parsed. This would mean that a package could not enable a new tag to be passthrough for the main document. It could probably enable it for itself and any future strings that get parsed, but by the time the package include happens the primary document will already be parsed.

@alerque
Copy link
Member Author

alerque commented Apr 19, 2022

Clarifying usage for the -I argument and if my proposal in #1373 will make it just a little bit easier to get a path to allow people to add their own RAW commands.

Another note is that if the TOC iteration issues is fixed properly (cf. issue #230 and PR #593) then we would have a way to restart processing after one pass. This would possibly enable seeing a library load that added a raw tag, then re-parse the input with the new function(s) available. This might run into some issues with syntax validation on the initial pass, but a failed pass could also be a good time to restart if we had new parser rules registered. Somewhat inefficient maybe but ergonomic.

@alerque
Copy link
Member Author

alerque commented Jul 4, 2022

I expect the next release to have not one but 2 ways to handle this, one with the \raw command in #1347 and one using the new --requires CLI flag that will load a module early enough that it can modify the parser before it runs and hence allow modules to define their own raw commands.

@alerque
Copy link
Member Author

alerque commented Jul 19, 2022

Re-opening because the PR that closed this is the less direct of the two solutions slated for v0.14.0, I'll let the more direct answer be the final closer here.

@alerque alerque reopened this Jul 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Software improvement or feature request modules:packages Issue relates to core or 3rd party packages
Projects
None yet
2 participants