Skip to content

Commit

Permalink
fix: splitLines extra new lines, fix #576
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Feb 5, 2024
1 parent d936747 commit 0bb2810
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 5 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/transformer-decorations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ export function transformerDecorations(): ShikiTransformer {

const lines = Array.from(codeEl.children).filter(i => i.type === 'element' && i.tagName === 'span') as Element[]

// if (lines.length !== ctx.converter.lines.length)
// throw new ShikiError(`Number of lines in code element (${lines.length}) does not match the number of lines in the source (${ctx.converter.lines.length}). Failed to apply decorations.`)
if (lines.length !== ctx.converter.lines.length)
throw new ShikiError(`Number of lines in code element (${lines.length}) does not match the number of lines in the source (${ctx.converter.lines.length}). Failed to apply decorations.`)

function applyLineSection(line: number, start: number, end: number, decoration: DecorationItem) {
const lineEl = lines[line]
Expand Down
17 changes: 14 additions & 3 deletions packages/core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,19 @@ export function toArray<T>(x: MaybeArray<T>): T[] {
/**
* Slipt a string into lines, each line preserves the line ending.
*/
export function splitLines(str: string) {
return Array.from(str.matchAll(/^.*$/mg)).map(x => [x[0], x.index!] as [code: string, offset: number])
export function splitLines(code: string, preserveEnding = false): [string, number][] {
const parts = code.split(/(\r?\n)/g)
let index = 0
const lines: [string, number][] = []
for (let i = 0; i < parts.length; i += 2) {
const line = preserveEnding
? parts[i] + (parts[i + 1] || '')
: parts[i]
lines.push([line, index])
index += parts[i].length
index += parts[i + 1]?.length || 0
}
return lines
}

/**
Expand Down Expand Up @@ -169,7 +180,7 @@ export function stringifyTokenStyle(token: Record<string, string>) {
* Creates a converter between index and position in a code block.
*/
export function createPositionConverter(code: string) {
const lines = Array.from(code.matchAll(/.*?($|\n)/g)).map(match => match[0])
const lines = splitLines(code, true).map(([line]) => line)

function indexToPos(index: number): Position {
let character = index
Expand Down
47 changes: 47 additions & 0 deletions packages/core/test/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* eslint-disable style/no-tabs */
import { describe, expect, it } from 'vitest'
import { splitLines } from '../src/utils'

describe('utils', () => {
it('splitLines', () => {
const lines = [
'\t*/\r',
'\tpublic void setTestingRefNum(long l) {\r',
'\ttestingRefNum = l;\r',
'\t}\r',
]
const code = lines.join('\n')

const resultWithEnding = splitLines(code, true)
const resultWithoutEnding = splitLines(code, false)
const reconstructed = resultWithEnding.map(([line]) => line).join('')
expect(reconstructed).toBe(code)
// the offset should be the same
expect(resultWithoutEnding.map(i => i[1]))
.toEqual(resultWithEnding.map(i => i[1]))
expect(resultWithEnding).toMatchInlineSnapshot(`
[
[
" */
",
0,
],
[
" public void setTestingRefNum(long l) {
",
5,
],
[
" testingRefNum = l;
",
46,
],
[
" }
",
67,
],
]
`)
})
})

0 comments on commit 0bb2810

Please sign in to comment.