fix: preserve CJK layout names in defineSlideMaster() titles - #1
Open
wwsinagogogo wants to merge 3 commits into
Open
fix: preserve CJK layout names in defineSlideMaster() titles#1wwsinagogogo wants to merge 3 commits into
wwsinagogogo wants to merge 3 commits into
Conversation
… helper
PptxGenJS rejects empty titles with "requires a `title` value", but the old toUpperSnakeCase stripped every non-ASCII character via /[^a-zA-Z0-9\s]/g, so a pure-Chinese layout name like "标题页" collapsed to "" and crashed defineSlideMaster(). Switch the character class to Unicode property escapes (\p{L}\p{N}\p{M}) and add a resolveTitle() helper so downstream generators (preview, skill, masters.js, agent docs) get a self-contained fallback to master.name when extract() is bypassed (e.g. unit-test fixtures). Final LAYOUT_FALLBACK sentinel guarantees PptxGenJS never sees an empty title.
Adds 9 unit tests covering pure-CJK, mixed ASCII+CJK, Japanese/Korean, fullwidth space (\u3000), symbol-only input, and non-string input (undefined/null/number).
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Two distinct layouts can normalize to the same title (e.g. whitespace-padded CJK variants), and PptxGenJS rejects the empty title that toUpperSnakeCase previously produced for symbol-only or whitespace-only names. Add a final pass over masterData that assigns LAYOUT_<n> to empty titles and appends _2, _3, ... suffixes to collisions, so every layout reaching the downstream generators has a unique non-empty title. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
preview.js and skill.js each computed titles via toUpperSnakeCase(master.name) directly, which would re-introduce the empty-title crash whenever they ran without extract()'s dedup pass (e.g. library consumers calling generatePreview or generateBrandSkill with hand-built masterData). Switch both to the resolveTitle() helper exported by the previous commit so they share the same master.title → toUpperSnakeCase(name) → LAYOUT_FALLBACK chain. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
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.
Problem
When a
.pptxtemplate's slide layouts use Chinese / Japanese / Korean names (e.g.标题页,目次,표지),pptx-masterscrashes with:Root cause
toUpperSnakeCase()stripped every non-ASCII character viareplace(/[^a-zA-Z0-9\s]/g, ''). CJK characters are letters, not punctuation, but the regex didn't know that — so标题页collapsed to""and was forwarded straight todefineSlideMaster({ title: '' }).A second issue: the function never produced unique titles, so two layouts whose names normalized to the same value silently overwrote each other.
Fix
toUpperSnakeCase()uses Unicode property escapes (\p{L}\p{N}\p{M}) so all-language letters / digits / combining marks are preserved. Fullwidth space\u3000is treated as a separator via the/uflag.extract()runs a final dedup pass: empty titles fall back toLAYOUT_<n>, collisions get_2,_3, … suffixes — every layout reaching downstream code has a unique non-empty title.resolveTitle()helper is exported fromsrc/generator/code.js. All four downstream generators (generateMastersCode,generateAgentInstructions,generatePreview,generateBrandSkill) route through it, so library callers passing hand-builtmasterData(e.g. tests) get a self-containedmaster.title → toUpperSnakeCase(name) → LAYOUT_FALLBACKchain.LAYOUT_FALLBACKis the last-resort sentinel guaranteeing PptxGenJS never sees an empty title.Verification
标题页now extracts totitle: '标题页'inmasters.jsand runs through PptxGenJS without error<p:cSld name="...">attribute stripped off a layout falls back toLAYOUT_2instead of crashingOut of scope
src/cli.jshas an unrelatedcreateRequirefallback sobun build --compileproduces a working standalone binary. That change is local and stays out of this PR.Commits
fix: preserve CJK characters in toUpperSnakeCase and add resolveTitle helper— core fix + unit testsfix: dedup master titles in extract with empty-title fallback— pipeline dedup passrefactor: route downstream generators through resolveTitle helper— wire preview.js / skill.js through the helper🤖 Generated with Sisyphus
Co-authored-by: Sisyphus clio-agent@sisyphuslabs.ai