vimd 0.5.6 → 0.5.8

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.
@@ -516,6 +516,100 @@ body a:focus {
516
516
  outline-offset: -2px;
517
517
  }
518
518
 
519
+ /* LaTeX metadata styles */
520
+ .vimd-authors {
521
+ font-size: 1.1em;
522
+ margin-bottom: 0.5em;
523
+ color: #1f2328;
524
+ }
525
+
526
+ .vimd-authors sup {
527
+ color: #0969da;
528
+ font-weight: bold;
529
+ }
530
+
531
+ .vimd-affiliations {
532
+ font-size: 0.9em;
533
+ color: #656d76;
534
+ margin-bottom: 0.5em;
535
+ }
536
+
537
+ .vimd-affiliation {
538
+ margin-bottom: 0.25em;
539
+ }
540
+
541
+ .vimd-affiliation sup {
542
+ color: #0969da;
543
+ font-weight: bold;
544
+ margin-right: 0.25em;
545
+ }
546
+
547
+ .vimd-corresponding {
548
+ font-size: 0.9em;
549
+ color: #656d76;
550
+ font-style: italic;
551
+ margin-bottom: 1.5em;
552
+ padding-bottom: 1em;
553
+ border-bottom: 1px solid #d0d7de;
554
+ }
555
+
556
+ .vimd-corresponding a {
557
+ color: #0969da;
558
+ }
559
+
560
+ /* LaTeX document title */
561
+ .vimd-title {
562
+ font-size: 1.8em;
563
+ font-weight: bold;
564
+ text-align: center;
565
+ margin-bottom: 0.5em;
566
+ color: #1f2328;
567
+ }
568
+
569
+ /* Key Points box */
570
+ .vimd-keypoints {
571
+ background-color: #f6f8fa;
572
+ border: 1px solid #d0d7de;
573
+ border-radius: 6px;
574
+ padding: 1em;
575
+ margin: 1em 0;
576
+ }
577
+
578
+ .vimd-keypoints h2 {
579
+ font-size: 1.1em;
580
+ margin-top: 0;
581
+ margin-bottom: 0.5em;
582
+ color: #1f2328;
583
+ }
584
+
585
+ .vimd-keypoints ul {
586
+ margin: 0;
587
+ padding-left: 1.5em;
588
+ }
589
+
590
+ .vimd-keypoints li {
591
+ margin-bottom: 0.3em;
592
+ }
593
+
594
+ /* Abstract section */
595
+ .vimd-abstract {
596
+ border-left: 4px solid #0969da;
597
+ padding-left: 1em;
598
+ margin: 1em 0;
599
+ }
600
+
601
+ .vimd-abstract h2 {
602
+ font-size: 1.1em;
603
+ margin-top: 0;
604
+ margin-bottom: 0.5em;
605
+ color: #1f2328;
606
+ }
607
+
608
+ .vimd-abstract p {
609
+ margin: 0;
610
+ text-align: justify;
611
+ }
612
+
519
613
  /* Responsive */
520
614
  @media (max-width: 768px) {
521
615
  body {
@@ -513,6 +513,102 @@ body i {
513
513
  }
514
514
  }
515
515
 
516
+ /* ============================================
517
+ LaTeX Metadata
518
+ ============================================ */
519
+ .vimd-authors {
520
+ font-size: 1.1em;
521
+ margin-bottom: 0.5em;
522
+ color: #222;
523
+ }
524
+
525
+ .vimd-authors sup {
526
+ color: #555;
527
+ font-weight: bold;
528
+ }
529
+
530
+ .vimd-affiliations {
531
+ font-size: 0.9em;
532
+ color: #666;
533
+ margin-bottom: 0.5em;
534
+ }
535
+
536
+ .vimd-affiliation {
537
+ margin-bottom: 0.25em;
538
+ }
539
+
540
+ .vimd-affiliation sup {
541
+ color: #555;
542
+ font-weight: bold;
543
+ margin-right: 0.25em;
544
+ }
545
+
546
+ .vimd-corresponding {
547
+ font-size: 0.9em;
548
+ color: #666;
549
+ font-style: italic;
550
+ margin-bottom: 1.5em;
551
+ padding-bottom: 1em;
552
+ border-bottom: 1px solid #ddd;
553
+ }
554
+
555
+ .vimd-corresponding a {
556
+ color: #333;
557
+ }
558
+
559
+ /* LaTeX document title */
560
+ .vimd-title {
561
+ font-size: 1.8em;
562
+ font-weight: bold;
563
+ text-align: center;
564
+ margin-bottom: 0.5em;
565
+ color: #333;
566
+ }
567
+
568
+ /* Key Points box */
569
+ .vimd-keypoints {
570
+ background-color: #fafafa;
571
+ border: 1px solid #ddd;
572
+ border-radius: 4px;
573
+ padding: 1em;
574
+ margin: 1em 0;
575
+ }
576
+
577
+ .vimd-keypoints h2 {
578
+ font-size: 1.1em;
579
+ margin-top: 0;
580
+ margin-bottom: 0.5em;
581
+ color: #333;
582
+ }
583
+
584
+ .vimd-keypoints ul {
585
+ margin: 0;
586
+ padding-left: 1.5em;
587
+ }
588
+
589
+ .vimd-keypoints li {
590
+ margin-bottom: 0.3em;
591
+ }
592
+
593
+ /* Abstract section */
594
+ .vimd-abstract {
595
+ border-left: 3px solid #333;
596
+ padding-left: 1em;
597
+ margin: 1em 0;
598
+ }
599
+
600
+ .vimd-abstract h2 {
601
+ font-size: 1.1em;
602
+ margin-top: 0;
603
+ margin-bottom: 0.5em;
604
+ color: #333;
605
+ }
606
+
607
+ .vimd-abstract p {
608
+ margin: 0;
609
+ text-align: justify;
610
+ }
611
+
516
612
  /* ============================================
517
613
  Responsive
518
614
  ============================================ */
@@ -613,6 +613,102 @@ body i {
613
613
  }
614
614
  }
