docrev 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/bin/rev.js +5 -12
  2. package/dist/bin/rev.js +2 -2
  3. package/dist/lib/build.d.ts +2 -0
  4. package/dist/lib/build.d.ts.map +1 -1
  5. package/dist/lib/build.js +128 -2
  6. package/dist/lib/build.js.map +1 -1
  7. package/dist/lib/commands/comments.d.ts.map +1 -1
  8. package/dist/lib/commands/comments.js +19 -27
  9. package/dist/lib/commands/comments.js.map +1 -1
  10. package/dist/lib/commands/context.d.ts +1 -0
  11. package/dist/lib/commands/context.d.ts.map +1 -1
  12. package/dist/lib/commands/context.js +1 -2
  13. package/dist/lib/commands/context.js.map +1 -1
  14. package/dist/lib/commands/sections.d.ts.map +1 -1
  15. package/dist/lib/commands/sections.js +13 -0
  16. package/dist/lib/commands/sections.js.map +1 -1
  17. package/dist/lib/commands/utilities.d.ts.map +1 -1
  18. package/dist/lib/commands/utilities.js +20 -53
  19. package/dist/lib/commands/utilities.js.map +1 -1
  20. package/dist/lib/comment-realign.d.ts.map +1 -1
  21. package/dist/lib/comment-realign.js +0 -7
  22. package/dist/lib/comment-realign.js.map +1 -1
  23. package/dist/lib/crossref.d.ts +15 -0
  24. package/dist/lib/crossref.d.ts.map +1 -1
  25. package/dist/lib/crossref.js +54 -1
  26. package/dist/lib/crossref.js.map +1 -1
  27. package/dist/lib/dependencies.d.ts.map +1 -1
  28. package/dist/lib/dependencies.js +11 -23
  29. package/dist/lib/dependencies.js.map +1 -1
  30. package/dist/lib/git.d.ts.map +1 -1
  31. package/dist/lib/git.js +18 -28
  32. package/dist/lib/git.js.map +1 -1
  33. package/dist/lib/import.d.ts.map +1 -1
  34. package/dist/lib/import.js +1 -10
  35. package/dist/lib/import.js.map +1 -1
  36. package/dist/lib/journals.d.ts.map +1 -1
  37. package/dist/lib/journals.js +13 -0
  38. package/dist/lib/journals.js.map +1 -1
  39. package/dist/lib/merge.d.ts.map +1 -1
  40. package/dist/lib/merge.js +29 -117
  41. package/dist/lib/merge.js.map +1 -1
  42. package/dist/lib/pdf-comments.d.ts.map +1 -1
  43. package/dist/lib/pdf-comments.js +1 -13
  44. package/dist/lib/pdf-comments.js.map +1 -1
  45. package/dist/lib/pptx-themes.d.ts.map +1 -1
  46. package/dist/lib/pptx-themes.js +0 -403
  47. package/dist/lib/pptx-themes.js.map +1 -1
  48. package/dist/lib/protect-restore.d.ts.map +1 -1
  49. package/dist/lib/protect-restore.js +34 -36
  50. package/dist/lib/protect-restore.js.map +1 -1
  51. package/dist/lib/slides.d.ts.map +1 -1
  52. package/dist/lib/slides.js +0 -35
  53. package/dist/lib/slides.js.map +1 -1
  54. package/dist/lib/trackchanges.d.ts.map +1 -1
  55. package/dist/lib/trackchanges.js +1 -11
  56. package/dist/lib/trackchanges.js.map +1 -1
  57. package/dist/lib/tui.d.ts +36 -45
  58. package/dist/lib/tui.d.ts.map +1 -1
  59. package/dist/lib/tui.js +92 -108
  60. package/dist/lib/tui.js.map +1 -1
  61. package/dist/lib/types.d.ts +2 -0
  62. package/dist/lib/types.d.ts.map +1 -1
  63. package/dist/lib/undo.d.ts +3 -4
  64. package/dist/lib/undo.d.ts.map +1 -1
  65. package/dist/lib/undo.js +0 -7
  66. package/dist/lib/undo.js.map +1 -1
  67. package/dist/lib/utils.d.ts +12 -0
  68. package/dist/lib/utils.d.ts.map +1 -1
  69. package/dist/lib/utils.js +26 -0
  70. package/dist/lib/utils.js.map +1 -1
  71. package/dist/lib/wordcomments.d.ts.map +1 -1
  72. package/dist/lib/wordcomments.js +1 -8
  73. package/dist/lib/wordcomments.js.map +1 -1
  74. package/dist/package.json +137 -0
  75. package/lib/build.ts +143 -2
  76. package/lib/commands/comments.ts +20 -25
  77. package/lib/commands/context.ts +1 -2
  78. package/lib/commands/sections.ts +13 -0
  79. package/lib/commands/utilities.ts +30 -53
  80. package/lib/comment-realign.ts +0 -8
  81. package/lib/crossref.ts +62 -1
  82. package/lib/dependencies.ts +12 -20
  83. package/lib/git.ts +24 -31
  84. package/lib/import.ts +1 -11
  85. package/lib/journals.ts +14 -0
  86. package/lib/merge.ts +42 -132
  87. package/lib/pdf-comments.ts +2 -14
  88. package/lib/pptx-themes.ts +0 -413
  89. package/lib/protect-restore.ts +48 -44
  90. package/lib/slides.ts +0 -37
  91. package/lib/trackchanges.ts +1 -12
  92. package/lib/{tui.js → tui.ts} +139 -126
  93. package/lib/types.ts +2 -0
  94. package/lib/undo.ts +3 -12
  95. package/lib/utils.ts +28 -0
  96. package/lib/wordcomments.ts +1 -9
  97. package/package.json +37 -37
  98. package/scripts/postbuild.js +28 -0
  99. package/skill/REFERENCE.md +1 -1
  100. package/skill/SKILL.md +1 -1
