11const fs = require ( 'fs' ) ;
22const path = require ( 'path' ) ;
33const glob = require ( 'glob' ) ;
4+ const https = require ( 'https' ) ;
5+ const http = require ( 'http' ) ;
6+
7+ // Helper function to fetch content from URL
8+ function fetchUrl ( url ) {
9+ return new Promise ( ( resolve , reject ) => {
10+ const client = url . startsWith ( 'https:' ) ? https : http ;
11+
12+ client . get ( url , ( res ) => {
13+ if ( res . statusCode !== 200 ) {
14+ reject ( new Error ( `HTTP ${ res . statusCode } : ${ res . statusMessage } ` ) ) ;
15+ return ;
16+ }
17+
18+ let data = '' ;
19+ res . on ( 'data' , chunk => data += chunk ) ;
20+ res . on ( 'end' , ( ) => resolve ( data ) ) ;
21+ } ) . on ( 'error' , reject ) ;
22+ } ) ;
23+ }
424
525function codeImportPlugin ( context , options ) {
626 return {
@@ -22,24 +42,44 @@ function codeImportPlugin(context, options) {
2242 let content = fs . readFileSync ( filePath , 'utf8' ) ;
2343 let modified = false ;
2444
25- // Process code blocks with file= syntax
26- content = content . replace ( / ` ` ` ( \w + ) ? \s * ( f i l e = [ ^ \s \n ] + ) ( [ ^ \n ] * ) \n ( [ ^ ` ] * ?) ` ` ` / g, ( match , lang , fileParam , additionalMeta , existingContent ) => {
45+ // Process code blocks with file= or url= syntax
46+ const fileUrlRegex = / ` ` ` ( \w + ) ? \s * ( (?: f i l e | u r l ) = [ ^ \s \n ] + ) ( [ ^ \n ] * ) \n ( [ ^ ` ] * ?) ` ` ` / g;
47+ const matches = [ ...content . matchAll ( fileUrlRegex ) ] ;
48+
49+ for ( const match of matches ) {
50+ const [ fullMatch , lang , param , additionalMeta , existingContent ] = match ;
51+
2752 try {
28- const importPath = fileParam . replace ( 'file=' , '' ) ;
29- const absoluteImportPath = path . resolve ( context . siteDir , importPath ) ;
30- const importedContent = fs . readFileSync ( absoluteImportPath , 'utf8' ) ;
31- modified = true ;
53+ let importedContent ;
54+
55+ if ( param . startsWith ( 'file=' ) ) {
56+ // Handle file import
57+ const importPath = param . replace ( 'file=' , '' ) ;
58+ const absoluteImportPath = path . resolve ( context . siteDir , importPath ) ;
59+ importedContent = fs . readFileSync ( absoluteImportPath , 'utf8' ) ;
60+ } else if ( param . startsWith ( 'url=' ) ) {
61+ // Handle URL import
62+ const url = param . replace ( 'url=' , '' ) ;
63+ try {
64+ importedContent = await fetchUrl ( url ) ;
65+ } catch ( urlError ) {
66+ console . warn ( `Could not fetch URL ${ url } in ${ filePath } : ${ urlError . message } ` ) ;
67+ continue ; // Skip this replacement if URL fetch fails
68+ }
69+ }
3270
33- // Preserve the complete metadata including file= and any additional parameters
34- const fullMeta = `${ fileParam } ${ additionalMeta } ` ;
71+ // Preserve the complete metadata
72+ const fullMeta = `${ param } ${ additionalMeta } ` ;
3573 const metaStr = fullMeta ? ` ${ fullMeta } ` : '' ;
74+ const replacement = `\`\`\`${ lang || '' } ${ metaStr } \n${ importedContent } \`\`\`` ;
75+
76+ content = content . replace ( fullMatch , replacement ) ;
77+ modified = true ;
3678
37- return `\`\`\`${ lang || '' } ${ metaStr } \n${ importedContent } \`\`\`` ;
3879 } catch ( error ) {
39- console . warn ( `Could not import file ${ importPath } in ${ filePath } : ${ error . message } ` ) ;
40- return match ; // Return original if import fails
80+ console . warn ( `Could not process ${ param } in ${ filePath } : ${ error . message } ` ) ;
4181 }
42- } ) ;
82+ }
4383
4484 if ( modified ) {
4585 processedFiles . push ( {
0 commit comments