(line: StyledSpan[], mark: string)
| 418 | } |
| 419 | |
| 420 | export function mark(line: StyledSpan[], mark: string): StyledSpan[] { |
| 421 | // Mark is of the form "1-3" and indicates a range of characters to mark |
| 422 | const [start, end_] = mark.split('-').map((x) => parseInt(x)); |
| 423 | let end = end_; |
| 424 | if (end === undefined) end = start + 1; |
| 425 | if (start >= end) end = start + 1; |
| 426 | |
| 427 | let pos = 0; |
| 428 | |
| 429 | const markSpan = (span: StyledSpan): StyledSpan[] => { |
| 430 | const content = span.content; |
| 431 | |
| 432 | const spanStart = pos; |
| 433 | const spanEnd = pos + content.length - 1; |
| 434 | |
| 435 | pos += content.length; |
| 436 | |
| 437 | // Is the span entirely outside the marked range? |
| 438 | if (spanEnd < start || end < spanStart) return [span]; |
| 439 | |
| 440 | // Is the span entirely inside the marked range? |
| 441 | if (spanStart >= start && spanEnd <= end) |
| 442 | return [{ ...span, ...DEFAULT_THEME.mark }]; |
| 443 | |
| 444 | // Is the start of the span in the marked range? |
| 445 | if (spanStart >= start && spanEnd > end) { |
| 446 | const before = content.slice(0, end + 1 - pos); |
| 447 | const after = content.slice(end + 1 - pos); |
| 448 | return [ |
| 449 | { ...span, content: before, ...DEFAULT_THEME.mark }, |
| 450 | { ...span, content: after }, |
| 451 | ]; |
| 452 | } |
| 453 | |
| 454 | // Is the end of the span in the marked range? |
| 455 | if (start >= spanStart && end >= spanEnd) { |
| 456 | const before = content.slice(0, start - pos); |
| 457 | const after = content.slice(start - pos); |
| 458 | return [ |
| 459 | { ...span, content: before }, |
| 460 | { ...span, content: after, ...DEFAULT_THEME.mark }, |
| 461 | ]; |
| 462 | } |
| 463 | |
| 464 | // The span is entirely inside the marked range |
| 465 | const before = content.slice(0, start - pos); |
| 466 | const marked = content.slice(start - pos, end - pos + 1); |
| 467 | const after = content.slice(end - pos + 1); |
| 468 | return [ |
| 469 | { ...span, content: before }, |
| 470 | { ...span, content: marked, ...DEFAULT_THEME.mark }, |
| 471 | { ...span, content: after }, |
| 472 | ]; |
| 473 | }; |
| 474 | |
| 475 | return line.flatMap((span) => markSpan(span)); |
| 476 | } |
| 477 |
no test coverage detected