@@ -14,6 +14,9 @@ import GithubSlugger from "github-slugger";
1414import yaml from "js-yaml" ;
1515import { visitParents } from "unist-util-visit-parents" ;
1616import remarkMdxEmbeddedHast from "./lib/mdast-embedded-hast.mjs" ;
17+ import rehypeParse from "rehype-parse" ;
18+ import fs from 'node:fs/promises' ;
19+ import { optimize } from 'svgo' ;
1720import toVfile from "to-vfile" ;
1821const { read, write } = toVfile ;
1922
@@ -29,6 +32,8 @@ const formatErrorPath = (path, line, column) => {
2932 : `${ path } :${ line } :${ column } ` ;
3033} ;
3134
35+ const imageExts = [ ".png" , ".svg" , ".jpg" , ".jpeg" , ".gif" ] ;
36+
3237( async ( ) => {
3338 if ( ! process . argv [ 2 ] ) {
3439 console . log ( `usage:
@@ -69,7 +74,7 @@ function cleanup() {
6974 const originalRE =
7075 / < s p a n d a t a - o r i g i n a l - p a t h = ' (?< originalPath > .+ ?) : (?< originalStartLine > \d + ) ' > < \/ s p a n > / ;
7176 const docsUrl = "https://www.enterprisedb.com/docs" ;
72- return ( tree , file ) => {
77+ return async ( tree , file ) => {
7378 const docsLocations = / p r o d u c t _ d o c s \/ d o c s | a d v o c a c y _ d o c s / ;
7479 const thisProductPath = path . dirname ( file . path ) . split ( docsLocations ) [ 1 ] ;
7580 const isVersioned = file . path . includes ( "product_docs/" )
@@ -92,6 +97,10 @@ function cleanup() {
9297 const slugger = new GithubSlugger ( ) ;
9398
9499 const getSlugForOrigPathAndSlug = ( origPath , origSlug ) => {
100+ const ext = path . posix . extname ( origPath ) ;
101+ const isImageUrl = imageExts . includes ( ext ) ;
102+ if ( isImageUrl ) return "" ;
103+
95104 const normalizedPath = origPath
96105 . replace ( / \/ ? $ / , "" )
97106 . replace ( / \. m d x ? $ / , "" ) ;
@@ -144,7 +153,7 @@ function cleanup() {
144153
145154 visitParents (
146155 tree ,
147- [ "jsx-hast" , "element" , "link" , "heading" , "code" , "admonition" , "table" ] ,
156+ [ "jsx-hast" , "element" , "link" , "image" , " heading", "code" , "admonition" , "table" ] ,
148157 ( node , ancestors ) => {
149158 if ( node . type === "jsx-hast" ) {
150159 let { originalPath, originalStartLine } =
@@ -218,7 +227,14 @@ function cleanup() {
218227 ) {
219228 node . properties . href = normalizeUrl ( node . properties . href ) ;
220229 }
221- if ( node . type === "link" ) {
230+ else if (
231+ node . type === "element" &&
232+ node . tagName === "img" &&
233+ node . properties . src
234+ ) {
235+ node . properties . src = normalizeUrl ( node . properties . src ) ;
236+ }
237+ if ( node . type === "link" || node . type === "image" ) {
222238 node . url = normalizeUrl ( node . url ) ;
223239 }
224240
@@ -234,7 +250,8 @@ function cleanup() {
234250 const siblings = ancestors [ ancestors . length - 1 ] . children ;
235251 const idx = siblings . indexOf ( node ) ;
236252 siblings . splice ( idx + 1 , 0 , { type : "code" , lang : "output" , value : output } ) ;
237- return idx + 2 ;
253+ siblings . splice ( idx , 0 , { type : "jsx" , value : '<div class="next-pre-has-output"></div>' } ) ;
254+ return idx + 3 ;
238255 }
239256 }
240257
@@ -307,8 +324,19 @@ function cleanup() {
307324 slugMap [ "" ] = "" ;
308325 }
309326
327+ function urlToFileUrl ( url )
328+ {
329+ if (
330+ url . startsWith ( thisProductUrl )
331+ ) {
332+ const dest = new URL ( url . replace ( thisProductUrl + '/' , '' ) , `file://${ path . dirname ( path . resolve ( file . path ) ) } /` ) ;
333+ return dest . toString ( ) ;
334+ }
335+ }
336+
337+ let svgNodes = [ ] ;
310338 let lineOffset = 0 ;
311- visitParents ( tree , [ "link" , "element" , "heading" ] , ( node ) => {
339+ visitParents ( tree , [ "link" , "image" , " element", "heading" ] , ( node ) => {
312340 try {
313341 if ( node . type === "heading" && node . data ?. originalFile ) {
314342 currentOriginalFile = node . data . originalFile ;
@@ -322,7 +350,21 @@ function cleanup() {
322350 node . properties . href
323351 )
324352 node . properties . href = mapUrlToSlug ( node . properties . href ) ;
353+ else if (
354+ node . type === "element" &&
355+ node . tagName === "img" &&
356+ node . properties . src
357+ ) {
358+ node . properties . src = urlToFileUrl ( node . properties . src ) ;
359+ if ( node . properties . src . endsWith ( ".svg" ) )
360+ svgNodes . push ( node ) ;
361+ }
325362 else if ( node . type === "link" ) node . url = mapUrlToSlug ( node . url ) ;
363+ else if ( node . type === "image" ) {
364+ node . url = urlToFileUrl ( node . url ) ;
365+ if ( node . url . endsWith ( ".svg" ) )
366+ svgNodes . push ( node ) ;
367+ }
326368 } catch ( e ) {
327369 console . log (
328370 `${ e . severity === 1 ? "⚠️⚠️ " : "⚠️ " } ${ formatErrorPath (
@@ -334,5 +376,54 @@ function cleanup() {
334376 ) ;
335377 }
336378 } ) ;
379+
380+ for ( let node of svgNodes ) {
381+ await convertSvgNode ( node ) ;
382+ }
337383 } ;
338384}
385+
386+ const svgoPlugins = [
387+ {
388+ name : 'preset-default' ,
389+ params : {
390+ overrides : {
391+ // disable plugins
392+ removeTitle : false ,
393+ removeDesc : false ,
394+ } ,
395+ } ,
396+ } ,
397+ 'removeXMLNS' ,
398+ ] ;
399+
400+ // adapted from https://github.com/alvinometric/remark-inline-svg to suit the specific needs of this pipeline
401+ async function convertSvgNode ( node ) {
402+ const url = new URL ( node . url || node . properties . src ) ;
403+ const image = await fs . readFile ( url . pathname , 'utf-8' ) ;
404+ const result = optimize ( image , { path : url . pathname , multipass : true , plugins : svgoPlugins } ) ;
405+
406+ if ( node . properties . src ) {
407+ let hast = unified ( )
408+ . use ( rehypeParse , {
409+ emitParseErrors : true ,
410+ verbose : true ,
411+ fragment : true ,
412+ } )
413+ . parse ( result . data ) ;
414+ node . tagName = "figure" ;
415+ let style = node . properties . style ;
416+ if ( node . properties . width )
417+ style = `${ style ? style + '; ' : '' } width: ${ node . properties . width } ` ;
418+ delete node . properties ;
419+ if ( style )
420+ node . properties = { style} ;
421+ node . children = hast . children ;
422+ }
423+ else {
424+ node . type = "jsx" ;
425+ node . value = result . data ;
426+ delete node . url ;
427+ }
428+
429+ }
0 commit comments