Skip to content

MarkdownRenderer structure step 2e: share the TextMateSharp adapter through an engine package - #113

Merged
Xueyang-Song merged 5 commits into
codex/markdown-renderer-1-0from
codex/markdown-renderer-textmate-engine
Oct 31, 2026
Merged

Xueyang-Song merged 5 commits into
codex/markdown-renderer-1-0from
codex/markdown-renderer-textmate-engine

Conversation

@Xueyang-Song

Copy link
Copy Markdown
Collaborator

Step 2, part 5 of the MarkdownRenderer structure cleanup. It is stacked on #112 and targets that branch; it retargets as the branches below it merge.

The TextMate grammar packs shared their TextMateSharp adapter by compiling one source file into both assemblies, the last file link in the renderer. That adapter now lives in a new shipping package, MarkdownRenderer.SyntaxHighlighting.TextMate.Engine, and both packs reference it. No file links remain, and no ProjectStructureException remains anywhere.

The engine package

You chose a shared engine package whose API takes TextMateSharp's registry options.

...SyntaxHighlighting.TextMate   (lean integration and provider contracts; no TextMateSharp)
  └─ ...TextMate.Engine          (TextMateSharpGrammarProvider; brings TextMateSharp and Onigwrap)
       ├─ ...Grammars.Common     (curated embedded grammars)
       └─ ...Grammars.All        (TextMateSharp.Grammars)
  • TextMateSharpGrammarProvider is the former internal BundledTextMateGrammarProvider, moved with history. It is unchanged apart from its constructor. The required inputs (revision, registry-options factory, scope resolver) come first, then optional allowedLanguageIds and options; null options now mean the defaults. The test-only checkpoint hook stays on an internal constructor, and the engine grants internal access to its TextMate test project.
  • Common and All wrap it exactly as before. Their public API, revisions and behavior are unchanged.
  • Package rules, as checked by the TextMate release evidence:
    • the lean integration still depends on no TextMateSharp, TextMateSharp.Grammars or Onigwrap;
    • the engine depends on the integration and TextMateSharp, and never on TextMateSharp.Grammars;
    • Common depends on the engine and TextMateSharp, and still never on TextMateSharp.Grammars;
    • All depends on the engine and TextMateSharp.Grammars.
  • The Common deployment cap (6 MiB per RID) now counts the engine DLL too, because a Common deployment ships it.

The one public TextMateSharp dependency

The PublicApi tests forbid third-party types in any shipping public signature. The engine is now the single exception: ForbiddenContractTypeTests allows TextMateSharp. for that assembly only. A new test, ThirdPartyExceptions_NameShippingAssembliesThatActuallyUseThem, fails if the exception stops being needed. The lean integration and both grammar packs still expose no TextMateSharp type. As a result, the engine package's version has to follow TextMateSharp's breaking changes. public-api.md says so, and the package description tells hosts to install a grammar pack instead.

Wiring the ninth package

  • Both solutions, the CI workflow's locked-restore and pack lists, the expected release package set and its TextMate scope, the managed-architecture map, and the TextMate release-evidence script (restore, pack, entries, dependencies, managed assets and the selected-RID payload).
  • The compliance tooling self-test pinned 8 package IDs and matched error text with "8" in three places. It now pins 9 and derives the rest from the expected set.
  • ShippingAssemblies, and the app's security-gate test, which lists the shipping projects inside the app's locked graph.
  • Lock files: the engine's own, plus the nine projects that reach it through a grammar pack. The changes are only the engine entry and its TextMateSharp dependency.
  • Docs: the package table and dependency graph in packaging-and-distribution.md, and public-api.md. The packaging table's Mermaid row no longer calls the MMIR scene contracts public, which follows from MarkdownRenderer structure step 2d: overload rules on, Mermaid and Math expose configuration only #112.

Decisions for review

  • Package name ...TextMate.Engine, as proposed. The lean pack keeps its name. The release-evidence script used to call the lean pack $enginePackage, so that variable is now $integrationPackage, to avoid two different "engines".
  • No size gate for the engine. It packs to 18 KB; the lean integration and Grammars.All have no gate either. Its bytes count toward the Common selected-RID cap above.
  • No notices file in the engine package. It embeds no third-party content; TextMateSharp arrives as a NuGet dependency carrying its own license.
  • Common keeps its direct TextMateSharp reference even though the engine brings TextMateSharp transitively, because CuratedRegistryOptions implements TextMateSharp's registry contract itself.

Verification