615
615
 
616
+ /* ============================================
617
+ LaTeX Metadata
618
+ ============================================ */
619
+ .vimd-authors {
620
+ font-size: 1.1em;
621
+ margin-bottom: 0.5em;
622
+ color: #d4d4d4;
623
+ }
624
+
625
+ .vimd-authors sup {
626
+ color: #4ec9b0;
627
+ font-weight: bold;
628
+ }
629
+
630
+ .vimd-affiliations {
631
+ font-size: 0.9em;
632
+ color: #9cdcfe;
633
+ margin-bottom: 0.5em;
634
+ }
635
+
636
+ .vimd-affiliation {
637
+ margin-bottom: 0.25em;
638
+ }
639
+
640
+ .vimd-affiliation sup {
641
+ color: #4ec9b0;
642
+ font-weight: bold;
643
+ margin-right: 0.25em;
644
+ }
645
+
646
+ .vimd-corresponding {
647
+ font-size: 0.9em;
648
+ color: #9cdcfe;
649
+ font-style: italic;
650
+ margin-bottom: 1.5em;
651
+ padding-bottom: 1em;
652
+ border-bottom: 1px solid #3c3c3c;
653
+ }
654
+
655
+ .vimd-corresponding a {
656
+ color: #569cd6;
657
+ }
658
+
659
+ /* LaTeX document title */
660
+ .vimd-title {
661
+ font-size: 1.8em;
662
+ font-weight: bold;
663
+ text-align: center;
664
+ margin-bottom: 0.5em;
665
+ color: #d4d4d4;
666
+ }
667
+
668
+ /* Key Points box */
669
+ .vimd-keypoints {
670
+ background-color: #252526;
671
+ border: 1px solid #3c3c3c;
672
+ border-radius: 4px;
673
+ padding: 1em;
674
+ margin: 1em 0;
675
+ }
676
+
677
+ .vimd-keypoints h2 {
678
+ font-size: 1.1em;
679
+ margin-top: 0;
680
+ margin-bottom: 0.5em;
681
+ color: #d4d4d4;
682
+ }
683
+
684
+ .vimd-keypoints ul {
685
+ margin: 0;
686
+ padding-left: 1.5em;
687
+ }
688
+
689
+ .vimd-keypoints li {
690
+ margin-bottom: 0.3em;
691
+ }
692
+
693
+ /* Abstract section */
694
+ .vimd-abstract {
695
+ border-left: 4px solid #569cd6;
696
+ padding-left: 1em;
697
+ margin: 1em 0;
698
+ }
699
+
700
+ .vimd-abstract h2 {
701
+ font-size: 1.1em;
702
+ margin-top: 0;
703
+ margin-bottom: 0.5em;
704
+ color: #d4d4d4;
705
+ }
706
+
707
+ .vimd-abstract p {
708
+ margin: 0;
709
+ text-align: justify;
710
+ }
711
+
616
712
  /* ============================================
617
713
  Responsive
618
714
  ============================================ */
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/utils/session-manager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAkC;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAGnC;IAEF;;OAEG;WACU,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;IAWlD;;OAEG;WACU,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhE;;OAEG;WACU,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAKlE;;OAEG;WACU,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7D;;OAEG;WACU,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvD;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAS3C;;OAEG;WACU,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBvD;;OAEG;WACU,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IA0BjD;;OAEG;WACU,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAmCvE;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYtD;;OAEG;WACU,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAcnE"}
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/utils/session-manager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAkC;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAGnC;IAEF;;OAEG;WACU,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;IAWlD;;OAEG;WACU,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhE;;OAEG;WACU,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAKlE;;OAEG;WACU,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7D;;OAEG;WACU,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvD;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAS3C;;OAEG;WACU,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBvD;;OAEG;WACU,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IA2BjD;;OAEG;WACU,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAmCvE;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYtD;;OAEG;WACU,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAcnE"}
@@ -87,8 +87,9 @@ export class SessionManager {
87
87
  for (const [port, session] of Object.entries(sessions)) {
88
88
  if (!this.isProcessAlive(session.pid)) {
89
89
  // Process is dead, clean up HTML if exists
90
+ // Skip if htmlPath is empty (single file / folder mode)
90
91
  try {
91
- if (await fs.pathExists(session.htmlPath)) {
92
+ if (session.htmlPath && await fs.pathExists(session.htmlPath)) {
92
93
  await fs.remove(session.htmlPath);
93
94
  }
94
95
  }
@@ -122,9 +123,9 @@ export class SessionManager {
122
123
  if (this.isProcessAlive(session.pid)) {
123
124
  result.killed = await this.killProcess(session.pid);
124
125
  }
125
- // Remove HTML file
126
+ // Remove HTML file (skip if htmlPath is empty - single file / folder mode)
126
127
  try {
127
- if (await fs.pathExists(session.htmlPath)) {
128
+ if (session.htmlPath && await fs.pathExists(session.htmlPath)) {
128
129
  await fs.remove(session.htmlPath);
129
130
  result.htmlRemoved = true;
130
131
  }
@@ -0,0 +1,135 @@
1
+ -- filters/latex-metadata.lua
2
+ -- Extract metadata from AGU journal format LaTeX and insert as HTML at document start
3
+
4
+ local extracted = {
5
+ title = nil,
6
+ authors = nil,
7
+ affiliations = {},
8
+ corresponding = nil,
9
+ keypoints = {},
10
+ abstract = nil
11
+ }
12
+
13
+ -- Convert \affil{n} to <sup>n</sup>
14
+ local function process_affil(text)
15
+ return text:gsub('\\affil{(%d+)}', '<sup>%1</sup>')
16
+ end
17
+
18
+ -- Extract title and abstract from Meta (pandoc processes these as metadata)
19
+ function Meta(meta)
20
+ if meta.title then
21
+ extracted.title = pandoc.utils.stringify(meta.title)
22
+ end
23
+ if meta.abstract then
24
+ extracted.abstract = pandoc.utils.stringify(meta.abstract)
25
+ end
26
+ return meta
27
+ end
28
+
29
+ function RawBlock(el)
30
+ if el.format:match('latex') or el.format:match('tex') then
31
+ local text = el.text
32
+
33
+ -- Extract \authors{...}
34
+ local authors = text:match('\\authors%s*{(.+)}')
35
+ if authors then
36
+ extracted.authors = process_affil(authors)
37
+ end
38
+
39
+ -- Extract \affiliation{n}{...}
40
+ local affil_num, affil_text = text:match('\\affiliation%s*{(%d+)}%s*{(.+)}')
41
+ if affil_num and affil_text then
42
+ extracted.affiliations[tonumber(affil_num)] = affil_text
43
+ end
44
+
45
+ -- Extract \correspondingauthor{name}{email}
46
+ local corr_name, corr_email = text:match('\\correspondingauthor%s*{([^}]+)}%s*{([^}]+)}')
47
+ if corr_name and corr_email then
48
+ extracted.corresponding = { name = corr_name, email = corr_email }
49
+ end
50
+
51
+ -- Extract \begin{keypoints}...\end{keypoints}
52
+ local keypoints_content = text:match('\\begin{keypoints}(.-)\\end{keypoints}')
53
+ if keypoints_content then
54
+ -- Extract each \item content
55
+ for item in keypoints_content:gmatch('\\item%s*([^\n]+)') do
56
+ -- Trim whitespace
57
+ item = item:gsub('^%s*', ''):gsub('%s*$', '')
58
+ if item ~= '' then
59
+ table.insert(extracted.keypoints, item)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ return el
65
+ end
66
+
67
+ function Pandoc(doc)
68
+ local header_blocks = {}
69
+
70
+ -- 1. Title
71
+ if extracted.title then
72
+ table.insert(header_blocks, pandoc.RawBlock('html',
73
+ '<h1 class="vimd-title">' .. extracted.title .. '</h1>'))
74
+ end
75
+
76
+ -- 2. Authors
77
+ if extracted.authors then
78
+ table.insert(header_blocks, pandoc.RawBlock('html',
79
+ '<div class="vimd-authors">' .. extracted.authors .. '</div>'))
80
+ end
81
+
82
+ -- 3. Affiliations
83
+ if next(extracted.affiliations) then
84
+ local affil_html = '<div class="vimd-affiliations">'
85
+ -- Sort by affiliation number
86
+ local sorted_keys = {}
87
+ for k in pairs(extracted.affiliations) do
88
+ table.insert(sorted_keys, k)
89
+ end
90
+ table.sort(sorted_keys)
91
+ for _, i in ipairs(sorted_keys) do
92
+ local affil = extracted.affiliations[i]
93
+ affil_html = affil_html .. '<div class="vimd-affiliation"><sup>' .. i .. '</sup> ' .. affil .. '</div>'
94
+ end
95
+ affil_html = affil_html .. '</div>'
96
+ table.insert(header_blocks, pandoc.RawBlock('html', affil_html))
97
+ end
98
+
99
+ -- 4. Corresponding author
100
+ if extracted.corresponding then
101
+ local corr_html = '<div class="vimd-corresponding">Corresponding author: '
102
+ .. extracted.corresponding.name .. ' (<a href="mailto:' .. extracted.corresponding.email .. '">'
103
+ .. extracted.corresponding.email .. '</a>)</div>'
104
+ table.insert(header_blocks, pandoc.RawBlock('html', corr_html))
105
+ end
106
+
107
+ -- 5. Key Points
108
+ if #extracted.keypoints > 0 then
109
+ local kp_html = '<div class="vimd-keypoints"><h2>Key Points</h2><ul>'
110
+ for _, item in ipairs(extracted.keypoints) do
111
+ kp_html = kp_html .. '<li>' .. item .. '</li>'
112
+ end
113
+ kp_html = kp_html .. '</ul></div>'
114
+ table.insert(header_blocks, pandoc.RawBlock('html', kp_html))
115
+ end
116
+
117
+ -- 6. Abstract
118
+ if extracted.abstract then
119
+ table.insert(header_blocks, pandoc.RawBlock('html',
120
+ '<div class="vimd-abstract"><h2>Abstract</h2><p>' .. extracted.abstract .. '</p></div>'))
121
+ end
122
+
123
+ -- Insert at document start (in reverse order to maintain order)
124
+ for i = #header_blocks, 1, -1 do
125
+ table.insert(doc.blocks, 1, header_blocks[i])
126
+ end
127
+
128
+ return doc
129
+ end
130
+
131
+ return {
132
+ { Meta = Meta },
133
+ { RawBlock = RawBlock },
134
+ { Pandoc = Pandoc }
135
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vimd",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "description": "Real-time Markdown preview tool with pandoc (view markdown)",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -30,6 +30,7 @@
30
30
  "files": [
31
31
  "dist",
32
32
  "templates",
33
+ "filters",
33
34
  "README.md",
34
35
  "LICENSE"
35
36
  ],
@@ -29,11 +29,15 @@
29
29
  </style>
30
30
  <script>
31
31
  MathJax = {
32
- loader: {load: ['[tex]/bussproofs', '[tex]/ams', '[tex]/physics']},
32
+ loader: {load: ['[tex]/bussproofs', '[tex]/ams', '[tex]/physics', '[tex]/boldsymbol']},
33
33
  tex: {
34
- packages: {'[+]': ['bussproofs', 'ams', 'physics']},
34
+ packages: {'[+]': ['bussproofs', 'ams', 'physics', 'boldsymbol']},
35
35
  inlineMath: [['$', '$'], ['\\(', '\\)']],
36
- displayMath: [['$$', '$$'], ['\\[', '\\]']]
36
+ displayMath: [['$$', '$$'], ['\\[', '\\]']],
37
+ tags: 'ams',
38
+ macros: {
39
+ bm: ['\\boldsymbol{#1}', 1]
40
+ }
37
41
  }
38
42
  };
39
43
  </script>
@@ -27,11 +27,15 @@
27
27
  </style>
28
28
  <script>
29
29
  MathJax = {
30
- loader: {load: ['[tex]/bussproofs', '[tex]/ams', '[tex]/physics']},
30
+ loader: {load: ['[tex]/bussproofs', '[tex]/ams', '[tex]/physics', '[tex]/boldsymbol']},
31
31
  tex: {
32
- packages: {'[+]': ['bussproofs', 'ams', 'physics']},
32
+ packages: {'[+]': ['bussproofs', 'ams', 'physics', 'boldsymbol']},
33
33
  inlineMath: [['$', '$'], ['\\(', '\\)']],
34
- displayMath: [['$$', '$$'], ['\\[', '\\]']]
34
+ displayMath: [['$$', '$$'], ['\\[', '\\]']],
35
+ tags: 'ams',
36
+ macros: {
37
+ bm: ['\\boldsymbol{#1}', 1]
38
+ }
35
39
  }
36
40
  };
37
41
  </script>