| 543 | |
| 544 | // copied from ACE |
| 545 | const _processSpaces = (s: string) => { |
| 546 | const doesWrap = true; |
| 547 | if (s.indexOf('<') < 0 && !doesWrap) { |
| 548 | // short-cut |
| 549 | return s.replace(/[ \u00a0]/g, ' '); |
| 550 | } |
| 551 | const parts: string[] = []; |
| 552 | s.replace(/<[^>]*>?|[ \u00a0]|[^ \u00a0<]+/g, (m) => { |
| 553 | parts.push(m); |
| 554 | return m |
| 555 | }); |
| 556 | // U+00A0 is content for run-bookkeeping - it terminates a space run |
| 557 | // just like a word character would, so runs of regular spaces adjacent |
| 558 | // to a nbsp are not miscounted as one long run (issue #3037). |
| 559 | if (doesWrap) { |
| 560 | let endOfLine = true; |
| 561 | let beforeSpace = false; |
| 562 | // last space in a run is normal, others are nbsp, |
| 563 | // end of line is nbsp |
| 564 | for (let i = parts.length - 1; i >= 0; i--) { |
| 565 | const p = parts[i]; |
| 566 | if (p === ' ') { |
| 567 | if (endOfLine || beforeSpace) parts[i] = ' '; |
| 568 | endOfLine = false; |
| 569 | beforeSpace = true; |
| 570 | } else if (p.charAt(0) !== '<') { |
| 571 | endOfLine = false; |
| 572 | beforeSpace = false; |
| 573 | } |
| 574 | } |
| 575 | // beginning of line is nbsp |
| 576 | for (let i = 0; i < parts.length; i++) { |
| 577 | const p = parts[i]; |
| 578 | if (p === ' ') { |
| 579 | parts[i] = ' '; |
| 580 | break; |
| 581 | } else if (p.charAt(0) !== '<') { |
| 582 | break; |
| 583 | } |
| 584 | } |
| 585 | } else { |
| 586 | for (let i = 0; i < parts.length; i++) { |
| 587 | const p = parts[i]; |
| 588 | if (p === ' ') { |
| 589 | parts[i] = ' '; |
| 590 | } |
| 591 | } |
| 592 | } |
| 593 | for (let i = 0; i < parts.length; i++) { |
| 594 | if (parts[i] === '\u00a0') parts[i] = ' '; |
| 595 | } |
| 596 | return parts.join(''); |
| 597 | }; |
| 598 | |
| 599 | exports.getPadHTML = getPadHTML; |
| 600 | exports.getHTMLFromAtext = getHTMLFromAtext; |