(value: string)
| 232 | * nodes on emphasis markers so we still render inline styling in those cases. |
| 233 | */ |
| 234 | const parseInlineFallback = (value: string): InlineFallbackNode[] => { |
| 235 | if (!value || !hasUnescapedMarker(value)) { |
| 236 | return [{ type: 'text', value }] |
| 237 | } |
| 238 | |
| 239 | const nodes: InlineFallbackNode[] = [] |
| 240 | let buffer = '' |
| 241 | |
| 242 | const flushBuffer = () => { |
| 243 | if (buffer.length > 0) { |
| 244 | nodes.push({ type: 'text', value: buffer }) |
| 245 | buffer = '' |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | let index = 0 |
| 250 | while (index < value.length) { |
| 251 | const char = value[index] |
| 252 | |
| 253 | if (char === '*') { |
| 254 | const markerChar = char |
| 255 | const isDouble = |
| 256 | index + 1 < value.length && value[index + 1] === markerChar |
| 257 | const marker = isDouble ? markerChar.repeat(2) : markerChar |
| 258 | const markerLength = marker.length |
| 259 | |
| 260 | let backslashes = 0 |
| 261 | for ( |
| 262 | let offset = index - 1; |
| 263 | offset >= 0 && value[offset] === '\\'; |
| 264 | offset -= 1 |
| 265 | ) { |
| 266 | backslashes += 1 |
| 267 | } |
| 268 | |
| 269 | if (backslashes % 2 === 1) { |
| 270 | buffer += marker |
| 271 | index += markerLength |
| 272 | continue |
| 273 | } |
| 274 | |
| 275 | const closing = findClosingDelimiter(value, index + markerLength, marker) |
| 276 | if (closing === -1) { |
| 277 | buffer += marker |
| 278 | index += markerLength |
| 279 | continue |
| 280 | } |
| 281 | |
| 282 | const inner = value.slice(index + markerLength, closing) |
| 283 | flushBuffer() |
| 284 | const children = parseInlineFallback(inner).filter( |
| 285 | (node) => !(node.type === 'text' && node.value.length === 0), |
| 286 | ) |
| 287 | |
| 288 | const emphasisNode: InlineFallbackNode = |
| 289 | isDouble |
| 290 | ? { type: 'strong', children } |
| 291 | : { type: 'emphasis', children } |
no test coverage detected