@@ -7,10 +7,9 @@ import { RenderResult } from "./types";
77import { getTypstBinaryPath } from "./cli-installer" ;
88import { DEFAULT_VERSION } from "./config" ;
99
10- function mergeSVGsVertically ( svgPaths : string [ ] ) : string {
10+ function mergeSVGsVertically ( svgPaths : string [ ] , padding : number = 10 ) : string {
1111 const viewBoxRegex = / < s v g [ ^ > ] * v i e w B o x = " ( [ ^ " ] * ) " [ ^ > ] * > / ;
1212
13- // Check total file size before reading any files
1413 let totalSize = 0 ;
1514 for ( const path of svgPaths ) {
1615 const stats = statSync ( path ) ;
@@ -35,25 +34,33 @@ function mergeSVGsVertically(svgPaths: string[]): string {
3534
3635 const contentStart = svg . indexOf ( ">" ) + 1 ;
3736 const contentEnd = svg . lastIndexOf ( "</svg>" ) ;
38- const content = svg . slice ( contentStart , contentEnd ) ;
39- contents . push ( content ) ;
37+ contents . push ( svg . slice ( contentStart , contentEnd ) ) ;
4038 }
4139 } ) ;
4240
4341 const maxWidth = Math . max ( ...viewBoxes . map ( ( vb ) => vb . w ) ) ;
44- const totalHeight = viewBoxes . reduce ( ( sum , vb ) => sum + vb . h , 0 ) ;
45- const mergedViewBox = `0 0 ${ maxWidth } ${ totalHeight } ` ;
42+ const totalHeight =
43+ viewBoxes . reduce ( ( sum , vb ) => sum + vb . h , 0 ) +
44+ padding * ( viewBoxes . length - 1 ) ;
4645
4746 let yOffset = 0 ;
48- const mergedContent = contents
47+ const groups = contents
4948 . map ( ( content , i ) => {
50- const result = `<g transform="translate(0, ${ yOffset } )">${ content } </g>` ;
51- yOffset += viewBoxes [ i ] . h ;
52- return result ;
49+ const vb = viewBoxes [ i ] ;
50+ const group = `<g transform="translate(0,${ yOffset } )"><rect width="${ vb . w } " height="${ vb . h } " fill="white"/><g clip-path="url(#c${ i } )">${ content } </g></g>` ;
51+ yOffset += vb . h + padding ;
52+ return group ;
5353 } )
5454 . join ( "" ) ;
5555
56- return `<svg style="overflow: visible;" class="typst-doc" viewBox="${ mergedViewBox } " width="${ maxWidth } " height="${ totalHeight } " data-width="${ maxWidth } " data-height="${ totalHeight } " xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:h5="http://www.w3.org/1999/xhtml">${ mergedContent } </svg>` ;
56+ const clipDefs = viewBoxes
57+ . map (
58+ ( vb , i ) =>
59+ `<clipPath id="c${ i } "><rect width="${ vb . w } " height="${ vb . h } "/></clipPath>`
60+ )
61+ . join ( "" ) ;
62+
63+ return `<svg class="typst-doc" viewBox="0 0 ${ maxWidth } ${ totalHeight } " width="${ maxWidth } " height="${ totalHeight } " xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs>${ clipDefs } </defs>${ groups } </svg>` ;
5764}
5865
5966export async function renderTypst (
0 commit comments