마크다운 표 파싱 로직 분리

This commit is contained in:
2026-07-24 14:00:04 +09:00
parent 164bc2131f
commit f996506a15
7 changed files with 174 additions and 87 deletions

View File

@@ -34,6 +34,7 @@ import {
} from '../../lib/markdown-live-edit.js'
import { buildCodeBlockLines, buildCodeFenceOpener, parseCodeFenceLine } from '../../lib/markdown-code-block.js'
import { buildToggleBlockLines, parseToggleOpenerLine } from '../../lib/markdown-toggle.js'
import { parseMarkdownTableBlock } from '../../lib/markdown-table.js'
import {
buildCalloutOpenerLine,
CALLOUT_BACKGROUND_OPTIONS,
@@ -475,90 +476,6 @@ const parseMediaMeta = (raw) => {
return meta
}
/**
* 마크다운 표 행 후보인지 확인한다.
* @param {string} line - 원본 줄
* @returns {boolean} 표 행 후보 여부
*/
const isMarkdownTableRow = (line) => {
const value = String(line || '').trim()
return value.startsWith('|') && value.endsWith('|') && value.split('|').length >= 4
}
/**
* 마크다운 표 구분선 행인지 확인한다.
* @param {string} line - 원본 줄
* @returns {boolean} 구분선 여부
*/
const isMarkdownTableSeparator = (line) => {
if (!isMarkdownTableRow(line)) {
return false
}
return splitMarkdownTableRow(line).every((cell) => /^:?-{3,}:?$/.test(cell.trim()))
}
/**
* 마크다운 표 행을 셀 배열로 나눈다.
* @param {string} line - 원본 줄
* @returns {string[]} 셀 목록
*/
const splitMarkdownTableRow = (line) => String(line || '')
.trim()
.replace(/^\|/, '')
.replace(/\|$/, '')
.split('|')
.map((cell) => cell.trim().replace(/\\\|/g, '|'))
/**
* 표 정렬 행에서 셀 정렬 값을 파싱한다.
* @param {string} cell - 구분선 셀
* @returns {'left'|'center'|'right'} 정렬 값
*/
const parseMarkdownTableAlignment = (cell) => {
const value = String(cell || '').trim()
if (value.startsWith(':') && value.endsWith(':')) {
return 'center'
}
if (value.endsWith(':')) {
return 'right'
}
return 'left'
}
/**
* 마크다운 표 블록을 파싱한다.
* @param {string[]} lines - 전체 마크다운 줄
* @param {number} startIndex - 표 시작 후보 줄
* @returns {{headers: string[], alignments: string[], rows: string[][], endLine: number, nextIndex: number}|null} 표 메타
*/
const parseMarkdownTableBlock = (lines, startIndex) => {
if (!isMarkdownTableRow(lines[startIndex]) || !isMarkdownTableSeparator(lines[startIndex + 1])) {
return null
}
const headers = splitMarkdownTableRow(lines[startIndex])
const alignments = splitMarkdownTableRow(lines[startIndex + 1]).map(parseMarkdownTableAlignment)
const rows = []
let index = startIndex + 2
while (index < lines.length && isMarkdownTableRow(lines[index]) && !isMarkdownTableSeparator(lines[index])) {
rows.push(splitMarkdownTableRow(lines[index]))
index += 1
}
return {
headers,
alignments,
rows,
endLine: index - 1,
nextIndex: index
}
}
/**
* 마크다운 문자열을 렌더링용 블록 목록으로 변환
* @param {string} markdown - 마크다운 문자열