@@ -367,419 +367,6 @@ function generateTheme(theme: PptxTheme): string {
367
367
  </a:theme>`;
368
368
  }
369
369
 
370
- /**
371
- * Generate slide master with background
372
- */
373
- function generateSlideMaster(theme: PptxTheme): string {
374
- // For dark themes, set explicit background
375
- let bgFill = '<a:solidFill><a:schemeClr val="lt1"/></a:solidFill>';
376
- if (theme.background) {
377
- bgFill = `<a:solidFill><a:srgbClr val="${theme.background}"/></a:solidFill>`;
378
- }
379
-
380
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
381
- <p:sldMaster xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
382
- <p:cSld>
383
- <p:bg>
384
- <p:bgPr>
385
- ${bgFill}
386
- <a:effectLst/>
387
- </p:bgPr>
388
- </p:bg>
389
- <p:spTree>
390
- <p:nvGrpSpPr>
391
- <p:cNvPr id="1" name=""/>
392
- <p:cNvGrpSpPr/>
393
- <p:nvPr/>
394
- </p:nvGrpSpPr>
395
- <p:grpSpPr>
396
- <a:xfrm>
397
- <a:off x="0" y="0"/>
398
- <a:ext cx="0" cy="0"/>
399
- <a:chOff x="0" y="0"/>
400
- <a:chExt cx="0" cy="0"/>
401
- </a:xfrm>
402
- </p:grpSpPr>
403
- <p:sp>
404
- <p:nvSpPr>
405
- <p:cNvPr id="2" name="Title Placeholder 1"/>
406
- <p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
407
- <p:nvPr><p:ph type="title"/></p:nvPr>
408
- </p:nvSpPr>
409
- <p:spPr>
410
- <a:xfrm>
411
- <a:off x="838200" y="365125"/>
412
- <a:ext cx="10515600" cy="1325563"/>
413
- </a:xfrm>
414
- <a:prstGeom prst="rect"><a:avLst/></a:prstGeom>
415
- </p:spPr>
416
- <p:txBody>
417
- <a:bodyPr vert="horz" lIns="91440" tIns="45720" rIns="91440" bIns="45720" rtlCol="0" anchor="ctr"/>
418
- <a:lstStyle>
419
- <a:lvl1pPr algn="l">
420
- <a:defRPr sz="4400" b="0">
421
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
422
- <a:latin typeface="+mj-lt"/>
423
- <a:ea typeface="+mj-ea"/>
424
- <a:cs typeface="+mj-cs"/>
425
- </a:defRPr>
426
- </a:lvl1pPr>
427
- </a:lstStyle>
428
- <a:p><a:r><a:rPr lang="en-US"/><a:t>Click to edit Master title style</a:t></a:r></a:p>
429
- </p:txBody>
430
- </p:sp>
431
- <p:sp>
432
- <p:nvSpPr>
433
- <p:cNvPr id="3" name="Text Placeholder 2"/>
434
- <p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
435
- <p:nvPr><p:ph type="body" idx="1"/></p:nvPr>
436
- </p:nvSpPr>
437
- <p:spPr>
438
- <a:xfrm>
439
- <a:off x="838200" y="1825625"/>
440
- <a:ext cx="10515600" cy="4351338"/>
441
- </a:xfrm>
442
- <a:prstGeom prst="rect"><a:avLst/></a:prstGeom>
443
- </p:spPr>
444
- <p:txBody>
445
- <a:bodyPr vert="horz" lIns="91440" tIns="45720" rIns="91440" bIns="45720" rtlCol="0"/>
446
- <a:lstStyle>
447
- <a:lvl1pPr marL="0" indent="0" algn="l">
448
- <a:buNone/>
449
- <a:defRPr sz="2800">
450
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
451
- <a:latin typeface="+mn-lt"/>
452
- </a:defRPr>
453
- </a:lvl1pPr>
454
- <a:lvl2pPr marL="457200" indent="0" algn="l">
455
- <a:buNone/>
456
- <a:defRPr sz="2400">
457
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
458
- <a:latin typeface="+mn-lt"/>
459
- </a:defRPr>
460
- </a:lvl2pPr>
461
- <a:lvl3pPr marL="914400" indent="0" algn="l">
462
- <a:buNone/>
463
- <a:defRPr sz="2000">
464
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
465
- <a:latin typeface="+mn-lt"/>
466
- </a:defRPr>
467
- </a:lvl3pPr>
468
- <a:lvl4pPr marL="1371600" indent="0" algn="l">
469
- <a:buNone/>
470
- <a:defRPr sz="1800">
471
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
472
- <a:latin typeface="+mn-lt"/>
473
- </a:defRPr>
474
- </a:lvl4pPr>
475
- <a:lvl5pPr marL="1828800" indent="0" algn="l">
476
- <a:buNone/>
477
- <a:defRPr sz="1800">
478
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
479
- <a:latin typeface="+mn-lt"/>
480
- </a:defRPr>
481
- </a:lvl5pPr>
482
- </a:lstStyle>
483
- <a:p><a:pPr lvl="0"/><a:r><a:rPr lang="en-US"/><a:t>Click to edit Master text styles</a:t></a:r></a:p>
484
- <a:p><a:pPr lvl="1"/><a:r><a:rPr lang="en-US"/><a:t>Second level</a:t></a:r></a:p>
485
- <a:p><a:pPr lvl="2"/><a:r><a:rPr lang="en-US"/><a:t>Third level</a:t></a:r></a:p>
486
- </p:txBody>
487
- </p:sp>
488
- <p:sp>
489
- <p:nvSpPr>
490
- <p:cNvPr id="4" name="Slide Number Placeholder 3"/>
491
- <p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
492
- <p:nvPr><p:ph type="sldNum" sz="quarter" idx="4"/></p:nvPr>
493
- </p:nvSpPr>
494
- <p:spPr>
495
- <a:xfrm>
496
- <a:off x="8610600" y="6356350"/>
497
- <a:ext cx="2743200" cy="365125"/>
498
- </a:xfrm>
499
- <a:prstGeom prst="rect"><a:avLst/></a:prstGeom>
500
- </p:spPr>
501
- <p:txBody>
502
- <a:bodyPr vert="horz" lIns="91440" tIns="45720" rIns="91440" bIns="45720" rtlCol="0" anchor="ctr"/>
503
- <a:lstStyle>
504
- <a:lvl1pPr algn="r">
505
- <a:defRPr sz="1200">
506
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
507
- </a:defRPr>
508
- </a:lvl1pPr>
509
- </a:lstStyle>
510
- <a:p>
511
- <a:fld id="{B6F15528-21DE-4FAA-801F-C0D5B2D67AA7}" type="slidenum">
512
- <a:rPr lang="en-US" smtClean="0"/>
513
- <a:t>‹#›</a:t>
514
- </a:fld>
515
- <a:endParaRPr lang="en-US"/>
516
- </a:p>
517
- </p:txBody>
518
- </p:sp>
519
- </p:spTree>
520
- </p:cSld>
521
- <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"/>
522
- <p:sldLayoutIdLst>
523
- <p:sldLayoutId id="2147483649" r:id="rId1"/>
524
- <p:sldLayoutId id="2147483650" r:id="rId2"/>
525
- </p:sldLayoutIdLst>
526
- <p:txStyles>
527
- <p:titleStyle>
528
- <a:lvl1pPr algn="l">
529
- <a:defRPr sz="4400" b="0" kern="1200">
530
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
531
- <a:latin typeface="+mj-lt"/>
532
- <a:ea typeface="+mj-ea"/>
533
- <a:cs typeface="+mj-cs"/>
534
- </a:defRPr>
535
- </a:lvl1pPr>
536
- </p:titleStyle>
537
- <p:bodyStyle>
538
- <a:lvl1pPr marL="0" indent="0" algn="l">
539
- <a:buNone/>
540
- <a:defRPr sz="2800" kern="1200">
541
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
542
- <a:latin typeface="+mn-lt"/>
543
- <a:ea typeface="+mn-ea"/>
544
- <a:cs typeface="+mn-cs"/>
545
- </a:defRPr>
546
- </a:lvl1pPr>
547
- <a:lvl2pPr marL="457200" indent="0" algn="l">
548
- <a:buNone/>
549
- <a:defRPr sz="2400" kern="1200">
550
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
551
- <a:latin typeface="+mn-lt"/>
552
- </a:defRPr>
553
- </a:lvl2pPr>
554
- <a:lvl3pPr marL="914400" indent="0" algn="l">
555
- <a:buNone/>
556
- <a:defRPr sz="2000" kern="1200">
557
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
558
- <a:latin typeface="+mn-lt"/>
559
- </a:defRPr>
560
- </a:lvl3pPr>
561
- <a:lvl4pPr marL="1371600" indent="0" algn="l">
562
- <a:buNone/>
563
- <a:defRPr sz="1800" kern="1200">
564
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
565
- <a:latin typeface="+mn-lt"/>
566
- </a:defRPr>
567
- </a:lvl4pPr>
568
- <a:lvl5pPr marL="1828800" indent="0" algn="l">
569
- <a:buNone/>
570
- <a:defRPr sz="1800" kern="1200">
571
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
572
- <a:latin typeface="+mn-lt"/>
573
- </a:defRPr>
574
- </a:lvl5pPr>
575
- </p:bodyStyle>
576
- <p:otherStyle>
577
- <a:defPPr><a:defRPr lang="en-US"/></a:defPPr>
578
- </p:otherStyle>
579
- </p:txStyles>
580
- </p:sldMaster>`;
581
- }
582
-
583
- /**
584
- * Generate slide master relationships
585
- */
586
- function generateSlideMasterRels(): string {
587
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
588
- <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
589
- <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/>
590
- <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout2.xml"/>
591
- <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="../theme/theme1.xml"/>
592
- </Relationships>`;
593
- }
594
-
595
- /**
596
- * Generate title slide layout
597
- */
598
- function generateTitleLayout(theme: PptxTheme): string {
599
- let bgFill = '<a:solidFill><a:schemeClr val="lt1"/></a:solidFill>';
600
- if (theme.background) {
601
- bgFill = `<a:solidFill><a:srgbClr val="${theme.background}"/></a:solidFill>`;
602
- }
603
-
604
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
605
- <p:sldLayout xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" type="title" preserve="1">
606
- <p:cSld name="Title Slide">
607
- <p:bg>
608
- <p:bgPr>
609
- ${bgFill}
610
- <a:effectLst/>
611
- </p:bgPr>
612
- </p:bg>
613
- <p:spTree>
614
- <p:nvGrpSpPr>
615
- <p:cNvPr id="1" name=""/>
616
- <p:cNvGrpSpPr/>
617
- <p:nvPr/>
618
- </p:nvGrpSpPr>
619
- <p:grpSpPr>
620
- <a:xfrm>
621
- <a:off x="0" y="0"/>
622
- <a:ext cx="0" cy="0"/>
623
- <a:chOff x="0" y="0"/>
624
- <a:chExt cx="0" cy="0"/>
625
- </a:xfrm>
626
- </p:grpSpPr>
627
- <p:sp>
628
- <p:nvSpPr>
629
- <p:cNvPr id="2" name="Title 1"/>
630
- <p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
631
- <p:nvPr><p:ph type="ctrTitle"/></p:nvPr>
632
- </p:nvSpPr>
633
- <p:spPr>
634
- <a:xfrm>
635
- <a:off x="1524000" y="1122363"/>
636
- <a:ext cx="9144000" cy="2387600"/>
637
- </a:xfrm>
638
- </p:spPr>
639
- <p:txBody>
640
- <a:bodyPr anchor="b"/>
641
- <a:lstStyle>
642
- <a:lvl1pPr algn="ctr">
643
- <a:defRPr sz="6000">
644
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
645
- </a:defRPr>
646
- </a:lvl1pPr>
647
- </a:lstStyle>
648
- <a:p><a:r><a:rPr lang="en-US"/><a:t>Click to edit title</a:t></a:r></a:p>
649
- </p:txBody>
650
- </p:sp>
651
- <p:sp>
652
- <p:nvSpPr>
653
- <p:cNvPr id="3" name="Subtitle 2"/>
654
- <p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
655
- <p:nvPr><p:ph type="subTitle" idx="1"/></p:nvPr>
656
- </p:nvSpPr>
657
- <p:spPr>
658
- <a:xfrm>
659
- <a:off x="1524000" y="3602038"/>
660
- <a:ext cx="9144000" cy="1655762"/>
661
- </a:xfrm>
662
- </p:spPr>
663
- <p:txBody>
664
- <a:bodyPr/>
665
- <a:lstStyle>
666
- <a:lvl1pPr marL="0" indent="0" algn="ctr">
667
- <a:buNone/>
668
- <a:defRPr sz="2400">
669
- <a:solidFill><a:schemeClr val="dk1"/></a:solidFill>
670
- </a:defRPr>
671
- </a:lvl1pPr>
672
- </a:lstStyle>
673
- <a:p><a:r><a:rPr lang="en-US"/><a:t>Click to edit subtitle</a:t></a:r></a:p>
674
- </p:txBody>
675
- </p:sp>
676
- </p:spTree>
677
- </p:cSld>
678
- <p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>
679
- </p:sldLayout>`;
680
- }
681
-
682
- /**
683
- * Generate content slide layout
684
- */
685
- function generateContentLayout(theme: PptxTheme): string {
686
- let bgFill = '<a:solidFill><a:schemeClr val="lt1"/></a:solidFill>';
687
- if (theme.background) {
688
- bgFill = `<a:solidFill><a:srgbClr val="${theme.background}"/></a:solidFill>`;
689
- }
690
-
691
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
692
- <p:sldLayout xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" type="obj" preserve="1">
693
- <p:cSld name="Title and Content">
694
- <p:bg>
695
- <p:bgPr>
696
- ${bgFill}
697
- <a:effectLst/>
698
- </p:bgPr>
699
- </p:bg>
700
- <p:spTree>
701
- <p:nvGrpSpPr>
702
- <p:cNvPr id="1" name=""/>
703
- <p:cNvGrpSpPr/>
704
- <p:nvPr/>
705
- </p:nvGrpSpPr>
706
- <p:grpSpPr>
707
- <a:xfrm>
708
- <a:off x="0" y="0"/>
709
- <a:ext cx="0" cy="0"/>
710
- <a:chOff x="0" y="0"/>
711
- <a:chExt cx="0" cy="0"/>
712
- </a:xfrm>
713
- </p:grpSpPr>
714
- <p:sp>
715
- <p:nvSpPr>
716
- <p:cNvPr id="2" name="Title 1"/>
717
- <p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
718
- <p:nvPr><p:ph type="title"/></p:nvPr>
719
- </p:nvSpPr>
720
- <p:spPr/>
721
- <p:txBody>
722
- <a:bodyPr/>
723
- <a:lstStyle/>
724
- <a:p><a:r><a:rPr lang="en-US"/><a:t>Click to edit title</a:t></a:r></a:p>
725
- </p:txBody>
726
- </p:sp>
727
- <p:sp>
728
- <p:nvSpPr>
729
- <p:cNvPr id="3" name="Content Placeholder 2"/>
730
- <p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr>
731
- <p:nvPr><p:ph idx="1"/></p:nvPr>
732
- </p:nvSpPr>
733
- <p:spPr/>
734
- <p:txBody>
735
- <a:bodyPr/>
736
- <a:lstStyle/>
737
- <a:p><a:pPr lvl="0"/><a:r><a:rPr lang="en-US"/><a:t>Click to edit text</a:t></a:r></a:p>
738
- </p:txBody>
739
- </p:sp>
740
- </p:spTree>
741
- </p:cSld>
742
- <p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>
743
- </p:sldLayout>`;
744
- }
745
-
746
- /**
747
- * Generate slide layout relationships
748
- */
749
- function generateSlideLayoutRels(): string {
750
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
751
- <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
752
- <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="../slideMasters/slideMaster1.xml"/>
753
- </Relationships>`;
754
- }
755
-
756
- /**
757
- * Generate docProps/core.xml
758
- */
759
- function generateCore(themeName: string): string {
760
- const now = new Date().toISOString();
761
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
762
- <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">
763
- <dc:title>${themeName} Theme</dc:title>
764
- <dc:creator>docrev</dc:creator>
765
- <cp:lastModifiedBy>docrev</cp:lastModifiedBy>
766
- <dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created>
767
- <dcterms:modified xsi:type="dcterms:W3CDTF">${now}</dcterms:modified>
768
- </cp:coreProperties>`;
769
- }
770
-
771
- /**
772
- * Generate docProps/app.xml
773
- */
774
- function generateApp(): string {
775
- return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
776
- <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
777
- <Application>docrev</Application>
778
- <PresentationFormat>Widescreen</PresentationFormat>
779
- <Slides>0</Slides>
780
- </Properties>`;
781
- }
782
-
783
370
  /**
784
371
  * Get pandoc's default reference.pptx as a base template
785
372
  */