Check Result
MarkdownRenderer.slnx Release x64 0 warnings, 0 errors
Test-ProjectStructure.ps1 passes: 32 projects, 1,053 files; no ProjectStructureException in any project
MarkdownRenderer.Tests / GitHub.Tests / Svg.Resvg.Tests 1,408 / 3,043 / 808
Math / Mermaid / Html / TextMate / Conformance 80 / 259 / 10 / 70 / 9
PublicApi.Tests / Sample.Automation.Tests 19 / 4
JitHub.WinUI.Tests Debug 3,126 of 3,126
JitHub.WinUI Release x64 with the security gate passes; 84/84 ReleaseSecurity tests, including the engine in the app's locked graph. One warning: MSB3774, this machine has no VCLibs SDK
Invoke-TextMateReleaseEvidence.ps1 passes: contract tests, provenance, two reproducible packs, entries and dependency rules for all four packages, compliance, and package consumers for x86, x64 and ARM64
Common selected-RID payload, now including the engine DLL 5,399,040 / 5,392,384 / 5,353,472 bytes (x86 / x64 / ARM64), under the 6 MiB cap
NativeAOT project smokes, win-x64 all publish with 0 warnings and run; TextMate highlights through both Common and All
MarkdownRenderer package consumed by NativeAOT and trimmed single-file x86 and x64 run; ARM64 cross-published
Packed packages 9; size gates pass (936,971 bytes compressed, 2,301,952 managed); engine 18,454 bytes
Managed package architecture 8 managed assemblies across 9 packages, all AnyCPU
--locked-mode restore every project except JitHub.Web and JitHub.Web.Tests, whose locks don't match this machine's SDK (10.0.14 vs 10.0.11); unchanged here
Engineering and compliance script self-tests pass
resvg worker identity, x86/x64/arm64 verified

Not run: Sandbox UI cases, PixelTests and the external performance-gate subset. This change moves code between assemblies without changing rendering.

🤖 Generated with Claude Code

Xueyang-Song and others added 4 commits October 28, 2026 12:00
The sample app and the performance harness were the last projects that read
renderer internals through ProjectStructureException grants.

Sample: public API only.
- MarkdownTheme.ForcedContrastColors (MarkdownContrastColors) replaces the
  process-wide ThemeResolver.SystemThemeProviderOverride. Setting it raises
  the theme's Changed notification, so views restyle as for a Windows
  contrast switch.
- MarkdownRendererControl.RenderedContentSize and RenderedThemeVariant report
  what the view last displayed, which the sample's UI-test status and touch
  layout capture use as checks.
- The touch capture reads scroll position through the UI Automation scroll
  pattern.
- CodeBlockThemeVariant becomes MarkdownThemeVariant in Theming, shared by
  RenderedThemeVariant and CodeBlockHighlightRequest.ThemeVariant.

Performance harness: a white-box performance test.
- MRS0002 now allows grants only to the renderer's own projects at
  tests\<name>\<name>.csproj or perf\<name>\<name>.csproj, which never ship,
  instead of to any name ending in .Tests or .Benchmarks.
- PerformanceEventListener moves into PerformanceHarness.Core, which
  GitHub.Tests references instead of linking the harness's source file.
- The harness's measured code is unchanged, so results stay comparable with
  the existing baselines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ad rules, hide Mermaid and Math processors

Turn RS0026/RS0027 back into errors and fix what they find: one constructor
each for MarkdownVectorTextStyle, MarkdownStyleContext and MarkdownStyleSelector
with the role/ancestor qualifier as a trailing optional parameter, and explicit
MarkdownVectorScene overloads. The feature extension classes suppress the rules
at class level, and a new PublicApi test checks the property they rely on for
each receiver.

Mermaid and Math now expose only host configuration. The headless processors,
their results, diagnostics, scene formats and decoders become internal; Math
grants internal access to its tests and the benchmarks. The Mermaid and Math
NativeAOT smokes now render through UseMermaid/UseMathematics. EmbedVisibility
becomes internal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hrough an engine package

Move the TextMateSharp-backed grammar provider that Grammars.Common and
Grammars.All compiled from one linked source file into a new shipping package,
MarkdownRenderer.SyntaxHighlighting.TextMate.Engine, as the public
TextMateSharpGrammarProvider. Both packs reference it, and no file link or
ProjectStructureException remains.

The engine is the one package whose public API names TextMateSharp types; the
forbidden-contract test allows that for this assembly only and fails if the
exception stops being needed. Wire the ninth package into both solutions, CI
restore and pack lists, the release package set, the managed-architecture map,
the TextMate release evidence (dependency rules and the Common selected-RID
payload), the compliance self-tests, the app security gate test, lock files
and the packaging docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Xueyang-Song
Xueyang-Song changed the base branch from codex/markdown-renderer-api-surface to codex/markdown-renderer-1-0 October 31, 2026 01:50
…te-engine

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Xueyang-Song
Xueyang-Song merged commit 6043559 into codex/markdown-renderer-1-0 Oct 31, 2026
10 of 12 checks passed
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.

2 participants