mdv-live 0.3.5 → 0.3.7
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.
- package/bin/mdv.js +1 -1
- package/package.json +1 -1
- package/src/api/pdf.js +1 -1
- package/src/rendering/markdown.js +15 -1
- package/src/static/app.js +19 -0
- package/src/static/styles.css +53 -0
package/bin/mdv.js
CHANGED
|
@@ -274,7 +274,7 @@ async function convertToPdf(inputPath, outputPath) {
|
|
|
274
274
|
*/
|
|
275
275
|
async function convertMarpToPdf(inputPath, outputPath) {
|
|
276
276
|
try {
|
|
277
|
-
execSync(`npx @marp-team/marp-cli --no-stdin "${inputPath}" --pdf -o "${outputPath}"`, {
|
|
277
|
+
execSync(`npx @marp-team/marp-cli --no-stdin "${inputPath}" --pdf --html --allow-local-files -o "${outputPath}"`, {
|
|
278
278
|
encoding: 'utf-8',
|
|
279
279
|
stdio: 'inherit'
|
|
280
280
|
});
|
package/package.json
CHANGED
package/src/api/pdf.js
CHANGED
|
@@ -49,7 +49,7 @@ export function setupPdfRoutes(app) {
|
|
|
49
49
|
|
|
50
50
|
const outputPath = fullPath.replace(/\.md$/, '.pdf');
|
|
51
51
|
const outputFileName = path.basename(outputPath);
|
|
52
|
-
const command = `"${marpBin}" "${fullPath}" -o "${outputPath}" --allow-local-files --no-stdin`;
|
|
52
|
+
const command = `"${marpBin}" "${fullPath}" -o "${outputPath}" --html --allow-local-files --no-stdin`;
|
|
53
53
|
|
|
54
54
|
try {
|
|
55
55
|
await execAsync(command, { timeout: 60000 });
|
|
@@ -23,9 +23,12 @@ md.use(taskLists, { enabled: true, label: true, labelAfter: true });
|
|
|
23
23
|
// Pattern to detect Marp frontmatter (must be at very start of file, not using 'm' flag)
|
|
24
24
|
const MARP_PATTERN = /^---\s*\n[\s\S]*?marp:\s*true[\s\S]*?\n---/;
|
|
25
25
|
|
|
26
|
-
// Pattern to detect YAML frontmatter
|
|
26
|
+
// Pattern to detect YAML frontmatter at start of file
|
|
27
27
|
const FRONTMATTER_PATTERN = /^---\s*\n([\s\S]*?)\n---\s*(\n|$)/;
|
|
28
28
|
|
|
29
|
+
// Pattern to detect metadata block after h1 heading (Claude Agent format)
|
|
30
|
+
const HEADING_METADATA_PATTERN = /^(#[^\n]+\n+)(---\s*\n)([\s\S]*?)(\n---\s*)(\n|$)/;
|
|
31
|
+
|
|
29
32
|
// Pattern for Mermaid code blocks
|
|
30
33
|
const MERMAID_PATTERN = /```mermaid\s*\n([\s\S]*?)\n```/g;
|
|
31
34
|
|
|
@@ -44,12 +47,23 @@ export function isMarp(content) {
|
|
|
44
47
|
* @returns {string} Content with frontmatter converted
|
|
45
48
|
*/
|
|
46
49
|
function convertFrontmatter(content) {
|
|
50
|
+
// Check for standard frontmatter at start of file
|
|
47
51
|
const match = content.match(FRONTMATTER_PATTERN);
|
|
48
52
|
if (match) {
|
|
49
53
|
const frontmatter = match[1];
|
|
50
54
|
const rest = content.slice(match[0].length);
|
|
51
55
|
return `\`\`\`yaml\n${frontmatter}\n\`\`\`\n${rest}`;
|
|
52
56
|
}
|
|
57
|
+
|
|
58
|
+
// Check for metadata block after h1 heading (Claude Agent format)
|
|
59
|
+
const headingMatch = content.match(HEADING_METADATA_PATTERN);
|
|
60
|
+
if (headingMatch) {
|
|
61
|
+
const heading = headingMatch[1];
|
|
62
|
+
const metadata = headingMatch[3];
|
|
63
|
+
const rest = content.slice(headingMatch[0].length);
|
|
64
|
+
return `${heading}\`\`\`yaml\n${metadata}\n\`\`\`\n${rest}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
53
67
|
return content;
|
|
54
68
|
}
|
|
55
69
|
|
package/src/static/app.js
CHANGED
|
@@ -608,6 +608,11 @@
|
|
|
608
608
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
609
609
|
</svg>
|
|
610
610
|
</button>
|
|
611
|
+
<button class="marp-fullscreen-btn" title="Fullscreen (F)">
|
|
612
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
613
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" />
|
|
614
|
+
</svg>
|
|
615
|
+
</button>
|
|
611
616
|
`;
|
|
612
617
|
marpit.appendChild(nav);
|
|
613
618
|
}
|
|
@@ -669,6 +674,13 @@
|
|
|
669
674
|
if (prevBtn) prevBtn.addEventListener('click', prevSlide);
|
|
670
675
|
if (nextBtn) nextBtn.addEventListener('click', nextSlide);
|
|
671
676
|
|
|
677
|
+
// Fullscreen toggle
|
|
678
|
+
const fullscreenBtn = elements.content.querySelector('.marp-fullscreen-btn');
|
|
679
|
+
const toggleFullscreen = () => {
|
|
680
|
+
document.body.classList.toggle('marp-fullscreen');
|
|
681
|
+
};
|
|
682
|
+
if (fullscreenBtn) fullscreenBtn.addEventListener('click', toggleFullscreen);
|
|
683
|
+
|
|
672
684
|
// Keyboard navigation
|
|
673
685
|
marpKeyHandler = (e) => {
|
|
674
686
|
// Don't handle if editing or in dialog
|
|
@@ -681,6 +693,12 @@
|
|
|
681
693
|
} else if (e.key === 'ArrowLeft') {
|
|
682
694
|
e.preventDefault();
|
|
683
695
|
prevSlide();
|
|
696
|
+
} else if (e.key === 'f' || e.key === 'F') {
|
|
697
|
+
e.preventDefault();
|
|
698
|
+
toggleFullscreen();
|
|
699
|
+
} else if (e.key === 'Escape' && document.body.classList.contains('marp-fullscreen')) {
|
|
700
|
+
e.preventDefault();
|
|
701
|
+
document.body.classList.remove('marp-fullscreen');
|
|
684
702
|
}
|
|
685
703
|
};
|
|
686
704
|
document.addEventListener('keydown', marpKeyHandler);
|
|
@@ -688,6 +706,7 @@
|
|
|
688
706
|
|
|
689
707
|
cleanupMarp() {
|
|
690
708
|
elements.content.classList.remove('marp-viewer');
|
|
709
|
+
document.body.classList.remove('marp-fullscreen');
|
|
691
710
|
if (marpKeyHandler) {
|
|
692
711
|
document.removeEventListener('keydown', marpKeyHandler);
|
|
693
712
|
marpKeyHandler = null;
|
package/src/static/styles.css
CHANGED
|
@@ -917,6 +917,59 @@ body {
|
|
|
917
917
|
margin-left: 8px;
|
|
918
918
|
}
|
|
919
919
|
|
|
920
|
+
/* Fullscreen Mode */
|
|
921
|
+
body.marp-fullscreen {
|
|
922
|
+
overflow: hidden;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
body.marp-fullscreen .sidebar,
|
|
926
|
+
body.marp-fullscreen .resize-handle,
|
|
927
|
+
body.marp-fullscreen .toolbar,
|
|
928
|
+
body.marp-fullscreen .tab-bar {
|
|
929
|
+
display: none !important;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
body.marp-fullscreen .container {
|
|
933
|
+
display: block;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
body.marp-fullscreen .main {
|
|
937
|
+
position: fixed;
|
|
938
|
+
top: 0;
|
|
939
|
+
left: 0;
|
|
940
|
+
right: 0;
|
|
941
|
+
bottom: 0;
|
|
942
|
+
z-index: 9999;
|
|
943
|
+
background: #0f172a;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
body.marp-fullscreen .content {
|
|
947
|
+
height: 100vh;
|
|
948
|
+
padding: 0;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
body.marp-fullscreen .marp-nav {
|
|
952
|
+
bottom: 32px;
|
|
953
|
+
right: 32px;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
body.marp-fullscreen .marpit {
|
|
957
|
+
padding: 0;
|
|
958
|
+
height: 100vh;
|
|
959
|
+
display: flex;
|
|
960
|
+
align-items: center;
|
|
961
|
+
justify-content: center;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
body.marp-fullscreen .marpit > svg[data-marpit-svg] {
|
|
965
|
+
max-height: 95vh;
|
|
966
|
+
max-width: 95vw;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
.marp-fullscreen-btn {
|
|
970
|
+
margin-left: 4px;
|
|
971
|
+
}
|
|
972
|
+
|
|
920
973
|
/* Print styles for Marp */
|
|
921
974
|
@media print {
|
|
922
975
|
.marp-nav { display: none !important; }
|