Skip to content

Commit

Permalink
Merge pull request #398 from code-hike/lighter-annotations
Browse files Browse the repository at this point in the history
Use lighter annotations
  • Loading branch information
pomber authored Jul 10, 2023
2 parents b016a0c + 4667c0f commit fecddba
Show file tree
Hide file tree
Showing 20 changed files with 358 additions and 598 deletions.
File renamed without changes.
1 change: 1 addition & 0 deletions packages/mdx/dev/content/assets/bar.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
console.log("one")
console.log("two")
console.log("three")
// mark
console.log("four")
console.log("five")
console.log("six")
Expand Down
47 changes: 47 additions & 0 deletions packages/mdx/dev/content/comment-annotations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,50 @@ function adipiscing(...elit) {
return elit.map(ipsum => ipsum.sit)
}
```

## Inline comments

```css
body {
margin: 12px; /* mark[11:14] */
}
```

## Other syntaxes

```html hello.html
<!-- mark[6:14] -->
<div>Code Hike</div>
```

```mdx
{/* mark(2) */}

# Lorem

## Foo

# Ipsum {/* mark */}
```

```jsonc
{
// mark[12:20]
"name": "Code Hike"
}
```

```lua
-- mark[8:16]
print("Code Hike")
```

```matlab
% mark[7:15]
disp('Code Hike')
```

```lisp
; mark[9:17]
(print "Code Hike")
```
7 changes: 7 additions & 0 deletions packages/mdx/dev/content/simple-code.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ graph LR
--> End1(End)
```

```foobar
// unknown lang
function lorem(ipsum, dolor = 1) {
return ipsum + dolor;
}
```

```js
function lorem(ipsum, dolor = 1) {}
```
Expand Down
6 changes: 0 additions & 6 deletions packages/mdx/dev/content/test.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,3 @@ function foobarloremipsumfoobarloremipsumsitametfoobarloremipsumfoobarloremipsum
return 8
}
```

<CH.Preview>

Hello

</CH.Preview>
2 changes: 1 addition & 1 deletion packages/mdx/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"coverage": "vitest run --coverage"
},
"dependencies": {
"@code-hike/lighter": "0.7.0",
"@code-hike/lighter": "0.7.3",
"node-fetch": "^2.0.0"
},
"devDependencies": {
Expand Down
50 changes: 0 additions & 50 deletions packages/mdx/src/highlighter/index.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions packages/mdx/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
export { attacher as remarkCodeHike } from "./remark/transform"

export { highlight } from "./highlighter"
73 changes: 0 additions & 73 deletions packages/mdx/src/remark/__snapshots__/comment-data.test.ts.snap

This file was deleted.

155 changes: 155 additions & 0 deletions packages/mdx/src/remark/annotations.comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { CodeAnnotation } from "smooth-code"
import {
LighterAnnotation,
extractLighterAnnotations,
parseLighterAnnotations,
} from "./lighter"
import { annotationsMap } from "../mdx-client/annotations"

const annotationNames = Object.keys(annotationsMap)

export async function splitCodeAndAnnotations(
rawCode: string,
lang: string,
config: { filepath?: string; autoLink?: boolean }
): Promise<{
code: string
annotations: CodeAnnotation[]
focus: string
}> {
let { code, annotations } =
await extractLighterAnnotations(rawCode, lang, [
...annotationNames,
"from",
"focus",
])

// import external code if needed and re-run annotations extraction
const fromAnnotations = annotations.filter(
a => a.name === "from"
)
if (fromAnnotations.length === 1) {
const fromData = fromAnnotations[0].query?.trim()
const [codepath, range] = fromData?.split(/\s+/) || []
const externalFileContent = await readFile(
codepath,
config.filepath,
range
)

const result = await extractLighterAnnotations(
externalFileContent,
lang,
[...annotationNames, "focus"]
)
code = result.code
annotations = result.annotations
}

if (config.autoLink) {
const autoLinkAnnotations = findLinkAnnotations(code)
annotations = [...annotations, ...autoLinkAnnotations]
}

return { code, ...parseLighterAnnotations(annotations) }
}

async function readFile(
externalCodePath: string,
mdxFilePath: string,
range: string | undefined
) {
const annotationContent =
"from " + mdxFilePath + " " + (range || "")

let fs, path

try {
fs = (await import("fs")).default
path = (await import("path")).default
if (!fs || !fs.readFileSync || !path || !path.resolve) {
throw new Error("fs or path not found")
}
} catch (e) {
e.message = `Code Hike couldn't resolve this annotation:
${annotationContent}
Looks like node "fs" and "path" modules are not available.`
throw e
}

// if we don't know the path of the mdx file:
if (mdxFilePath == null) {
throw new Error(
`Code Hike couldn't resolve this annotation:
${annotationContent}
Someone is calling the mdx compile function without setting the path.
Open an issue on CodeHike's repo for help.`
)
}

const dir = path.dirname(mdxFilePath)
const absoluteCodepath = path.resolve(
dir,
externalCodePath
)

let content: string
try {
content = fs.readFileSync(absoluteCodepath, "utf8")
} catch (e) {
e.message = `Code Hike couldn't resolve this annotation:
${annotationContent}
${absoluteCodepath} doesn't exist.`
throw e
}

if (range) {
const [start, end] = range.split(":")
const startLine = parseInt(start)
const endLine = parseInt(end)
if (isNaN(startLine) || isNaN(endLine)) {
throw new Error(
`Code Hike couldn't resolve this annotation:
${annotationContent}
The range is not valid. Should be something like:
${externalCodePath} 2:5`
)
}
const lines = content.split("\n")
content = lines.slice(startLine - 1, endLine).join("\n")
}

return content
}

const urlRegex = /https?:\/\/[\w\-_.~:/?#[\]@!$&*+,;=%]+/g
function findLinkAnnotations(
code: string
): LighterAnnotation[] {
const lines = code.split("\n")

const annotations: LighterAnnotation[] = []

lines.forEach((line, i) => {
let match: RegExpExecArray | null
while ((match = urlRegex.exec(line)) !== null) {
const url = match[0]
const start = match.index
const end = start + url.length

annotations.push({
name: "link",
query: url,
ranges: [
{
lineNumber: i + 1,
fromColumn: start + 1,
toColumn: end + 1,
},
],
})
}
})

return annotations
}
15 changes: 15 additions & 0 deletions packages/mdx/src/remark/annotations.metastring.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { CodeAnnotation } from "../smooth-code"
import { annotationsMap } from "../mdx-client/annotations"

export function getAnnotationsFromMetastring(
options: Record<string, string>
) {
const annotations = [] as CodeAnnotation[]
Object.keys(options).forEach(key => {
const Component = annotationsMap[key]
if (Component) {
annotations?.push({ focus: options[key], Component })
}
})
return annotations
}
Loading

0 comments on commit fecddba

Please sign in to comment.