Fix PDF diagram text rendering with format-optimized generation
Problem: SVG diagrams had missing text in PDFs due to Inkscape conversion issues with foreignObject elements used by Mermaid for HTML text rendering. Solution: Implement format-specific optimal generation: - HTML: SVG files for perfect vector scaling and text rendering - PDF: High-resolution PNG files (3x scale) for sharp images with readable text Changes: - Generate SVG for HTML output using standard mmdc command - Generate PNG for PDF output using mmdc with --scale 3 for high resolution - Remove SVG LaTeX package dependency and Inkscape requirement - Update documentation to reflect the dual-format approach Results: - HTML: Crisp, scalable vector diagrams with perfect text - PDF: Sharp, high-resolution raster diagrams with clear text - No external dependencies beyond mermaid-cli 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
4aab281f4b
commit
7f1f1aeeb0
@ -42,7 +42,7 @@ cabal repl
|
|||||||
The application consists of:
|
The application consists of:
|
||||||
|
|
||||||
1. **Main.hs** (app/Main.hs:1-69) - Entry point and core logic
|
1. **Main.hs** (app/Main.hs:1-69) - Entry point and core logic
|
||||||
- `processMermaid` (app/Main.hs:21-34) - Transforms Mermaid code blocks into SVG images
|
- `processMermaidBlock` (app/Main.hs:54-79) - Transforms Mermaid code blocks into images (SVG for HTML, high-res PNG for PDF)
|
||||||
- `transformDoc` (app/Main.hs:36-37) - Walks the Pandoc AST to process all blocks
|
- `transformDoc` (app/Main.hs:36-37) - Walks the Pandoc AST to process all blocks
|
||||||
- `compileToPDF` (app/Main.hs:47-58) - Converts Markdown to PDF using LaTeX
|
- `compileToPDF` (app/Main.hs:47-58) - Converts Markdown to PDF using LaTeX
|
||||||
- `compileToHTML` (app/Main.hs:60-68) - Converts Markdown to HTML
|
- `compileToHTML` (app/Main.hs:60-68) - Converts Markdown to HTML
|
||||||
@ -50,7 +50,7 @@ The application consists of:
|
|||||||
The tool uses Pandoc's AST transformation capabilities to:
|
The tool uses Pandoc's AST transformation capabilities to:
|
||||||
1. Parse Markdown input
|
1. Parse Markdown input
|
||||||
2. Find Mermaid code blocks
|
2. Find Mermaid code blocks
|
||||||
3. Generate SVG files using mermaid-cli (mmdc)
|
3. Generate image files using mermaid-cli (mmdc) - SVG for HTML, high-resolution PNG for PDF
|
||||||
4. Replace code blocks with image references
|
4. Replace code blocks with image references
|
||||||
5. Output final PDF/HTML
|
5. Output final PDF/HTML
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ The tool uses Pandoc's AST transformation capabilities to:
|
|||||||
External requirements:
|
External requirements:
|
||||||
- GHC 9.12.2 and Cabal 3.16 (install via ghcup)
|
- GHC 9.12.2 and Cabal 3.16 (install via ghcup)
|
||||||
- Pandoc library
|
- Pandoc library
|
||||||
- TeX Live (for PDF generation via pdflatex)
|
- TeX Live (for PDF generation via XeLaTeX)
|
||||||
- Mermaid CLI (`npm install -g @mermaid-js/mermaid-cli`)
|
- Mermaid CLI (`npm install -g @mermaid-js/mermaid-cli`)
|
||||||
|
|
||||||
To install GHC and Cabal:
|
To install GHC and Cabal:
|
||||||
|
18
app/Main.hs
18
app/Main.hs
@ -58,19 +58,23 @@ processMermaidBlock (SourceDir sourceDir) (OutputPath outputPath) (CodeBlock (id
|
|||||||
let DiagramId diagId = generateDiagramId id' contents
|
let DiagramId diagId = generateDiagramId id' contents
|
||||||
diagIdStr = T.unpack diagId
|
diagIdStr = T.unpack diagId
|
||||||
mmdFile = sourceDir </> diagIdStr <> ".mmd"
|
mmdFile = sourceDir </> diagIdStr <> ".mmd"
|
||||||
pngFile = sourceDir </> diagIdStr <> ".png"
|
-- Use SVG for HTML (scalable), high-res PNG for PDF (text compatibility)
|
||||||
-- Determine the correct image path based on output format
|
(outputFile, imagePath) = if isHTMLOutput outputPath
|
||||||
imagePath = if isHTMLOutput outputPath
|
then let svgFile = sourceDir </> diagIdStr <> ".svg"
|
||||||
then takeFileName pngFile -- Just filename for HTML
|
in (svgFile, takeFileName svgFile)
|
||||||
else pngFile -- Full path for PDF/LaTeX
|
else let pngFile = sourceDir </> diagIdStr <> ".png"
|
||||||
|
in (pngFile, pngFile)
|
||||||
|
|
||||||
-- Use bracket to ensure cleanup of temporary mermaid file
|
-- Use bracket to ensure cleanup of temporary mermaid file
|
||||||
bracket
|
bracket
|
||||||
(TIO.writeFile mmdFile contents >> return mmdFile)
|
(TIO.writeFile mmdFile contents >> return mmdFile)
|
||||||
(\file -> removeFile file `catch` \(_ :: SomeException) -> return ())
|
(\file -> removeFile file `catch` \(_ :: SomeException) -> return ())
|
||||||
(\_ -> do
|
(\_ -> do
|
||||||
void $ callProcess mermaidCommand ["-i", mmdFile, "-o", pngFile]
|
-- Generate with appropriate format and quality for output type
|
||||||
putStrLn $ successEmoji <> " Generated " <> pngFile
|
if isHTMLOutput outputPath
|
||||||
|
then void $ callProcess mermaidCommand ["-i", mmdFile, "-o", outputFile]
|
||||||
|
else void $ callProcess mermaidCommand ["-i", mmdFile, "-o", outputFile, "--scale", "3"]
|
||||||
|
putStrLn $ successEmoji <> " Generated " <> outputFile
|
||||||
return $ Para [Image nullAttr [] (T.pack imagePath, "Mermaid diagram")])
|
return $ Para [Image nullAttr [] (T.pack imagePath, "Mermaid diagram")])
|
||||||
processMermaidBlock _ _ block = return block
|
processMermaidBlock _ _ block = return block
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user