Bin29's picture
Sync from main: c1ef036 chore: document docker persistence volumes
94e1b2f
const FULLWIDTH_PUNCTUATION_MAP: Record<string, string> = {
'\uFF0C': ',',
'\u3001': ',',
'\u3002': '.',
'\uFF1B': ';',
'\uFF1A': ':',
'\uFF08': '(',
'\uFF09': ')',
'\u3010': '[',
'\u3011': ']',
'\u300C': '"',
'\u300D': '"',
'\u300E': '"',
'\u300F': '"',
'\u201C': '"',
'\u201D': '"',
'\u2018': "'",
'\u2019': "'",
'\uFF01': '!',
'\uFF1F': '?',
'\uFF05': '%',
'\uFF0B': '+',
'\uFF1D': '=',
'\uFF0D': '-',
'\u2013': '-',
'\u2014': '-',
'\uFF5E': '~'
}
function isIdentifierChar(value: string | undefined): boolean {
return !!value && /[A-Za-z0-9_]/.test(value)
}
export function replaceFullwidthOutsideStrings(code: string): { code: string; replaced: number } {
let result = ''
let replaced = 0
let i = 0
let inSingle = false
let inDouble = false
let inTripleSingle = false
let inTripleDouble = false
let inComment = false
while (i < code.length) {
const ch = code[i]
const nextThree = code.slice(i, i + 3)
if (inComment) {
result += ch
if (ch === '\n') {
inComment = false
}
i += 1
continue
}
if (!inSingle && !inDouble && !inTripleSingle && !inTripleDouble) {
if (nextThree === "'''" && !inDouble) {
inTripleSingle = true
result += nextThree
i += 3
continue
}
if (nextThree === '"""' && !inSingle) {
inTripleDouble = true
result += nextThree
i += 3
continue
}
if (ch === '#') {
inComment = true
result += ch
i += 1
continue
}
if (ch === "'") {
inSingle = true
result += ch
i += 1
continue
}
if (ch === '"') {
inDouble = true
result += ch
i += 1
continue
}
const replacement = FULLWIDTH_PUNCTUATION_MAP[ch]
if (replacement) {
result += replacement
replaced += 1
} else {
result += ch
}
i += 1
continue
}
if (inTripleSingle) {
if (nextThree === "'''") {
inTripleSingle = false
result += nextThree
i += 3
} else {
result += ch
i += 1
}
continue
}
if (inTripleDouble) {
if (nextThree === '"""') {
inTripleDouble = false
result += nextThree
i += 3
} else {
result += ch
i += 1
}
continue
}
if (inSingle || inDouble) {
result += ch
if (ch === '\\' && i + 1 < code.length) {
result += code[i + 1]
i += 2
continue
}
if (inSingle && ch === "'") {
inSingle = false
} else if (inDouble && ch === '"') {
inDouble = false
}
i += 1
}
}
return { code: result, replaced }
}
export function replaceLineWithDashedLine(code: string): { code: string; changed: number } {
let result = ''
let changed = 0
let i = 0
while (i < code.length) {
if (code.startsWith('Line(', i) && !isIdentifierChar(code[i - 1])) {
let j = i + 5
let depth = 1
let inSingle = false
let inDouble = false
let inTripleSingle = false
let inTripleDouble = false
while (j < code.length && depth > 0) {
const ch = code[j]
const nextThree = code.slice(j, j + 3)
if (!inSingle && !inDouble && !inTripleSingle && !inTripleDouble) {
if (nextThree === "'''" && !inDouble) {
inTripleSingle = true
j += 3
continue
}
if (nextThree === '"""' && !inSingle) {
inTripleDouble = true
j += 3
continue
}
if (ch === "'") {
inSingle = true
j += 1
continue
}
if (ch === '"') {
inDouble = true
j += 1
continue
}
if (ch === '(') {
depth += 1
} else if (ch === ')') {
depth -= 1
}
j += 1
continue
}
if (inTripleSingle) {
if (nextThree === "'''") {
inTripleSingle = false
j += 3
} else {
j += 1
}
continue
}
if (inTripleDouble) {
if (nextThree === '"""') {
inTripleDouble = false
j += 3
} else {
j += 1
}
continue
}
if (inSingle || inDouble) {
if (ch === '\\' && j + 1 < code.length) {
j += 2
continue
}
if (inSingle && ch === "'") {
inSingle = false
} else if (inDouble && ch === '"') {
inDouble = false
}
j += 1
}
}
const segment = code.slice(i, j)
if (segment.includes('dash_length') || segment.includes('dashed_ratio') || segment.includes('dash_ratio')) {
result += segment.replace(/^Line\(/, 'DashedLine(')
changed += 1
} else {
result += segment
}
i = j
continue
}
result += code[i]
i += 1
}
return { code: result, changed }
}