@@ -8,9 +8,10 @@ import {
88 extractAnnotationsFromCode ,
99 extractJSXAnnotations ,
1010} from "./annotations"
11- import { mergeFocus } from "../utils"
11+ import { Code , mergeFocus } from "../utils"
1212import { CodeNode , SuperNode } from "./nodes"
1313import { CodeHikeConfig } from "./config"
14+ import { getCommentData } from "./comment-data"
1415
1516export function isEditorNode (
1617 node : SuperNode ,
@@ -119,12 +120,15 @@ async function mapFile(
119120
120121 const lang = ( node . lang as string ) || "text"
121122
122- const code = await highlight ( {
123+ let code = await highlight ( {
123124 code : node . value as string ,
124125 lang,
125126 theme,
126127 } )
127128
129+ // if the code is a single line with a "from" annotation
130+ code = await getCodeFromExternalFileIfNeeded ( code , config )
131+
128132 const [ commentAnnotations , commentFocus ] =
129133 extractAnnotationsFromCode ( code )
130134
@@ -136,12 +140,12 @@ async function mapFile(
136140 options as any
137141 )
138142
139- const linkAnnotations = extractLinks (
140- node ,
141- index ,
142- parent ,
143- node . value as string
144- )
143+ // const linkAnnotations = extractLinks(
144+ // node,
145+ // index,
146+ // parent,
147+ // nodeValue as string
148+ // )
145149
146150 const jsxAnnotations = extractJSXAnnotations (
147151 node ,
@@ -188,3 +192,69 @@ function parseMetastring(
188192 } )
189193 return { name : name || "" , ...options }
190194}
195+
196+ async function getCodeFromExternalFileIfNeeded (
197+ code : Code ,
198+ config : CodeHikeConfig
199+ ) {
200+ if ( code ?. lines ?. length != 1 ) {
201+ return code
202+ }
203+
204+ const firstLine = code . lines [ 0 ]
205+ const commentData = getCommentData ( firstLine , code . lang )
206+
207+ if ( ! commentData || commentData . key != "from" ) {
208+ return code
209+ }
210+
211+ const fileText = firstLine . tokens
212+ . map ( t => t . content )
213+ . join ( "" )
214+
215+ const codepath = commentData . data
216+
217+ let fs , path
218+
219+ try {
220+ fs = ( await import ( "fs" ) ) . default
221+ path = ( await import ( "path" ) ) . default
222+ if ( ! fs || ! fs . readFileSync || ! path || ! path . resolve ) {
223+ throw new Error ( "fs or path not found" )
224+ }
225+ } catch ( e ) {
226+ e . message = `Code Hike couldn't resolve this annotation:
227+ ${ fileText }
228+ Looks like node "fs" and "path" modules are not available.`
229+ throw e
230+ }
231+
232+ // if we don't know the path of the mdx file:
233+ if ( config . filepath === undefined ) {
234+ throw new Error (
235+ `Code Hike couldn't resolve this annotation:
236+ ${ fileText }
237+ Someone is calling the mdx compile function without setting the path.
238+ Open an issue on CodeHike's repo for help.`
239+ )
240+ }
241+
242+ const dir = path . dirname ( config . filepath )
243+ const absoluteCodepath = path . resolve ( dir , codepath )
244+
245+ let nodeValue
246+ try {
247+ nodeValue = fs . readFileSync ( absoluteCodepath , "utf8" )
248+ } catch ( e ) {
249+ e . message = `Code Hike couldn't resolve this annotation:
250+ ${ fileText }
251+ ${ absoluteCodepath } doesn't exist.`
252+ throw e
253+ }
254+
255+ return await highlight ( {
256+ code : nodeValue ,
257+ lang : code . lang ,
258+ theme : config . theme ,
259+ } )
260+ }
0 commit comments