Skip to main content 홈 크리에이터 guyoung boxagnts pptx-generator
pptx-generator "Compile Markdown into a valid Microsoft PowerPoint (.pptx) file using pure JavaScript. Pipeline: Markdown → AST → Slide IR → Layout IR → OOXML → ZIP. Images embedded from local files."
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/guyoung/boxagnts --skill pptx-generator명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... name pptx-generator description Compile Markdown into a valid Microsoft PowerPoint (.pptx) file using pure JavaScript. Pipeline: Markdown → AST → Slide IR → Layout IR → OOXML → ZIP. Images embedded from local files. when_to_use Use when generating PowerPoint (.pptx) files from Markdown input. tools jsexec, read, write, bash args [{"name":"output_path","description":"Absolute file path for the generated .pptx file","required":true},{"name":"markdown","description":"Markdown text input. Supports headings, lists, code, tables, blockquotes, inline formatting, links, images (local paths), and --- slide breaks","required":true},{"name":"show_slide_numbers","description":"When true, renders N / M page numbers at bottom-right","required":false}]
CODE SKILL — VERBATIM REQUIRED
This skill targets a formal specification (OOXML).
Adaptation is prohibited per C2-A Rule 3.
CRITICAL: Execution Constraints
The code below is the SOLE IMPLEMENTATION — it MUST NOT be replaced, simplified, or reimplemented.
Prohibited deviations:
Do NOT write your own crc32(), ZipBuilder, parseMarkdownAST(), buildSlideIR(), layoutSlide(), renderSlideXML()
Do NOT skip any OOXML file from the 13+ core file baseline
Do NOT use compression (method 8 / DEFLATE) — STORE mode only (method 0)
Do NOT skip scanAndAssignLinks() — hyperlinks MUST be registered as relationships
Do NOT use remote URLs for images — images MUST be local file paths
Correct Invocation Pattern
Copy the complete script from ## Runnable Entry Point below
Replace ONLY {{markdown}}, {{output_path}}, {{show_slide_numbers}} with actual values
Execute as a single jsexec call with NO modifications
Argument Details
Arg Type Required Default Description markdownstringyes — Markdown input for slide generation output_pathstringyes — Output .pptx file path show_slide_numbersbooleanno falseShow N / M page numbers
Runnable Entry Point (COMPLETE IIFE, DO NOT MODIFY)
(async function ( ) {
const fs = require ("fs" );
const pathModule = require ("path" );
function esc (s ) {
return String (s).replace (/&/g , '&' ).replace (/</g , '<' ).replace (/>/g , '>' ).replace (/"/g , '"' ).replace (/'/g , ''' );
}
let shapeId = 1 ;
let relId = 2 ;
let imageIndex = 1 ;
function nextShapeId ( ) { return shapeId++; }
function nextRelId ( ) { return 'rId' + relId++; }
function nextImageName (ext = 'png' ) { return ; }
= ( );
( i = ; i < ; i++) {
c = i;
( j = ; j < ; j++) {
c = (c & ) ? ( ^ (c >>> )) : (c >>> );
}
[i] = c;
}
( ) {
c = ;
( i = ; i < buf. ; i++) {
c = [(c ^ buf[i]) & ] ^ (c >>> );
}
(c ^ ) >>> ;
}
{
( ) {
. = [];
. = [];
. = ;
. = ;
}
( ) {
buf = content === ? . (content, ) : content;
crc = (buf);
nameBuf = . (path, );
localHeader = . ( );
localHeader. ( , );
localHeader. ( , );
localHeader. ( , );
localHeader. ( , );
localHeader. ( , );
localHeader. ( , );
localHeader. (crc, );
localHeader. (buf. , );
localHeader. (buf. , );
localHeader. (nameBuf. , );
localHeader. ( , );
. . (localHeader, nameBuf, buf);
cd = . ( );
cd. ( , );
cd. ( , );
cd. ( , );
cd. ( , );
cd. ( , );
cd. ( , );
cd. ( , );
cd. (crc, );
cd. (buf. , );
cd. (buf. , );
cd. (nameBuf. , );
cd. ( , );
cd. ( , );
cd. ( , );
cd. ( , );
cd. ( , );
cd. ( . , );
. . (cd, nameBuf);
. += localHeader. + nameBuf. + buf. ;
. ++;
}
( ) {
localBlock = . ( . );
centralBlock = . ( . );
cdSize = centralBlock. ;
cdOffset = . ;
n = . ;
eocd = . ( );
eocd. ( , );
eocd. ( , );
eocd. ( , );
eocd. (n, );
eocd. (n, );
eocd. (cdSize, );
eocd. (cdOffset, );
eocd. ( , );
. ([localBlock, centralBlock, eocd]);
}
}
( ) {
runs = [];
i = ;
(i < raw. ) {
(raw[i] === ) {
end = raw. ( , i + );
(end !== - ) {
runs. ({ : raw. (i + , end), : });
i = end + ;
;
}
}
(raw[i] === && raw[i + ] === ) {
end = raw. ( , i + );
(end === - ) {
runs. ({ : raw. (i, i + ) });
i += ;
;
}
inner = raw. (i + , end);
innerRuns = (inner);
( r innerRuns) {
r. = ;
runs. (r);
}
i = end + ;
;
}
(raw[i] === && raw[i + ] !== ) {
end = raw. ( , i + );
(end !== - ) {
inner = raw. (i + , end);
innerRuns = (inner);
( r innerRuns) {
r. = ;
runs. (r);
}
i = end + ;
;
}
}
(raw[i] === ) {
closeBracket = raw. ( , i + );
(closeBracket !== - ) {
closeParen = raw. ( , closeBracket + );
(closeParen !== - ) {
linkText = raw. (i + , closeBracket);
linkUrl = raw. (closeBracket + , closeParen);
innerRuns = (linkText);
( r innerRuns) {
r. = linkUrl;
runs. (r);
}
i = closeParen + ;
;
}
}
}
end = i + ;
(end < raw. && . (raw[end]) === - ) { end++; }
runs. ({ : raw. (i, end) });
i = end;
}
(runs. === ) { runs. ({ : raw }); }
runs;
}
( ) {
lines = md. ( );
doc = { : [] };
i = ;
(i < lines. ) {
line = lines[i]. ();
(line === ) { doc. . ({ : }); i++; ; }
(line. ( )) {
level = line. ( )[ ]. ;
doc. . ({ : , level, : line. ( , ) });
i++; ;
}
(line. ( )) {
lang = line. ( , ). ();
i++;
code = [];
(i < lines. && !lines[i]. ( )) { code. (lines[i]); i++; }
doc. . ({ : , lang, : code. ( ) });
i++; ;
}
(line. ( )) {
items = [];
(i < lines. && lines[i]. ( )) { items. (lines[i]. ( )); i++; }
doc. . ({ : , items }); ;
}
( . (line)) {
items = [];
(i < lines. && . (lines[i])) { items. (lines[i]. ( , )); i++; }
doc. . ({ : , items }); ;
}
(line. ( ) && lines[i + ]?. ( )) {
rows = [];
(i < lines. && lines[i]. ( )) {
cells = lines[i]. ( ). ( c. ()). ( );
isSeparator = cells. > && cells. ( . (c)) && rows. === ;
(!isSeparator) { rows. (cells); }
i++;
}
doc. . ({ : , rows }); ;
}
(line. ( )) {
items = [];
(i < lines. && lines[i]. ( )) { items. (lines[i]. ( )); i++; }
doc. . ({ : , items }); ;
}
(line. ( )) {
imgMatch = line. ( );
(imgMatch) {
block = { : , : imgMatch[ ] };
dimStr = imgMatch[ ];
(dimStr) {
(dimStr. ( )) {
block. = (dimStr);
} {
wMatch = dimStr. ( );
hMatch = dimStr. ( );
(wMatch) block. = (wMatch[ ]);
(hMatch) block. = (hMatch[ ]);
}
}
doc. . (block);
}
i++; ;
}
(line) {
runs = (line);
doc. . ({ : , : line, runs });
}
i++;
}
doc;
}
= ;
= ;
= ;
= ;
( ) {
w = ;
( ch text) {
code = ch. ( );
((code >= && code <= )
|| (code >= && code <= )
|| (code >= && code <= )
|| (code >= && code <= )
|| (code >= && code <= )
|| (code >= && code <= )
|| (code >= && code <= )) {
w += ;
} {
w += ;
}
}
w;
}
( ) {
(b. === || b. === ) {
h = ;
( item (b. || [])) { lines = . ( (item) / ) || ; h += lines * ; }
h;
}
(b. === ) {
h = ;
( item (b. || [])) { lines = . ( (item) / ) || ; h += lines * ; }
h;
}
(b. === ) { text = b. || ; lines = . ( (text) / ) || ; lines * ; }
(b. === ) { codeLines = (b. || ). ( ). ; . (codeLines * , ); }
(b. === ) { rows = (b. || []). || ; . (rows * , ); }
;
}
( ) {
h = (slide. ? : ) + (slide. ? : );
( img (slide. || [])) {
data = (img && img === ) ? img : { : img };
imgW = data. || (data. ? . ( * data. / ) : ( - * ));
imgH = data. || (data. && !data. ? . (imgW * / ) : . (imgW * / ));
h += imgH + ;
}
( b slide. ) { h += (b); }
h;
}
( ) {
slides = [];
current = ();
( ) { { : , : , : [], : [], : }; }
( ) {
( (current) <= ) ;
overflow = ();
overflow. = ;
h = (current. ? : ) + (current. ? : );
( img (current. || [])) {
data = (img && img === ) ? img : { : img };
imgW = data. || (data. ? . ( * data. / ) : ( - * ));
imgH = data. || . (imgW * / );
h += imgH + ;
}
keepBlocks = [], overflowBlocks = [];
( b current. ) {
bh = (b);
(h + bh <= ) { keepBlocks. (b); h += bh; }
{ overflowBlocks. (b); }
}
(overflowBlocks. > ) { current. = keepBlocks; overflow. = overflowBlocks; slides. (current); current = overflow; }
}
( b ast. ) {
(b. === && b. === ) {
(current. || current. . || current. . ) { (); slides. (current); }
current = (); current. = b. ; ;
}
(b. === ) { (); slides. (current); current = (); ; }
(b. === && b. === ) { current. = b. ; ; }
(b. === ) {
current. . ({ : b. , : b. , : b. , : b. , : b. });
;
}
current. . (b); ();
}
(); slides. (current); slides;
}
= / ;
( ) { { : col * , y, : span * , h }; }
( ) {
layout = [];
(slide. ) { layout. ({ : , : slide. , : ( , , , ) }); }
(slide. ) { layout. ({ : , : slide. , : ( , , , ) }); }
bodyStart = slide. ? (slide. ? : ) : (slide. ? : );
= - * ;
= . ( * / );
(slide. && slide. . > ) {
( img slide. ) {
imgData = (img && img === ) ? img : { : img };
imgW, imgH;
(imgData. && imgData. ) {
imgW = imgData. ;
imgH = imgData. ;
} (imgData. ) {
imgW = . ( * imgData. / );
imgH = . (imgW * / );
} (imgData. && !imgData. ) {
imgW = imgData. ;
imgH = . (imgW * / );
} {
imgW = ;
imgH = ;
}
imgX = . (( - imgW) / );
layout. ({ : , : imgData. , : { : imgX, : bodyStart, : imgW, : imgH } });
bodyStart += imgH + ;
}
}
footerH = slide. ? : ;
(footerH > ) {
layout. ({ : , : , : ( , , - footerH, ) });
}
y = bodyStart;
( b slide. ) {
(b. === ) { text = b. || ; lines = . ( (text) / ) || ; h = lines * ; layout. ({ : , : b. , : b. , : ( , , y, h) }); y += h; }
(b. === ) { ( item b. ) { lines = . ( (item) / ) || ; h = lines * ; layout. ({ : , : item, : ( , , y, h) }); y += h; } }
(b. === ) { ( idx = ; idx < b. . ; idx++) { lines = . ( (b. [idx]) / ) || ; h = lines * ; layout. ({ : , : b. [idx], : idx + , : ( , , y, h) }); y += h; } }
(b. === ) { ( item b. ) { lines = . ( (item) / ) || ; h = lines * ; layout. ({ : , : item, : ( , , y, h) }); y += h; } }
(b. === ) { codeLines = (b. || ). ( ). ; h = . (codeLines * , ); layout. ({ : , : b. , : ( , , y, h) }); y += h; }
(b. === ) { rows = (b. || []). || ; h = . (rows * , ); layout. ({ : , : b. , : ( , , y, h) }); y += h; }
}
layout;
}
( ) {
( block ast. ) {
(block. === ) {
filePath = block. ;
(!filePath) { block. = ; ; }
(filePath. ( )) {
. ( );
;
}
(filePath. ( ) || filePath. ( )) {
. ( );
block. = ; ;
}
{
resolvedPath = pathModule. (filePath);
fs. (resolvedPath);
ext = pathModule. (filePath). ();
block. = resolvedPath;
block. = ext. ( , ) || ;
} (e) {
. ( );
block. = ;
}
}
}
ast. = ast. . ( !(b. === && b. === ));
}
( ) {
buf = fs. (imgPath);
ext = imgExt || ;
name = (ext);
zip. ( , buf);
{ : name, : (), ext };
}
( ) {
;
}
( ) {
;
}
( ) {
;
}
( ) {
;
}
( ) {
;
}
( ) {
body = ;
( run runs) {
rPrAttrs = baseFontSize ? : ;
rPrChildren = ;
needsClose = ;
(run. ) rPrAttrs += ;
(run. ) rPrAttrs += ;
(run. ) { rPrChildren += ; needsClose = ; }
(run. ) {
linkRId = run. || ;
rPrAttrs += ;
rPrChildren += ;
rPrChildren += ;
needsClose = ;
}
rPrOpen = needsClose ? : ;
rPrClose = needsClose ? : ;
runBody = ;
body += ;
}
body;
}
( ) {
slide. = {};
( item layout) {
runs = item. || (item. ? (item. ) : []);
( run runs) { (run. && !slide. [run. ]) { slide. [run. ] = (); } }
}
( item layout) { (item. ) { ( run item. ) { (run. ) run. = slide. [run. ]; } } }
}
( ) {
shapes = ;
( item layout) {
(item. === || item. === || item. === || item. === ) {
r = item. ;
fontSize = item. === ? : ;
runs = item. || (item. );
isBullet = item. === ;
bulletChar = isBullet ? : ;
runsXml = (runs, fontSize);
shapes += ;
}
(item. === ) {
r = item. ;
shapes += ;
}
(item. === ) {
r = item. ;
runsXml = ( (item. ), );
shapes += ;
}
(item. === ) {
r = item. ;
runs = (item. );
runsXml = (runs, );
shapes += ;
}
(item. === ) {
r = item. ;
lines = item. . ( );
paragraphs = ;
( line lines) {
paragraphs += ;
}
shapes += ;
}
(item. === ) {
r = item. ;
rows = item. ;
numCols = rows[ ] ? rows[ ]. : ;
colWidth = . (r. / numCols);
rowHeight = . (r. / rows. );
gridCols = ;
( c = ; c < numCols; c++) { gridCols += ; }
tableRows = ;
( ri = ; ri < rows. ; ri++) {
cells = ;
isHeader = ri === ;
( ci = ; ci < (rows[ri] ? rows[ri]. : ); ci++) {
(isHeader) {
cells += ;
} {
cells += ;
}
}
tableRows += ;
}
shapes += ;
}
(item. === && item. ) {
r = item. ;
shapes += ;
}
}
;
}
( ) {
;
}
( ) {
slideList = ;
( i = ; i < slideCount; i++) { slideList += ; }
;
}
( ) {
rels = ;
( i = ; i < slideCount; i++) { rels += ; }
presRId = slideCount + ;
rels += ;
rels += ;
rels += ;
rels += ;
;
}
( ) {
rels = ;
(slide. ) { ( img slide. ) { rels += ; } }
(slide. ) { ( [url, rId] . (slide. )) { rels += ; } }
;
}
( ) {
defaults = ;
defaults += ;
(imageExts && imageExts. > ) {
( ext imageExts) {
defaults += ;
}
}
overrides = ;
overrides += ;
overrides += ;
overrides += ;
overrides += ;
overrides += ;
overrides += ;
overrides += ;
( i = ; i < slideCount; i++) { overrides += ; }
overrides += ;
overrides += ;
;
}
( ) { ; }
( ) {
;
}
( ) { ; }
( ) {
now = (). (). ( , );
;
}
( ) {
;
}
( ) {
(!options) options = {};
shapeId = ; relId = ; imageIndex = ;
zip = ();
ast = (md);
(ast);
slides = (ast);
totalSlides = slides. ;
imageExts = ();
( i = ; i < slides. ; i++) {
slide = slides[i];
slide. = [];
slide. = !!options. ;
slide. = i + ;
slide. = totalSlides;
(slide. && slide. . > ) {
( img slide. ) {
imgData = (img && img === ) ? img. : img;
(imgData && imgData === && !imgData. ( )) {
ext = (img && img. ) || ;
imgInfo = (zip, imgData, ext);
slide. . (imgInfo);
(imgInfo. ) imageExts. (imgInfo. );
}
}
}
}
zip. ( , ());
zip. ( , (slides. ));
zip. ( , (slides. ));
zip. ( , ());
zip. ( , ());
zip. ( , ());
zip. ( , ());
zip. ( , ());
zip. ( , ());
zip. ( , ());
zip. ( , ());
zip. ( , ());
zip. ( , (slides. ));
( i = ; i < slides. ; i++) {
slide = slides[i];
layout = (slide);
imgIdx = ;
( item layout) { (item. === && slide. [imgIdx]) { item. = slide. [imgIdx]. ; imgIdx++; } }
(slide, layout);
zip. ( , (slide, layout));
zip. ( , (slide));
}
zip. ( , (slides. , imageExts));
fs. (output_path, zip. ());
{ : output_path, : slides. };
}
md = . ( , ) || ;
out = . ( , ) || ;
showNums = ( . ( , ) || ) === ;
result = (md, out, { : showNums });
. ( );
. ( );
})();
Usage Notes
Markdown → Slide Mapping Rules
Markdown Element Slide Behavior # H1Starts a new slide (title slide) ## H2Slide subtitle (below the H1 title) ###–###### H3–H6Regular text on current slide (bold format only, no special style) --- (horizontal rule)Explicit slide break (force new slide)- bullet listUnordered bullet points (●) 1. numbered listAuto-numbered (1. 2. 3. …) ```code```Code block — gray background (#F5F5F5), dark text, 12pt | table |Data table — blue header row (#4472C4), white text > blockquoteQuoted text — blue left border (#4472C4), 16pt [text](url)Hyperlink — blue underlined, registered as OOXML relationship Image — centered, auto-sized, embedded as raw binary (direct from file) Plain paragraph Body text — 18pt, full width
Slide Layout Dimensions
Slide size : 9144000 × 6858000 EMU (≈ 10″ × 7.5″), 4:3 aspect ratio
12-column grid : each column = SLIDE_W / 12
Title : grid(0, 12, 0, 1000000) — full width, 1M EMU height
Subtitle : grid(0, 12, 1000000, 800000) — centered below title
Body : starts at y=1800000 (if both title+subtitle), 1000000 (if only title), or 0 (no heading)
Image Handling
Direct binary pass-through : Images are read from disk as raw bytes and written straight into the ZIP — no intermediate base64 encoding. This avoids ~33% bloat and significant performance penalties.
Only local file paths supported (no remote URLs)
Supported formats: PNG, JPG, GIF, BMP, WebP
SVG is NOT supported — convert to PNG first (e.g. via plotter with output_format: "png")
Dimensions read from file headers; auto-scaled to fit slide width (max fallback: 600px wide)
Image bytes are read only once, at the moment of ZIP assembly (addImageToZip)
Auto-Overflow Splitting
When content exceeds the slide height, blocks are split into a new overflow slide (no title).
OOXML File Baseline (per presentation)
File Purpose _rels/.relsRoot relationships ppt/presentation.xmlSlide list + slide size + default text style ppt/_rels/presentation.xml.relsPresentation-level relationships ppt/presProps.xmlPresentation properties (extLst) ppt/viewProps.xmlView settings (guide, grid, zoom) ppt/tableStyles.xmlTable style defaults ppt/slideMasters/slideMaster1.xmlMaster slide (txStyles) ppt/slideMasters/_rels/slideMaster1.xml.relsMaster relationships ppt/slideLayouts/slideLayout1.xmlLayout (empty spTree) ppt/slideLayouts/_rels/slideLayout1.xml.relsLayout relationships ppt/theme/theme1.xmlColor/font/fill scheme docProps/core.xmlCreator, revision, modified date docProps/app.xmlSlide count, app metadata ppt/slides/slideN.xmlPer-slide shapes ppt/slides/_rels/slideN.xml.relsPer-slide relationships (links, images) ppt/media/imageN.extEmbedded images (if any, one per image) [Content_Types].xmlMIME type declarations for all parts
Common Pitfalls
⚠️ Image performance : ZipBuilder uses delayed-concat optimization — individual file headers and binary data are stored as separate chunk references, with only 3 Buffer.concat calls during final assembly (vs O(2n+3) previously). Combined with direct binary pass-through (no base64 bloat), image-heavy presentations perform efficiently even in Wasm environments.
⚠️ SVG images cannot be embedded : SVG files are not supported by the OOXML picture shape used in PPTX. Always convert SVGs to PNG before referencing them in Markdown. Use the plotter tool with output_format: "png" to render charts as PNG.
⚠️ Template literal backtick escaping : The entry point wraps markdown in a JavaScript template literal:
const md = `{{markdown}}` .replace (...);
If your markdown contains backticks (\``) — from code blocks or inline code — they will prematurely terminate the template literal, causing a syntax error. **Workaround**: Escape all backticks in the markdown with `(backslash-backtick). Similarly,${must be escaped as${`.
⚠️ No remote image URLs : resolveImages() explicitly skips URLs starting with http:// or https://. All images must be local files accessible via fs.readFileSync(). If an image cannot be read, it is silently dropped from the AST.
⚠️ Hyperlinks require scanAndAssignLinks() : The pipeline must call scanAndAssignLinks() before rendering each slide. Without it, [text](url) syntax will render as plain text (no hyperlink relationship). The Runnable Entry Point handles this automatically.
⚠️ STORE mode only : The ZipBuilder uses method 0 (no compression). Using DEFLATE (method 8) would produce a technically valid ZIP but may cause issues with some OOXML validators that expect uncompressed entries.
⚠️ Single master + single layout : All slides share one slide master and one slide layout. There is no concept of "different slide layouts" or "master slides per section."
⚠️ Schema-constrained XML templates — NEVER simplify : The theme() slideMaster() presProps() viewProps() presentation() functions generate OOXML Schema-constrained XML. Removing or simplifying ANY element (even if it appears "boilerplate") will cause validation failures.
C3 Verification
Check Item Constraint Common Omission Method ZIP Integrity EOCD + CD signatures valid Corrupted ZIP unzip -t <file>ppt/viewProps.xmlrestoredLeft/restoredTop/cSldViewPrSelf-closing tags → "file corrupted" Verify minOccurs=1 elements ppt/presProps.xmlextLst with 3 extEmpty presentationPr Count ext children ppt/slideMasters/slideMaster1.xmltxStyles (titleStyle+bodyStyle+otherStyle)Missing styles Verify 3 style sections ppt/presentation.xmldefaultTextStyle + sldSzWrong dimensions Verify 4:3 ppt/theme/theme1.xmlfmtScheme ≥3 children per listSchema violation Count fillStyleLst/lnStyleLst children Slides One slideN.xml per slide Missing slides Check file count Hyperlinks scanAndAssignLinks() runLinks broken Check slide rels Images ppt/media/ present if images used; binary CRC intactMissing or corrupted images Cross-check file count + CRC of each media entry Compression Method 0 (STORE) only Accidental DEFLATE Check ZIP method theme1.xml Schema folHlink, cs×2, effectStyleLstMissing schema-required elements Count: 1 folHlink + 2 cs + 1 effectStyleLst
`image${imageIndex++} .${ext} `
const
CRCT
new
Uint32Array
256
for
let
0
256
let
for
let
0
8
1
0xEDB88320
1
1
CRCT
function
crc32
buf
let
0xFFFFFFFF
for
let
0
length
CRCT
0xFF
8
return
0xFFFFFFFF
0
class
ZipBuilder
constructor
this
localChunks
this
centralChunks
this
offset
0
this
count
0
add
path, content
const
typeof
'string'
Buffer
from
'utf-8'
const
crc32
const
Buffer
from
'utf-8'
const
Buffer
alloc
30
writeUInt32LE
0x04034b50
0
writeUInt16LE
20
4
writeUInt16LE
0
6
writeUInt16LE
0
8
writeUInt16LE
0
10
writeUInt16LE
0
12
writeUInt32LE
14
writeUInt32LE
length
18
writeUInt32LE
length
22
writeUInt16LE
length
26
writeUInt16LE
0
28
this
localChunks
push
const
Buffer
alloc
46
writeUInt32LE
0x02014b50
0
writeUInt16LE
20
4
writeUInt16LE
20
6
writeUInt16LE
0
8
writeUInt16LE
0
10
writeUInt16LE
0
12
writeUInt16LE
0
14
writeUInt32LE
16
writeUInt32LE
length
20
writeUInt32LE
length
24
writeUInt16LE
length
28
writeUInt16LE
0
30
writeUInt16LE
0
32
writeUInt16LE
0
34
writeUInt16LE
0
36
writeUInt32LE
0
38
writeUInt32LE
this
offset
42
this
centralChunks
push
this
offset
length
length
length
this
count
build
const
Buffer
concat
this
localChunks
const
Buffer
concat
this
centralChunks
const
length
const
this
offset
const
this
count
const
Buffer
alloc
22
writeUInt32LE
0x06054b50
0
writeUInt16LE
0
4
writeUInt16LE
0
6
writeUInt16LE
8
writeUInt16LE
10
writeUInt32LE
12
writeUInt32LE
16
writeUInt16LE
0
20
return
Buffer
concat
function
parseInlineRuns
raw
const
let
0
while
length
if
'`'
const
indexOf
'`'
1
if
1
push
text
slice
1
mono
true
1
continue
if
'*'
1
'*'
let
indexOf
'**'
2
if
1
push
text
slice
2
2
continue
const
slice
2
const
parseInlineRuns
for
const
of
bold
true
push
2
continue
if
'*'
1
'*'
const
indexOf
'*'
1
if
1
const
slice
1
const
parseInlineRuns
for
const
of
italic
true
push
1
continue
if
'['
const
indexOf
']('
1
if
1
const
indexOf
')'
2
if
1
const
slice
1
const
slice
2
const
parseInlineRuns
for
const
of
link
push
1
continue
let
1
while
length
'`*['
indexOf
1
push
text
slice
if
length
0
push
text
return
function
parseMarkdownAST
md
const
split
'\n'
const
blocks
let
0
while
length
let
trim
if
'---'
blocks
push
type
'slide_break'
continue
if
startsWith
'#'
const
match
/^#+/
0
length
blocks
push
type
'heading'
text
replace
/^#+\s*/
''
continue
if
startsWith
'```'
const
replace
'```'
''
trim
const
while
length
startsWith
'```'
push
blocks
push
type
'code'
code
join
'\n'
continue
if
startsWith
'- '
const
while
length
startsWith
'- '
push
slice
2
blocks
push
type
'list'
continue
if
/^\d+\.\s/
test
const
while
length
/^\d+\.\s/
test
push
replace
/^\d+\.\s+/
''
blocks
push
type
'ordered_list'
continue
if
includes
'|'
1
includes
'|'
const
while
length
includes
'|'
const
split
'|'
map
c =>
trim
filter
Boolean
const
length
0
every
c =>
/^:?-+:?$/
test
length
1
if
push
blocks
push
type
'table'
continue
if
startsWith
'> '
const
while
length
startsWith
'> '
push
slice
2
blocks
push
type
'blockquote'
continue
if
startsWith
'!['
const
match
/!\[([^\]]*)\]\((.+?)\)(?:\{([^}]+)\})?/
if
const
type
'image'
data
2
const
3
if
if
includes
'%'
widthPct
parseFloat
else
const
match
/w=(\d+)/
const
match
/h=(\d+)/
if
width
parseInt
1
if
height
parseInt
1
blocks
push
continue
if
const
parseInlineRuns
blocks
push
type
'paragraph'
text
return
const
SLIDE_W
9144000
const
SLIDE_H
6858000
const
CHARS_PER_LINE
80
const
LINE_HEIGHT
300000
function
cjkWeightedLen
text
let
0
for
const
of
const
charCodeAt
0
if
0x4E00
0x9FFF
0x3400
0x4DBF
0xF900
0xFAFF
0x3040
0x30FF
0xAC00
0xD7AF
0xFF01
0xFF60
0xFFE0
0xFFE6
2
else
1
return
function
estimateBlockHeight
b
if
type
'list'
type
'ordered_list'
let
0
for
const
of
items
const
Math
ceil
cjkWeightedLen
CHARS_PER_LINE
1
LINE_HEIGHT
return
if
type
'blockquote'
let
0
for
const
of
items
const
Math
ceil
cjkWeightedLen
CHARS_PER_LINE
1
LINE_HEIGHT
return
if
type
'paragraph'
const
text
''
const
Math
ceil
cjkWeightedLen
CHARS_PER_LINE
1
return
LINE_HEIGHT
if
type
'code'
const
code
''
split
'\n'
length
return
Math
max
250000
1500000
if
type
'table'
const
rows
length
1
return
Math
max
400000
2000000
return
800000
function
estimateSlideH
slide
let
title
1000000
0
subtitle
800000
0
for
const
of
images
const
typeof
'object'
data
const
width
widthPct
Math
floor
SLIDE_W
widthPct
100
SLIDE_W
2
COL
const
height
width
height
Math
floor
9
16
Math
floor
9
16
100000
for
const
of
blocks
estimateBlockHeight
return
function
buildSlideIR
ast
const
let
createSlide
function
createSlide
return
title
''
subtitle
''
blocks
images
_overflow
false
function
splitOverflow
if
estimateSlideH
SLIDE_H
return
const
createSlide
_overflow
true
let
title
1000000
0
subtitle
800000
0
for
const
of
images
const
typeof
'object'
data
const
width
widthPct
Math
floor
SLIDE_W
widthPct
100
SLIDE_W
2
COL
const
height
Math
floor
9
16
100000
const
for
const
of
blocks
const
estimateBlockHeight
if
SLIDE_H
push
else
push
if
length
0
blocks
blocks
push
for
const
of
blocks
if
type
'heading'
level
1
if
title
blocks
length
images
length
splitOverflow
push
createSlide
title
text
continue
if
type
'slide_break'
splitOverflow
push
createSlide
continue
if
type
'heading'
level
2
subtitle
text
continue
if
type
'image'
images
push
data
data
_ext
_ext
width
width
height
height
widthPct
widthPct
continue
blocks
push
splitOverflow
splitOverflow
push
return
const
COL
SLIDE_W
12
function
grid
col, span, y, h
return
x
COL
w
COL
function
layoutSlide
slide
const
if
title
push
type
'title'
text
title
rect
grid
0
12
0
1000000
if
subtitle
push
type
'subtitle'
text
subtitle
rect
grid
0
12
1000000
800000
let
title
subtitle
1800000
1000000
subtitle
1800000
0
const
DEFAULT_IMG_W
SLIDE_W
2
COL
const
DEFAULT_IMG_H
Math
floor
DEFAULT_IMG_W
9
16
if
images
images
length
0
for
const
of
images
const
typeof
'object'
data
let
if
width
height
width
height
else
if
widthPct
Math
floor
SLIDE_W
widthPct
100
Math
floor
9
16
else
if
width
height
width
Math
floor
9
16
else
DEFAULT_IMG_W
DEFAULT_IMG_H
const
Math
floor
SLIDE_W
2
push
type
'image'
data
data
rect
x
y
w
h
100000
let
_showSlideNumber
600000
0
if
0
push
type
'page_number'
text
`${slide._pageNumber} / ${slide._totalPages} `
rect
grid
9
3
SLIDE_H
400000
let
for
const
of
blocks
if
type
'paragraph'
const
text
''
const
Math
ceil
cjkWeightedLen
CHARS_PER_LINE
1
const
LINE_HEIGHT
push
type
'text'
text
text
runs
runs
rect
grid
0
12
if
type
'list'
for
const
of
items
const
Math
ceil
cjkWeightedLen
CHARS_PER_LINE
1
const
LINE_HEIGHT
push
type
'bullet'
text
rect
grid
1
11
if
type
'ordered_list'
for
let
0
items
length
const
Math
ceil
cjkWeightedLen
items
CHARS_PER_LINE
1
const
LINE_HEIGHT
push
type
'ordered_bullet'
text
items
number
1
rect
grid
1
11
if
type
'blockquote'
for
const
of
items
const
Math
ceil
cjkWeightedLen
CHARS_PER_LINE
1
const
LINE_HEIGHT
push
type
'blockquote'
text
rect
grid
1
11
if
type
'code'
const
code
''
split
'\n'
length
const
Math
max
250000
1500000
push
type
'code'
text
code
rect
grid
0
12
if
type
'table'
const
rows
length
1
const
Math
max
400000
2000000
push
type
'table'
rows
rows
rect
grid
0
12
return
function
resolveImages
ast
for
const
of
blocks
if
type
'image'
const
data
if
data
null
continue
if
startsWith
'data:'
console
warn
'WARNING: data URI image. Use direct file paths for better performance (avoid ~33% base64 bloat).'
continue
if
startsWith
'http://'
startsWith
'https://'
console
warn
`WARNING: Image "${filePath} " is a remote URL. Skipping.`
data
null
continue
try
const
resolve
accessSync
const
extname
toLowerCase
data
_ext
replace
'.'
''
'png'
catch
console
warn
`WARNING: Cannot access "${filePath} ": ${e.message} . Skipping.`
data
null
blocks
blocks
filter
b =>
type
'image'
data
null
function
addImageToZip
zip, imgPath, imgExt
const
readFileSync
const
'png'
const
nextImageName
add
`ppt/media/${name} `
return
fileName
rId
nextRelId
function
slideMaster
return
`<?xml version="1.0" encoding="UTF-8"?>
<p:sldMaster xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<p:cSld>
<p:bg>
<p:bgRef idx="1001">
<a:schemeClr val="bg1"/>
</p:bgRef>
</p:bg>
<p:spTree>
<p:nvGrpSpPr>
<p:cNvPr id="1" name=""/>
<p:cNvGrpSpPr/>
<p:nvPr/>
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="0" cy="0"/>
<a:chOff x="0" y="0"/>
<a:chExt cx="0" cy="0"/>
</a:xfrm>
</p:grpSpPr>
</p:spTree>
</p:cSld>
<p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/>
<p:sldLayoutIdLst><p:sldLayoutId id="2147483649" r:id="rId1"/></p:sldLayoutIdLst>
<p:txStyles>
<p:titleStyle>
<a:lvl1pPr algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPct val="0"/></a:spcBef>
<a:buNone/>
<a:defRPr sz="4400" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mj-lt"/>
<a:ea typeface="+mj-ea"/>
<a:cs typeface="+mj-cs"/>
</a:defRPr>
</a:lvl1pPr>
</p:titleStyle>
<p:bodyStyle>
<a:lvl1pPr marL="228600" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPts val="1000"/></a:spcBef>
<a:buFont typeface="Arial" panose="020B0604020202020204" pitchFamily="34" charset="0"/>
<a:buChar char="•"/>
<a:defRPr sz="2800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl1pPr>
<a:lvl2pPr marL="685800" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPts val="500"/></a:spcBef>
<a:buFont typeface="Arial" panose="020B0604020202020204" pitchFamily="34" charset="0"/>
<a:buChar char="•"/>
<a:defRPr sz="2400" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl2pPr>
<a:lvl3pPr marL="1143000" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPts val="500"/></a:spcBef>
<a:buFont typeface="Arial" panose="020B0604020202020204" pitchFamily="34" charset="0"/>
<a:buChar char="•"/>
<a:defRPr sz="2000" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl3pPr>
<a:lvl4pPr marL="1600200" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPts val="500"/></a:spcBef>
<a:buFont typeface="Arial" panose="020B0604020202020204" pitchFamily="34" charset="0"/>
<a:buChar char="•"/>
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl4pPr>
<a:lvl5pPr marL="2057400" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPts val="500"/></a:spcBef>
<a:buFont typeface="Arial" panose="020B0604020202020204" pitchFamily="34" charset="0"/>
<a:buChar char="•"/>
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl5pPr>
<a:lvl6pPr marL="2514600" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPts val="500"/></a:spcBef>
<a:buFont typeface="Arial" panose="020B0604020202020204" pitchFamily="34" charset="0"/>
<a:buChar char="•"/>
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl6pPr>
<a:lvl7pPr marL="2971800" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPts val="500"/></a:spcBef>
<a:buFont typeface="Arial" panose="020B0604020202020204" pitchFamily="34" charset="0"/>
<a:buChar char="•"/>
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl7pPr>
<a:lvl8pPr marL="3429000" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPts val="500"/></a:spcBef>
<a:buFont typeface="Arial" panose="020B0604020202020204" pitchFamily="34" charset="0"/>
<a:buChar char="•"/>
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl8pPr>
<a:lvl9pPr marL="3886200" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:lnSpc><a:spcPct val="90000"/></a:lnSpc>
<a:spcBef><a:spcPts val="500"/></a:spcBef>
<a:buFont typeface="Arial" panose="020B0604020202020204" pitchFamily="34" charset="0"/>
<a:buChar char="•"/>
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl9pPr>
</p:bodyStyle>
<p:otherStyle>
<a:defPPr>
<a:defRPr lang="en-US"/>
</a:defPPr>
<a:lvl1pPr marL="0" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl1pPr>
<a:lvl2pPr marL="457200" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl2pPr>
<a:lvl3pPr marL="914400" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl3pPr>
<a:lvl4pPr marL="1371600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl4pPr>
<a:lvl5pPr marL="1828800" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl5pPr>
<a:lvl6pPr marL="2286000" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl6pPr>
<a:lvl7pPr marL="2743200" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl7pPr>
<a:lvl8pPr marL="3200400" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl8pPr>
<a:lvl9pPr marL="3657600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl9pPr>
</p:otherStyle>
</p:txStyles>
</p:sldMaster>`
function
slideMasterRels
return
`<?xml version="1.0" encoding="UTF-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="../theme/theme1.xml"/>
</Relationships>`
function
slideLayout
return
`<?xml version="1.0" encoding="UTF-8"?>
<p:sldLayout xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<p:cSld name="Default">
<p:spTree>
<p:nvGrpSpPr>
<p:cNvPr id="1" name=""/>
<p:cNvGrpSpPr/>
<p:nvPr/>
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="0" cy="0"/>
<a:chOff x="0" y="0"/>
<a:chExt cx="0" cy="0"/>
</a:xfrm>
</p:grpSpPr>
</p:spTree>
</p:cSld>
<p:clrMapOvr>
<a:masterClrMapping/>
</p:clrMapOvr>
</p:sldLayout>`
function
slideLayoutRels
return
`<?xml version="1.0" encoding="UTF-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="../slideMasters/slideMaster1.xml"/>
</Relationships>`
function
theme
return
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">
<a:themeElements>
<a:clrScheme name="Office">
<a:dk1><a:srgbClr val="000000"/></a:dk1>
<a:lt1><a:srgbClr val="FFFFFF"/></a:lt1>
<a:dk2><a:srgbClr val="44546A"/></a:dk2>
<a:lt2><a:srgbClr val="E7E6E6"/></a:lt2>
<a:accent1><a:srgbClr val="4472C4"/></a:accent1>
<a:accent2><a:srgbClr val="ED7D31"/></a:accent2>
<a:accent3><a:srgbClr val="A5A5A5"/></a:accent3>
<a:accent4><a:srgbClr val="FFC000"/></a:accent4>
<a:accent5><a:srgbClr val="5B9BD5"/></a:accent5>
<a:accent6><a:srgbClr val="70AD47"/></a:accent6>
<a:hlink><a:srgbClr val="0563C1"/></a:hlink>
<a:folHlink><a:srgbClr val="954F72"/></a:folHlink>
</a:clrScheme>
<a:fontScheme name="Office">
<a:majorFont><a:latin typeface="Calibri Light"/><a:ea typeface="Microsoft YaHei Light"/><a:cs typeface="Calibri Light"/></a:majorFont>
<a:minorFont><a:latin typeface="Calibri"/><a:ea typeface="Microsoft YaHei"/><a:cs typeface="Calibri"/></a:minorFont>
</a:fontScheme>
<a:fmtScheme name="Office">
<a:fillStyleLst>
<a:solidFill><a:schemeClr val="phClr"/></a:solidFill>
<a:gradFill rotWithShape="1">
<a:gsLst>
<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="50000"/><a:satMod val="300000"/></a:schemeClr></a:gs>
<a:gs pos="35000"><a:schemeClr val="phClr"><a:tint val="37000"/><a:satMod val="300000"/></a:schemeClr></a:gs>
<a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="15000"/><a:satMod val="350000"/></a:schemeClr></a:gs>
</a:gsLst>
<a:lin ang="16200000" scaled="1"/>
</a:gradFill>
<a:gradFill rotWithShape="1">
<a:gsLst>
<a:gs pos="0"><a:schemeClr val="phClr"><a:shade val="51000"/><a:satMod val="130000"/></a:schemeClr></a:gs>
<a:gs pos="80000"><a:schemeClr val="phClr"><a:shade val="93000"/><a:satMod val="130000"/></a:schemeClr></a:gs>
<a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="94000"/><a:satMod val="135000"/></a:schemeClr></a:gs>
</a:gsLst>
<a:lin ang="16200000" scaled="0"/>
</a:gradFill>
</a:fillStyleLst>
<a:lnStyleLst>
<a:ln w="9525" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"><a:shade val="95000"/><a:satMod val="105000"/></a:schemeClr></a:solidFill><a:prstDash val="solid"/></a:ln>
<a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln>
<a:ln w="38100" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln>
</a:lnStyleLst>
<a:effectStyleLst>
<a:effectStyle><a:effectLst/></a:effectStyle>
<a:effectStyle><a:effectLst/></a:effectStyle>
<a:effectStyle><a:effectLst/></a:effectStyle>
</a:effectStyleLst>
<a:bgFillStyleLst>
<a:solidFill><a:schemeClr val="phClr"/></a:solidFill>
<a:gradFill rotWithShape="1">
<a:gsLst>
<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="40000"/><a:satMod val="350000"/></a:schemeClr></a:gs>
<a:gs pos="40000"><a:schemeClr val="phClr"><a:tint val="45000"/><a:satMod val="350000"/><a:shade val="99000"/></a:schemeClr></a:gs>
<a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="20000"/><a:satMod val="255000"/></a:schemeClr></a:gs>
</a:gsLst>
<a:path path="circle"><a:fillToRect l="50000" t="-80000" r="50000" b="180000"/></a:path>
</a:gradFill>
<a:gradFill rotWithShape="1">
<a:gsLst>
<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="80000"/><a:satMod val="300000"/></a:schemeClr></a:gs>
<a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="30000"/><a:satMod val="200000"/></a:schemeClr></a:gs>
</a:gsLst>
<a:path path="circle"><a:fillToRect l="50000" t="50000" r="50000" b="50000"/></a:path>
</a:gradFill>
</a:bgFillStyleLst>
</a:fmtScheme>
</a:themeElements>
<a:objectDefaults/>
<a:extraClrSchemeLst/>
</a:theme>`
function
renderRuns
runs, baseFontSize
let
''
for
const
of
let
` sz="${baseFontSize} "`
''
let
''
let
false
if
bold
' b="1"'
if
italic
' i="1"'
if
mono
`<a:solidFill><a:srgbClr val="C7254E"/></a:solidFill><a:latin typeface="Consolas"/>`
true
if
link
const
_linkRId
''
' u="sng"'
`<a:solidFill><a:srgbClr val="0563C1"/></a:solidFill><a:uLn><a:solidFill><a:srgbClr val="0563C1"/></a:solidFill></a:uLn><a:latin typeface="Calibri"/>`
`<a:hlinkClick r:id="${linkRId} " tooltip="${esc(run.link)} "/>`
true
const
`<a:rPr${rPrAttrs} >${rPrChildren} `
`<a:rPr${rPrAttrs} />`
const
`</a:rPr>`
''
const
`<a:t>${esc(run.text)} </a:t>`
`<a:r>${rPrOpen} ${rPrClose} ${runBody} </a:r>`
return
function
scanAndAssignLinks
slide, layout
_linkMap
for
const
of
const
runs
text
parseInlineRuns
text
for
const
of
if
link
_linkMap
link
_linkMap
link
nextRelId
for
const
of
if
runs
for
const
of
runs
if
link
_linkRId
_linkMap
link
function
renderSlideXML
slide, layout
let
''
for
const
of
if
type
'title'
type
'subtitle'
type
'text'
type
'bullet'
const
rect
const
type
'title'
3600
1800
const
runs
parseInlineRuns
text
const
type
'bullet'
const
`<a:buChar char="\u2022"/>`
''
const
renderRuns
`
<p:sp>
<p:nvSpPr>
<p:cNvPr id="${nextShapeId()} " name="${item.type} "/>
<p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
<p:nvPr/>
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="${r.x} " y="${r.y} "/>
<a:ext cx="${r.w} " cy="${r.h} "/>
</a:xfrm>
</p:spPr>
<p:txBody>
<a:bodyPr/>
<a:lstStyle/>
<a:p><a:pPr>${bulletChar} </a:pPr>${runsXml} </a:p>
</p:txBody>
</p:sp>`
if
type
'page_number'
const
rect
`
<p:sp>
<p:nvSpPr>
<p:cNvPr id="${nextShapeId()} " name="pageNumber"/>
<p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
<p:nvPr/>
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="${r.x} " y="${r.y} "/>
<a:ext cx="${r.w} " cy="${r.h} "/>
</a:xfrm>
</p:spPr>
<p:txBody>
<a:bodyPr/>
<a:lstStyle/>
<a:p><a:pPr algn="r"/><a:r><a:rPr sz="1200"><a:solidFill><a:srgbClr val="888888"/></a:solidFill></a:rPr><a:t>${esc(item.text)} </a:t></a:r></a:p>
</p:txBody>
</p:sp>`
if
type
'ordered_bullet'
const
rect
const
renderRuns
parseInlineRuns
text
1800
`
<p:sp>
<p:nvSpPr>
<p:cNvPr id="${nextShapeId()} " name="ordered"/>
<p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
<p:nvPr/>
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="${r.x} " y="${r.y} "/>
<a:ext cx="${r.w} " cy="${r.h} "/>
</a:xfrm>
</p:spPr>
<p:txBody>
<a:bodyPr/>
<a:lstStyle/>
<a:p><a:pPr><a:buAutoNum type="arabicPeriod"/></a:pPr>${runsXml} </a:p>
</p:txBody>
</p:sp>`
if
type
'blockquote'
const
rect
const
parseInlineRuns
text
const
renderRuns
1600
`
<p:sp>
<p:nvSpPr>
<p:cNvPr id="${nextShapeId()} " name="blockquote"/>
<p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
<p:nvPr/>
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="${r.x} " y="${r.y} "/>
<a:ext cx="${r.w} " cy="${r.h} "/>
</a:xfrm>
<a:ln w="25400">
<a:solidFill><a:srgbClr val="4472C4"/></a:solidFill>
</a:ln>
</p:spPr>
<p:txBody>
<a:bodyPr lIns="228600"/>
<a:lstStyle/>
<a:p>${runsXml} </a:p>
</p:txBody>
</p:sp>`
if
type
'code'
const
rect
const
text
split
'\n'
let
''
for
const
of
`<a:p><a:r><a:rPr sz="1200"><a:solidFill><a:srgbClr val="333333"/></a:solidFill></a:rPr><a:t>${esc(line)} </a:t></a:r></a:p>`
`
<p:sp>
<p:nvSpPr>
<p:cNvPr id="${nextShapeId()} " name="code"/>
<p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
<p:nvPr/>
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="${r.x} " y="${r.y} "/>
<a:ext cx="${r.w} " cy="${r.h} "/>
</a:xfrm>
<a:solidFill>
<a:srgbClr val="F5F5F5"/>
</a:solidFill>
</p:spPr>
<p:txBody>
<a:bodyPr lIns="91440" tIns="45720" rIns="91440" bIns="45720"/>
<a:lstStyle/>
${paragraphs}
</p:txBody>
</p:sp>`
if
type
'table'
const
rect
const
rows
const
0
0
length
1
const
Math
floor
w
const
Math
floor
h
length
let
''
for
let
0
`<a:gridCol w="${colWidth} "/>`
let
''
for
let
0
length
let
''
const
0
for
let
0
length
0
if
`<a:tc>
<a:txBody>
<a:bodyPr/>
<a:lstStyle/>
<a:p><a:r><a:rPr sz="1400" b="1"><a:solidFill><a:srgbClr val="FFFFFF"/></a:solidFill></a:rPr><a:t>${esc(rows[ri][ci])} </a:t></a:r></a:p>
</a:txBody>
<a:tcPr><a:solidFill><a:srgbClr val="4472C4"/></a:solidFill></a:tcPr>
</a:tc>`
else
`<a:tc>
<a:txBody>
<a:bodyPr/>
<a:lstStyle/>
<a:p><a:r><a:rPr sz="1400"/><a:t>${esc(rows[ri][ci])} </a:t></a:r></a:p>
</a:txBody>
<a:tcPr/>
</a:tc>`
`<a:tr h="${rowHeight} ">${cells} </a:tr>`
`
<p:graphicFrame>
<p:nvGraphicFramePr>
<p:cNvPr id="${nextShapeId()} " name="table"/>
<p:cNvGraphicFramePr><a:graphicFrameLocks noGrp="1"/></p:cNvGraphicFramePr>
<p:nvPr/>
</p:nvGraphicFramePr>
<p:xfrm>
<a:off x="${r.x} " y="${r.y} "/>
<a:ext cx="${r.w} " cy="${r.h} "/>
</p:xfrm>
<a:graphic>
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/table">
<a:tbl>
<a:tblPr/>
<a:tblGrid>${gridCols} </a:tblGrid>
${tableRows}
</a:tbl>
</a:graphicData>
</a:graphic>
</p:graphicFrame>`
if
type
'image'
imageRId
const
rect
`
<p:pic>
<p:nvPicPr>
<p:cNvPr id="${nextShapeId()} " name="image"/>
<p:cNvPicPr/>
<p:nvPr/>
</p:nvPicPr>
<p:blipFill>
<a:blip r:embed="${item.imageRId} "/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</p:blipFill>
<p:spPr>
<a:xfrm>
<a:off x="${r.x} " y="${r.y} "/>
<a:ext cx="${r.w} " cy="${r.h} "/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
</p:spPr>
</p:pic>`
return
`<?xml version="1.0" encoding="UTF-8"?>
<p:sld xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<p:cSld>
<p:spTree>
<p:nvGrpSpPr>
<p:cNvPr id="1" name=""/>
<p:cNvGrpSpPr/>
<p:nvPr/>
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="0" cy="0"/>
<a:chOff x="0" y="0"/>
<a:chExt cx="0" cy="0"/>
</a:xfrm>
</p:grpSpPr>
${shapes}
</p:spTree>
</p:cSld>
<p:clrMapOvr>
<a:masterClrMapping/>
</p:clrMapOvr>
</p:sld>`
function
rootRels
return
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="ppt/presentation.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/></Relationships>`
function
presentation
slideCount
let
''
for
let
0
` <p:sldId id="${256 + i} " r:id="rId${i + 2 } "/>\n`
return
`<?xml version="1.0" encoding="UTF-8"?>
<p:presentation xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<p:sldMasterIdLst>
<p:sldMasterId id="2147483648" r:id="rId1"/>
</p:sldMasterIdLst>
<p:sldIdLst>
${slideList} </p:sldIdLst>
<p:sldSz cx="9144000" cy="6858000" type="screen4x3"/>
<p:notesSz cx="6858000" cy="9144000"/>
<p:defaultTextStyle>
<a:defPPr>
<a:defRPr lang="en-US"/>
</a:defPPr>
<a:lvl1pPr marL="0" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl1pPr>
<a:lvl2pPr marL="457200" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl2pPr>
<a:lvl3pPr marL="914400" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl3pPr>
<a:lvl4pPr marL="1371600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl4pPr>
<a:lvl5pPr marL="1828800" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl5pPr>
<a:lvl6pPr marL="2286000" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl6pPr>
<a:lvl7pPr marL="2743200" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl7pPr>
<a:lvl8pPr marL="3200400" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl8pPr>
<a:lvl9pPr marL="3657600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1">
<a:defRPr sz="1800" kern="1200">
<a:solidFill><a:schemeClr val="tx1"/></a:solidFill>
<a:latin typeface="+mn-lt"/>
<a:ea typeface="+mn-ea"/>
<a:cs typeface="+mn-cs"/>
</a:defRPr>
</a:lvl9pPr>
</p:defaultTextStyle>
</p:presentation>`
function
presentationRels
slideCount
let
` <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="slideMasters/slideMaster1.xml"/>\n`
for
let
0
` <Relationship Id="rId${i + 2 } " Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" Target="slides/slide${i + 1 } .xml"/>\n`
const
2
` <Relationship Id="rId${presRId} " Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps" Target="presProps.xml"/>\n`
` <Relationship Id="rId${presRId + 1 } " Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps" Target="viewProps.xml"/>\n`
` <Relationship Id="rId${presRId + 2 } " Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>\n`
` <Relationship Id="rId${presRId + 3 } " Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles" Target="tableStyles.xml"/>\n`
return
`<?xml version="1.0" encoding="UTF-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
${rels} </Relationships>`
function
slideRels
slide
let
` <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/>\n`
if
_images
for
const
of
_images
` <Relationship Id="${img.rId} " Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/${img.fileName} "/>\n`
if
_linkMap
for
const
of
Object
entries
_linkMap
` <Relationship Id="${rId} " Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="${esc(url)} " TargetMode="External"/>\n`
return
`<?xml version="1.0" encoding="UTF-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
${rels} </Relationships>`
function
contentTypes
slideCount, imageExts
let
` <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>\n`
` <Default Extension="xml" ContentType="application/xml"/>\n`
if
size
0
for
const
of
` <Default Extension="${ext} " ContentType="image/${ext} "/>\n`
let
''
` <Override PartName="/ppt/presentation.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/>\n`
` <Override PartName="/ppt/presProps.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presProps+xml"/>\n`
` <Override PartName="/ppt/viewProps.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml"/>\n`
` <Override PartName="/ppt/tableStyles.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml"/>\n`
` <Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/>\n`
` <Override PartName="/ppt/slideLayouts/slideLayout1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/>\n`
` <Override PartName="/ppt/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>\n`
for
let
0
` <Override PartName="/ppt/slides/slide${i + 1 } .xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/>\n`
` <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>\n`
` <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>\n`
return
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
${defaults} ${overrides} </Types>`
function
presProps
return
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<p:presentationPr xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<p:extLst>
<p:ext uri="{E76CE94A-603C-4142-B9EB-6D1370010A27}">
<p14:discardImageEditData xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="0"/>
</p:ext>
<p:ext uri="{D31A062A-798A-432F-ABDD-D45BAFD82E40}">
<p14:defaultImageDpi xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="220"/>
</p:ext>
<p:ext uri="{FD5C536A-5214-4C46-B8D8-A1DB69A19C07}">
<p14:chartTrackingRefBased xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="1"/>
</p:ext>
</p:extLst>
</p:presentationPr>`
function
viewProps
return
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<p:viewPr xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<p:normalViewPr showOutlineIcons="1">
<p:restoredLeft sz="15600"/>
<p:restoredTop sz="15260"/>
</p:normalViewPr>
<p:slideViewPr showComments="1">
<p:cSldViewPr snapToGrid="1" snapToObjects="1" showGuides="1">
<p:cViewPr varScale="1">
<p:scale>
<a:sx n="100000" d="100000"/>
<a:sy n="100000" d="100000"/>
</p:scale>
<p:origin x="0" y="0"/>
</p:cViewPr>
<p:guideLst/>
</p:cSldViewPr>
</p:slideViewPr>
<p:notesTextViewPr>
<p:cViewPr>
<p:scale>
<a:sx n="1" d="1"/>
<a:sy n="1" d="1"/>
</p:scale>
<p:origin x="0" y="0"/>
</p:cViewPr>
</p:notesTextViewPr>
<p:gridSpacing cx="76200" cy="76200"/>
</p:viewPr>`
function
tableStyles
return
`<?xml version="1.0" encoding="UTF-8"?>\n<a:tblStyleLst xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" def="{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}"/>`
function
docPropsCore
const
new
Date
toISOString
replace
/\.\d{3}/
''
return
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:creator>BoxAgnts</dc:creator><cp:lastModifiedBy>BoxAgnts</cp:lastModifiedBy><cp:revision>1</cp:revision><dcterms:modified xsi:type="dcterms:W3CDTF">${now} </dcterms:modified></cp:coreProperties>`
function
docPropsApp
slideCount
return
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><TotalTime>0</TotalTime><Words>0</Words><Application>BoxAgnts PPTX Generator</Application><PresentationFormat>On-screen Show (4:3)</PresentationFormat><Paragraphs>0</Paragraphs><Slides>${slideCount} </Slides><Notes>0</Notes><HiddenSlides>0</HiddenSlides><MMClips>0</MMClips><ScaleCrop>false</ScaleCrop><LinksUpToDate>false</LinksUpToDate><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>1.0</AppVersion></Properties>`
function
compileMarkdownToPPTX
md, output_path, options
if
1
2
1
const
new
ZipBuilder
const
parseMarkdownAST
resolveImages
const
buildSlideIR
const
length
const
new
Set
for
let
0
length
const
_images
_showSlideNumber
showSlideNumbers
_pageNumber
1
_totalPages
if
images
images
length
0
for
const
of
images
const
typeof
'object'
data
if
typeof
'string'
startsWith
'data:'
const
_ext
'png'
const
addImageToZip
_images
push
if
ext
add
ext
add
"_rels/.rels"
rootRels
add
"ppt/presentation.xml"
presentation
length
add
"ppt/_rels/presentation.xml.rels"
presentationRels
length
add
"ppt/presProps.xml"
presProps
add
"ppt/viewProps.xml"
viewProps
add
"ppt/tableStyles.xml"
tableStyles
add
"ppt/slideMasters/slideMaster1.xml"
slideMaster
add
"ppt/slideMasters/_rels/slideMaster1.xml.rels"
slideMasterRels
add
"ppt/slideLayouts/slideLayout1.xml"
slideLayout
add
"ppt/slideLayouts/_rels/slideLayout1.xml.rels"
slideLayoutRels
add
"ppt/theme/theme1.xml"
theme
add
"docProps/core.xml"
docPropsCore
add
"docProps/app.xml"
docPropsApp
length
for
let
0
length
const
const
layoutSlide
let
0
for
const
of
if
type
'image'
_images
imageRId
_images
rId
scanAndAssignLinks
add
`ppt/slides/slide${i + 1 } .xml`
renderSlideXML
add
`ppt/slides/_rels/slide${i + 1 } .xml.rels`
slideRels
add
"[Content_Types].xml"
contentTypes
length
writeFileSync
build
return
path
slides
length
const
`{{markdown}}`
replace
/^\{\{markdown\}\}$/
''
''
const
`{{output_path}}`
replace
/^\{\{output_path\}\}$/
''
'/tmp/output.pptx'
const
`{{show_slide_numbers}}`
replace
/^\{\{show_slide_numbers\}\}$/
''
'false'
'true'
const
compileMarkdownToPPTX
showSlideNumbers
console
log
`PPTX generated: ${result.path} `
console
log
`Slides: ${result.slides} `