Skip to content

Commit

Permalink
fix(glow): handle inline /* ... */ comment
Browse files Browse the repository at this point in the history
  • Loading branch information
maurice committed Jan 27, 2025
1 parent e7cf831 commit 58f3813
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 18 deletions.
56 changes: 39 additions & 17 deletions packages/glow/src/glow.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ const HTML_TAGS = [

// line comment
{ tag: 'sup', re: /# .+/ },

// inline comment
{ tag: 'sup', re: /\/\*.*?\*\//g },

{ tag: 'label', re: /\[([a-z\-]+)/g, lang: ['md', 'toml'], shift: true },

Expand Down Expand Up @@ -223,7 +226,7 @@ export function renderRow(row, lang, mark=true) {


// comment start & end
const COMMENT = [/(\/\*|^ *{# |<!--|'''|=begin)/, /(\*\/|#}|-->|'''|=end)$/]
const COMMENT = [/(\/\*|^ *{# |<!--|'''|=begin)/, /(\*\/|#}|-->|'''|=end)/]

export function parseSyntax(lines, lang, prefix = true) {
const [comm_start, comm_end] = COMMENT
Expand All @@ -232,16 +235,20 @@ export function parseSyntax(lines, lang, prefix = true) {
// multi-line comment
let comment

function endComment() {
html.push({ comment })
function endComment(partial) {
html.push({ comment, partial })
comment = null
}

lines.forEach((line, i) => {
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
if (!comment) {
if (comm_start.test(line)) {
const start_comm = comm_start.exec(line)
const end_comm = comm_end.exec(line);
if (start_comm && start_comm.index === 0 && (!end_comm || line.length === end_comm.index + end_comm[0].length)) {
// entire line is a complete comment OR the beginning of a block comment
comment = [line]
if (comm_end.test(line) && line?.trim() != "'''") endComment()
if (end_comm && line?.trim() != "'''") endComment()
} else {

// highlighted line
Expand All @@ -258,11 +265,20 @@ export function parseSyntax(lines, lang, prefix = true) {
}

} else {
comment.push(line)
if (comm_end.test(line)) endComment()
const end_comm = comm_end.exec(line);
if (end_comm) {
const end = end_comm.index + end_comm[0].length;
const [before, after] = [line.slice(0, end), line.slice(end)];
comment.push(before)
endComment(!!after.length)
if (after) {
lines.splice(i + 1, 0, after)
}
} else {
comment.push(line)
}
}
})

}

return html
}
Expand All @@ -280,24 +296,30 @@ export function glow(str, opts = { prefix: true, mark: true }) {
if (!lang && lines[0][0] == '<') lang = 'html'
const html = []

let is_partial = false
function push(line) {
html.push(opts.numbered ? elem('span', line) : line)
if (is_partial) html[html.length - 1] = html[html.length - 1] + line
else html.push(line)
is_partial = false
}

parseSyntax(lines, lang, opts.prefix).forEach(function(block) {
let { line, comment, wrap } = block

let { line, comment, wrap, partial } = block
// EOL comment
if (comment) {
return comment.forEach(el => push(elem('sup', encode(el))))

comment.forEach(el => push(elem('sup', encode(el))))
is_partial = partial
return

} else {
line = renderRow(line, lang, opts.mark)
}

if (wrap) line = elem(wrap, line)
push(line)
is_partial = partial
})

return `<code language="${lang || '*'}">${html.join(NL)}</code>`
return `<code language="${lang || '*'}">${html.map(el => opts.numbered ? elem('span', el) : el).join(NL)}</code>`
}
19 changes: 18 additions & 1 deletion packages/glow/test/glow.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { parseRow, renderRow, parseSyntax } from '../src/glow.js'
import { glow, parseRow, renderRow, parseSyntax } from '../src/glow.js'

test('HTML', () => {
const row = '<div class="hello">'
Expand Down Expand Up @@ -39,6 +39,23 @@ test('parse JS comment', () => {
expect(blocks[2].comment[0]).toEqual('/*')
})

test('parse TS inline comment', () => {
const html = renderRow('const colors: Record</* name */ string, /* hex */ string> = {};')
expect(html).toInclude('Record<i>&lt;</i><sup>/* name */</sup> <strong>string</strong><i>,</i> <sup>/* hex */</sup> <strong>string</strong><i>&gt;</i>')
})


test('parse block comment with content after comment-end', () => {
const result = glow(`/*
hello
*/ world`, 'js')
expect(result).toEqual('<code language=\"js\"><sup>/*</sup>\n<sup>hello</sup>\n<sup>*/</sup> world</code>')
})

test('parse inline comment with content after end', () => {
const result = glow(`/* this is a line comment */ const foo = 2;`, 'js')
expect(result).toEqual('<code language=\"js\"><sup>/* this is a line comment */</sup> <strong>const</strong> <b>foo</b> <i>=</i> <em>2</em><i>;</i></code>')
})

/* prefix and mark */
test('disable mark', () => {
Expand Down

0 comments on commit 58f3813

Please sign in to comment.