Skip to content

Commit

Permalink
Annotation extractor function (fix #26)
Browse files Browse the repository at this point in the history
  • Loading branch information
pomber committed Oct 11, 2023
1 parent 677d2d8 commit 567aadb
Show file tree
Hide file tree
Showing 12 changed files with 483 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changeset/clever-cheetahs-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@code-hike/lighter": minor
---

Add annotation extractor function
2 changes: 1 addition & 1 deletion lib/dist/browser.esm.mjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/dist/index.cjs.js

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion lib/dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ type Annotation = {
query?: string;
ranges: CodeRange[];
};
type AnnotationData = {
name: string;
rangeString: string;
query?: string;
};
type AnnotationExtractor = string[] | ((comment: string) => null | AnnotationData);

type Token = {
content: string;
Expand Down Expand Up @@ -113,7 +119,7 @@ declare function highlight(code: string, lang: LanguageAlias, themeOrThemeName?:
declare function highlight(code: string, lang: LanguageAlias, themeOrThemeName: Theme, config: AnnotatedConfig): Promise<AnnotatedLighterResult>;
declare function highlightSync(code: string, lang: LanguageAlias, themeOrThemeName?: Theme, config?: Config): LighterResult;
declare function highlightSync(code: string, lang: LanguageAlias, themeOrThemeName: Theme, config: AnnotatedConfig): AnnotatedLighterResult;
declare function extractAnnotations(code: string, lang: LanguageAlias, annotationNames?: string[]): Promise<{
declare function extractAnnotations(code: string, lang: LanguageAlias, annotationExtractor?: AnnotationExtractor): Promise<{
code: string;
annotations: Annotation[];
}>;
Expand Down
2 changes: 1 addition & 1 deletion lib/dist/index.esm.mjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/dist/worker.esm.mjs

Large diffs are not rendered by default.

32 changes: 26 additions & 6 deletions lib/src/comments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,21 @@ export type Annotation = {
ranges: CodeRange[];
};

export type AnnotationData = {
name: string;
rangeString: string;
query?: string;
};

export type AnnotationExtractor =
| string[]
| ((comment: string) => null | AnnotationData);

export function extractCommentsFromCode(
code: string,
grammar: IGrammar,
lang: string,
annotationNames: string[]
annotationExtractor: AnnotationExtractor
) {
const lines = !grammar
? highlightText(code)
Expand All @@ -49,7 +59,7 @@ export function extractCommentsFromCode(
.map((line) => {
const { annotations, lineWithoutComments } = getAnnotationsFromLine(
line,
annotationNames,
annotationExtractor,
lineNumber
);

Expand Down Expand Up @@ -81,7 +91,7 @@ export function extractCommentsFromCode(

function getAnnotationsFromLine(
tokens: Token[],
names: string[],
annotationExtractor: AnnotationExtractor,
lineNumber: number
) {
// if no punctuation return empty
Expand All @@ -106,12 +116,17 @@ function getAnnotationsFromLine(
continue;
}

const { name, query, rangeString } = getAnnotationData(token.content);
if (!names.includes(name)) {
const annotationData =
typeof annotationExtractor === "function"
? annotationExtractor(token.content)
: getAnnotationDataFromNames(token.content, annotationExtractor);

if (!annotationData) {
// a comment, but not an annotation
i++;
continue;
}
const { name, query, rangeString } = annotationData;

// we have an annotation
const prevToken = tokens[i - 1];
Expand Down Expand Up @@ -156,11 +171,16 @@ function getAnnotationsFromLine(
};
}

function getAnnotationData(content: string) {
function getAnnotationDataFromNames(content: string, names: string[]) {
const regex = /\s*([\w-]+)?(\([^\)]*\)|\[[^\]]*\])?(.*)$/;
const match = content.match(regex);
const name = match[1];
const rangeString = match[2];
const query = match[3]?.trim();

if (!names.includes(name)) {
return null;
}

return { name, rangeString, query };
}
12 changes: 8 additions & 4 deletions lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import {
preloadGrammars,
highlightText,
} from "./highlighter";
import { Annotation, extractCommentsFromCode } from "./comments";
import {
Annotation,
AnnotationExtractor,
extractCommentsFromCode,
} from "./comments";
import {
applyAnnotations,
Lines,
Expand Down Expand Up @@ -174,9 +178,9 @@ export function highlightSync(
export async function extractAnnotations(
code: string,
lang: LanguageAlias,
annotationNames: string[] = []
annotationExtractor?: AnnotationExtractor
) {
if (annotationNames.length === 0) {
if (!annotationExtractor) {
return { code, annotations: [] };
}

Expand All @@ -187,7 +191,7 @@ export async function extractAnnotations(
code,
grammar,
lang,
annotationNames
annotationExtractor
);

return { code: newCode, annotations };
Expand Down
134 changes: 134 additions & 0 deletions lib/test/__snapshots__/browser.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,140 @@ exports[`extract annottations from txt 2`] = `
}
`;

exports[`extract annottations with prefix 1`] = `
{
"annotations": [
{
"name": "xy",
"query": "bar",
"ranges": [
{
"fromColumn": 3,
"lineNumber": 3,
"toColumn": 5,
},
],
},
],
"code": "// xyz[3:5] foo
const x = 1;
const y = 2;",
}
`;

exports[`extract annottations with prefix 2`] = `
{
"lang": "javascript",
"lines": [
{
"lineNumber": 1,
"tokens": [
{
"content": "// xyz[3:5] foo",
"style": {
"color": "#6A9955",
},
},
],
},
{
"lineNumber": 2,
"tokens": [
{
"content": "const ",
"style": {
"color": "#569CD6",
},
},
{
"content": "x",
"style": {
"color": "#4FC1FF",
},
},
{
"content": " = ",
"style": {
"color": "#D4D4D4",
},
},
{
"content": "1",
"style": {
"color": "#B5CEA8",
},
},
{
"content": ";",
"style": {
"color": "#D4D4D4",
},
},
],
},
{
"lineNumber": 3,
"tokens": [
{
"content": "co",
"style": {
"color": "#569CD6",
},
},
{
"annotationName": "xy",
"annotationQuery": "bar",
"fromColumn": 3,
"toColumn": 5,
"tokens": [
{
"content": "nst",
"style": {
"color": "#569CD6",
},
},
],
},
{
"content": " ",
"style": {
"color": "#569CD6",
},
},
{
"content": "y",
"style": {
"color": "#4FC1FF",
},
},
{
"content": " = ",
"style": {
"color": "#D4D4D4",
},
},
{
"content": "2",
"style": {
"color": "#B5CEA8",
},
},
{
"content": ";",
"style": {
"color": "#D4D4D4",
},
},
],
},
],
"style": {
"background": "#1E1E1E",
"color": "#D4D4D4",
},
}
`;

exports[`highlight html with theme 1`] = `
{
"lang": "html",
Expand Down
Loading

1 comment on commit 567aadb

@vercel
Copy link

@vercel vercel bot commented on 567aadb Oct 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lighter – ./

lighter-git-main-codehike.vercel.app
lighter-codehike.vercel.app
lighter.codehike.org

Please sign in to comment.