@@ -69,6 +69,46 @@ interface ImageRegistry {
69
69
  byNumber?: Map<string, { label: string }>;
70
70
  }
71
71
 
72
+ // =============================================================================
73
+ // Shared Helpers
74
+ // =============================================================================
75
+
76
+ /**
77
+ * Replace regex matches with indexed placeholders and collect originals
78
+ */
79
+ function collectAndReplace(
80
+ text: string,
81
+ pattern: RegExp,
82
+ prefix: string,
83
+ suffix: string,
84
+ ): { text: string; items: ProtectedItem[] } {
85
+ const items: ProtectedItem[] = [];
86
+ const result = text.replace(pattern, (match) => {
87
+ const idx = items.length;
88
+ const placeholder = `${prefix}${idx}${suffix}`;
89
+ items.push({ original: match, placeholder });
90
+ return placeholder;
91
+ });
92
+ return { text: result, items };
93
+ }
94
+
95
+ /**
96
+ * Restore protected items from placeholders, handling annotation wrappers
97
+ * (deletion {--...--} and insertion {++...++} wrappers are unwrapped)
98
+ */
99
+ function restoreProtectedItems(text: string, items: ProtectedItem[]): string {
100
+ for (const item of items) {
101
+ const deletionPattern = new RegExp(`\\{--[^}]*?${item.placeholder}[^}]*?--\\}`, 'g');
102
+ text = text.replace(deletionPattern, item.original);
103
+
104
+ const insertionPattern = new RegExp(`\\{\\+\\+[^}]*?${item.placeholder}[^}]*?\\+\\+\\}`, 'g');
105
+ text = text.replace(insertionPattern, item.original);
106
+
107
+ text = text.split(item.placeholder).join(item.original);
108
+ }
109
+ return text;
110
+ }
111
+
72
112
  // =============================================================================
