@joaodotwork/md-2-pdf 1.3.0 → 1.4.0
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/README.md +3 -0
- package/filters/code-break.lua +40 -0
- package/md_to_pdf.py +14 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -20,6 +20,9 @@ Most markdown-to-pdf converters struggle with diagrams or produce poorly formatt
|
|
|
20
20
|
- Interactive, blue clickable links.
|
|
21
21
|
- Automatic widow/orphan protection (keeps headers with content).
|
|
22
22
|
- Wide tables wrap to fit the page — pipe tables with short separator dashes (`|---|---|`) get equal column widths and wrapping cells instead of overflowing.
|
|
23
|
+
- Long inline code (filenames, identifiers) wraps cleanly inside narrow table cells, breaking at `-`, `_`, `.`, and `/` instead of colliding with the next column.
|
|
24
|
+
- Code blocks wrap soft-overflow lines instead of running off the page (via `fvextra` `breaklines`), with a `↪` continuation marker.
|
|
25
|
+
- Unicode-safe monospace font (DejaVu Sans Mono) — box-drawing characters (`│ └── ├──`) and other non-ASCII glyphs render correctly in code blocks.
|
|
23
26
|
- Customizable margins and geometry.
|
|
24
27
|
- **Multi-Engine Support:** Automatically detects and uses the best available PDF engine (`xelatex`, `pdflatex`, `weasyprint`, or `wkhtmltopdf`).
|
|
25
28
|
- **Batch Processing:** Convert single files or entire directories with one command.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
-- Make long inline code spans (`like-this-filename.json`, `vngrd_woodcut_v3`)
|
|
2
|
+
-- wrappable inside narrow table cells.
|
|
3
|
+
--
|
|
4
|
+
-- Pandoc emits inline code as \texttt{...}, which has no break opportunities
|
|
5
|
+
-- inside the word (no spaces, hyphenchar disabled). Long identifiers then
|
|
6
|
+
-- overflow their column. We insert a zero-width \allowbreak after each
|
|
7
|
+
-- hyphen / underscore / dot / slash, so TeX can break the line there if it
|
|
8
|
+
-- needs to. The visible character stays put.
|
|
9
|
+
|
|
10
|
+
local break_after = { ['-'] = true, ['_'] = true, ['.'] = true, ['/'] = true }
|
|
11
|
+
|
|
12
|
+
local function latex_escape(c)
|
|
13
|
+
if c == '\\' then return '\\textbackslash{}'
|
|
14
|
+
elseif c == '{' then return '\\{'
|
|
15
|
+
elseif c == '}' then return '\\}'
|
|
16
|
+
elseif c == '$' then return '\\$'
|
|
17
|
+
elseif c == '&' then return '\\&'
|
|
18
|
+
elseif c == '%' then return '\\%'
|
|
19
|
+
elseif c == '#' then return '\\#'
|
|
20
|
+
elseif c == '_' then return '\\_'
|
|
21
|
+
elseif c == '^' then return '\\textasciicircum{}'
|
|
22
|
+
elseif c == '~' then return '\\textasciitilde{}'
|
|
23
|
+
else return c
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
function Code(elem)
|
|
28
|
+
if FORMAT ~= 'latex' and FORMAT ~= 'pdf' then return nil end
|
|
29
|
+
local text = elem.text
|
|
30
|
+
if not text:find('[-_./]') then return nil end
|
|
31
|
+
local out = {}
|
|
32
|
+
for i = 1, #text do
|
|
33
|
+
local c = text:sub(i, i)
|
|
34
|
+
out[#out + 1] = latex_escape(c)
|
|
35
|
+
if break_after[c] then
|
|
36
|
+
out[#out + 1] = '\\allowbreak{}'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
return pandoc.RawInline('latex', '\\texttt{' .. table.concat(out) .. '}')
|
|
40
|
+
end
|
package/md_to_pdf.py
CHANGED
|
@@ -170,6 +170,7 @@ def convert_markdown_to_pdf(
|
|
|
170
170
|
# Locate bundled Lua filters
|
|
171
171
|
script_dir = Path(__file__).resolve().parent
|
|
172
172
|
table_fit_filter = script_dir / 'filters' / 'table-fit.lua'
|
|
173
|
+
code_break_filter = script_dir / 'filters' / 'code-break.lua'
|
|
173
174
|
|
|
174
175
|
# Convert to PDF using pandoc
|
|
175
176
|
cmd = [
|
|
@@ -179,6 +180,7 @@ def convert_markdown_to_pdf(
|
|
|
179
180
|
'--from=gfm',
|
|
180
181
|
f'--pdf-engine={pdf_engine}',
|
|
181
182
|
f'--lua-filter={table_fit_filter}',
|
|
183
|
+
f'--lua-filter={code_break_filter}',
|
|
182
184
|
'-V', 'geometry:top=0.75in',
|
|
183
185
|
'-V', 'geometry:bottom=1in',
|
|
184
186
|
'-V', 'geometry:left=0.75in',
|
|
@@ -189,8 +191,19 @@ def convert_markdown_to_pdf(
|
|
|
189
191
|
'-V', 'colorlinks=true',
|
|
190
192
|
'-V', 'linkcolor=blue',
|
|
191
193
|
'-V', 'urlcolor=blue',
|
|
192
|
-
'-V', 'header-includes=\\renewcommand{\\rule}[2]{\\vspace{0.5em}} \\widowpenalty=10000 \\clubpenalty=10000 \\brokenpenalty=10000 \\setlength{\\emergencystretch}{3em} \\usepackage{newunicodechar} \\newunicodechar{·}{\\textperiodcentered\\allowbreak} \\newunicodechar{•}{\\textbullet\\allowbreak}'
|
|
194
|
+
'-V', 'header-includes=\\renewcommand{\\rule}[2]{\\vspace{0.5em}} \\widowpenalty=10000 \\clubpenalty=10000 \\brokenpenalty=10000 \\setlength{\\emergencystretch}{3em} \\usepackage{newunicodechar} \\newunicodechar{·}{\\textperiodcentered\\allowbreak} \\newunicodechar{•}{\\textbullet\\allowbreak} \\usepackage{fvextra} \\DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines,commandchars=\\\\\\{\\}} \\DefineVerbatimEnvironment{verbatim}{Verbatim}{breaklines}'
|
|
193
195
|
]
|
|
196
|
+
|
|
197
|
+
# Use a Unicode-rich monospace font when the engine supports it (fontspec).
|
|
198
|
+
# DejaVu Sans Mono ships with TeX Live and covers box-drawing characters
|
|
199
|
+
# (│ └── ├──), so ASCII-art trees in code blocks render correctly. Pass the
|
|
200
|
+
# font as a .ttf filename so fontspec resolves it via kpsewhich, which
|
|
201
|
+
# works regardless of fontconfig setup or TeX Live install path.
|
|
202
|
+
if pdf_engine in ('xelatex', 'lualatex'):
|
|
203
|
+
cmd.extend([
|
|
204
|
+
'-V', 'monofont=DejaVuSansMono.ttf',
|
|
205
|
+
'-V', 'monofontoptions=BoldFont=DejaVuSansMono-Bold.ttf, ItalicFont=DejaVuSansMono-Oblique.ttf, BoldItalicFont=DejaVuSansMono-BoldOblique.ttf',
|
|
206
|
+
])
|
|
194
207
|
|
|
195
208
|
try:
|
|
196
209
|
subprocess.run(cmd, check=True, capture_output=True)
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joaodotwork/md-2-pdf",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Convert markdown files to PDF with mermaid diagram support",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"md-2-pdf": "
|
|
7
|
+
"md-2-pdf": "bin/index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1"
|