Repository navigation
XSLT stylesheets compiled to C# by a source generator: Native AOT - #5
Open
simonebortolin wants to merge 4 commits into
Open
simonebortolin wants to merge 4 commits into
simonebortolin wants to merge 4 commits into
Conversation
SharpEquations.XsltGenerator compiles the three XSLT 1.0 stylesheets of Resources (omml2mml, mml2omml, mtef2mml) to C# at build time: a method for each template, the dispatch of apply-templates by element name, the XPath expressions as typed C# over Internal/Xslt (the XPath data model over LINQ to XML, and the result tree). XslCompiledTransform, which emits IL at run time, is gone: the library is IsAotCompatible on net10.0 and runs under Native AOT, and the stylesheets are no longer embedded. The output is what XslCompiledTransform gave, as text parsed again (disable-output-escaping as markup, empty text as <t></t>); CompiledStylesheetTests compares the two on the corpora. Strings are counted by code points, as XPath defines them, where XslCompiledTransform counted UTF-16 units: only characters outside the basic plane without a plain-letter form (emoji) are written differently in OMML. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Pre-release NuGet package of 788f2bb. Updated on every push, deleted when this PR is closed. |
simonebortolin
force-pushed
the
claude/xslt-generator
branch
2 times, most recently
from
November 11, 2026 00:03
bddcb10 to
169aab4
Compare
ctop.xsl, merged from main, is compiled by the generator, but its Transform had no defining declaration (CS0759): it is declared with the others and EquationStylesheets runs it. The emoji tests of OmmlAstralTests pinned the UTF-16 counting of XslCompiledTransform; the generated stylesheets count code points as XPath does, so 🍕 is written italic, in one run, and reads back to the same equation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyVioBuiMiSScbUYtdXLXq
# Conflicts: # BuildVersion.props
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
SharpEquations.XsltGenerator, a new source generator, compiles the three XSLT 1.0 stylesheets ofResources/(omml2mml.xsl,mml2omml.xsl,mtef2mml.xsl) to C# at build time.XslCompiledTransform, which emits IL at run time, is no longer used, so the library isIsAotCompatibleon net10.0 and runs under Native AOT.src/SharpEquations.XsltGenerator/): it generates a method for each template, a lazy property for each global variable and, for each mode, the dispatch ofxsl:apply-templates. The dispatch picks templates by element name first and follows the XSLT priority rules. XPath expressions become typed C# when their type is known, andobjectotherwise. Anything the stylesheets don't use (keys, sort, number, imports, extension functions) is a build error,XSLT001.src/SharpEquations/Internal/Xslt/): the XPath data model over LINQ to XML, the XPath functions, and the result tree. The output matches whatXslCompiledTransformgave once its text was parsed again: disable-output-escaping is treated as markup (mtef2mmlwrites character references in pieces), and empty text gives<t></t>.Stylesheets.csdeclares the generated classes as partial, so that Parlot, which compiles the project without the other generators, still compiles.Verification
Xslt/CompiledStylesheetTestscompares the compiled stylesheets withXslCompiledTransformon 2,122 inputs: the OMML of Word documents and of the UnicodeMathML examples, their MathML, and the MTEF fixtures. Every input without characters outside the BMP gives the same result.Behavior change
Strings are counted by code points, as XPath specifies;
XslCompiledTransformcounted UTF-16 units. In practice only characters outside the BMP that have no plain-letter form (emoji) are written differently in OMML. A single 🍕 is now treated as one character, and so losesm:sty p. Math alphanumerics such as 𝒢 and 𝟏 are unaffected, becauseOmmlSerializerwrites them as plain letters withm:scr/m:stybefore the stylesheet runs. The tests on branchclaude/astral-omml-tests-ae8c6bpin the current behavior and are not part of this PR.Costs
The first version is about 2–2.5× slower than
XslCompiledTransformon OMML, with about 3× the allocations: XPath steps become lists and LINQ. Making it faster is planned as follow-up work.VersionPrefix1.0.3 → 1.1.0.🤖 Generated with Claude Code