73
113
  // Public Functions
74
114
  // =============================================================================
@@ -103,17 +143,11 @@ export function extractMarkdownPrefix(line: string): MarkdownPrefix {
103
143
  * Anchors like {#fig:heatmap} and {#tbl:results} should never be deleted
104
144
  */
105
145
  export function protectAnchors(md: string): ProtectAnchorsResult {
106
- const anchors: ProtectedItem[] = [];
107
-
108
146
  // Match {#fig:label}, {#tbl:label}, {#eq:label}, {#sec:label} etc.
109
147
  // Also match with additional attributes like {#fig:label width=50%}
110
- const text = md.replace(/\{#(fig|tbl|eq|sec|lst):[^}]+\}/g, (match) => {
111
- const idx = anchors.length;
112
- const placeholder = `ANCHORBLOCK${idx}ENDANCHOR`;
113
- anchors.push({ original: match, placeholder });
114
- return placeholder;
115
- });
116
-
148
+ const { text, items: anchors } = collectAndReplace(
149
+ md, /\{#(fig|tbl|eq|sec|lst):[^}]+\}/g, 'ANCHORBLOCK', 'ENDANCHOR',
150
+ );
117
151
  return { text, anchors };
118
152
  }
119
153
 
@@ -164,17 +198,11 @@ export function restoreAnchors(text: string, anchors: ProtectedItem[]): string {
164
198
  * References like @fig:label, @tbl:label should be preserved
165
199
  */
166
200
  export function protectCrossrefs(md: string): ProtectCrossrefsResult {
167
- const crossrefs: ProtectedItem[] = [];
168
-
169
201
  // Match @fig:label, @tbl:label, @eq:label, @sec:label
170
202
  // Can appear as @fig:label or (@fig:label) or [@fig:label]
171
- const text = md.replace(/@(fig|tbl|eq|sec|lst):[a-zA-Z0-9_-]+/g, (match) => {
172
- const idx = crossrefs.length;
173
- const placeholder = `XREFBLOCK${idx}ENDXREF`;
174
- crossrefs.push({ original: match, placeholder });
175
- return placeholder;
176
- });
177
-
203
+ const { text, items: crossrefs } = collectAndReplace(
204
+ md, /@(fig|tbl|eq|sec|lst):[a-zA-Z0-9_-]+/g, 'XREFBLOCK', 'ENDXREF',
205
+ );
178
206
  return { text, crossrefs };
179
207
  }
180
208
 
@@ -386,19 +414,7 @@ export function protectImages(md: string, registry: ImageRegistry | null = null)
386
414
  * Restore images from placeholders
387
415
  */
388
416
  export function restoreImages(text: string, images: ProtectedImage[]): string {
389
- for (const img of images) {
390
- // Handle cases where placeholder might be inside annotations
391
- // {--IMAGEBLOCK0ENDIMAGE--} should restore the original image
392
- const deletionPattern = new RegExp(`\\{--[^}]*?${img.placeholder}[^}]*?--\\}`, 'g');
393
- text = text.replace(deletionPattern, img.original);
394
-
395
- const insertionPattern = new RegExp(`\\{\\+\\+[^}]*?${img.placeholder}[^}]*?\\+\\+\\}`, 'g');
396
- text = text.replace(insertionPattern, img.original);
397
-
398
- // Normal replacement
399
- text = text.split(img.placeholder).join(img.original);
400
- }
401
- return text;
417
+ return restoreProtectedItems(text, images);
402
418
  }
403
419
 
404
420
  /**
@@ -500,17 +516,5 @@ export function protectTables(md: string): ProtectTablesResult {
500
516
  * Restore tables from placeholders
501
517
  */
502
518
  export function restoreTables(text: string, tables: ProtectedTable[]): string {
503
- for (const table of tables) {
504
- // Handle cases where placeholder might be inside annotations
505
- // For tables, we want to preserve the original if it wasn't changed
506
- const deletionPattern = new RegExp(`\\{--[^}]*?${table.placeholder}[^}]*?--\\}`, 'g');
507
- text = text.replace(deletionPattern, table.original);
508
-
509
- const insertionPattern = new RegExp(`\\{\\+\\+[^}]*?${table.placeholder}[^}]*?\\+\\+\\}`, 'g');
510
- text = text.replace(insertionPattern, table.original);
511
-
512
- // Normal replacement
513
- text = text.split(table.placeholder).join(table.original);
514
- }
515
- return text;
519
+ return restoreProtectedItems(text, tables);
516
520
  }
package/lib/slides.ts CHANGED
@@ -90,16 +90,6 @@ const BEAMER_BACKGROUNDS: Record<string, string> = {
90
90
  inverse: '\\setbeamercolor{background canvas}{bg=structure.fg!90!black}\\setbeamercolor{normal text}{fg=white}\\usebeamercolor[fg]{normal text}',
91
91
  };
92
92
 
93
- /**
94
- * Special slide types mapped to Beamer frame options
95
- */
96
- const BEAMER_FRAME_OPTIONS: Record<string, string> = {
97
- cover: 'plain,noframenumbering,c',
98
- thanks: 'plain,noframenumbering,c',
99
- section: 'plain,noframenumbering,c',
100
- plain: 'plain',
101
- };
102
-
103
93
  /**
104
94
  * Parse a bullet list into a tree structure
105
95
  */
@@ -473,33 +463,6 @@ export function parseSlides(markdown: string): Slide[] {
473
463
  return slides;
474
464
  }
475
465
 
476
- /**
477
- * Build Beamer frame options string
478
- */
479
- function buildBeamerFrameOptions(style: SlideStyle | null): string {
480
- if (!style) return '';
481
-
482
- const options: string[] = [];
483
-
484
- // Special slide type options
485
- if (style.type && BEAMER_FRAME_OPTIONS[style.type]) {
486
- const opts = BEAMER_FRAME_OPTIONS[style.type];
487
- if (opts) options.push(...opts.split(','));
488
- } else {
489
- // Individual options
490
- if (style.nonumber) {
491
- options.push('noframenumbering');
492
- }
493
- if (style.center) {
494
- options.push('c');
495
- }
496
- }
497
-
498
- // Deduplicate
499
- const unique = [...new Set(options)];
500
- return unique.length > 0 ? `[${unique.join(',')}]` : '';
501
- }
502
-
503
466
  /**
504
467
  * Generate Beamer markdown using pandoc's native slide structure
505
468
  * Works WITH pandoc, not against it - pandoc creates frames, we add overlays
@@ -9,6 +9,7 @@ import * as path from 'path';
9
9
  import { execSync } from 'child_process';
10
10
  import AdmZip from 'adm-zip';
11
11
  import type { TrackChangeMarker } from './types.js';
12
+ import { escapeXml } from './utils.js';
12
13
 
13
14
  interface PrepareOptions {
14
15
  author?: string;
@@ -29,18 +30,6 @@ interface ApplyResult {
29
30
  };
30
31
  }
31
32
 
32
- /**
33
- * Escape XML special characters
34
- */
35
- function escapeXml(str: string): string {
36
- return str
37
- .replace(/&/g, '&amp;')
38
- .replace(/</g, '&lt;')
39
- .replace(/>/g, '&gt;')
40
- .replace(/"/g, '&quot;')
41
- .replace(/'/g, '&apos;');
42
- }
43
-
44
33
  /**
45
34
  * Prepare text with CriticMarkup annotations for track changes
46
35
  * Replaces annotations with markers that can be processed in DOCX