From c3666c98d6a7bb20261ace7a1e471ea7a4c8d50a Mon Sep 17 00:00:00 2001 From: dualfroz Date: Wed, 14 Oct 2026 19:36:06 +0200 Subject: [PATCH] keep a match's quotes and brackets out of m.text() in wrap() --- src/1-one/output/api/wrap.js | 14 +++++++++++++- tests/02-two/output/out.test.js | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/1-one/output/api/wrap.js b/src/1-one/output/api/wrap.js index f4a8e45..5f7963d 100644 --- a/src/1-one/output/api/wrap.js +++ b/src/1-one/output/api/wrap.js @@ -1,9 +1,21 @@ +import fmts from './_fmts.js' + const toText = function (term) { const pre = term.pre || '' const post = term.post || '' return pre + term.text + post } +// the match's pre and post are added around fn(m), so m.text() should leave them out +const withoutEnds = function (m) { + const text = m.text + m.text = fmt => { + const opts = typeof fmt === 'string' ? fmts[fmt] : fmt + return text.call(m, { keepEndPunct: false, ...opts }) + } + return m +} + const findStarts = function (doc, obj) { const starts = {} Object.keys(obj).forEach(reg => { @@ -25,7 +37,7 @@ const wrap = function (doc, obj) { // do a span tag if (Object.hasOwn(starts, t.id)) { const { fn, end } = starts[t.id] - const m = doc.update([[n, i, end]]) + const m = withoutEnds(doc.update([[n, i, end]])) text += terms[i].pre || '' text += fn(m) i = end - 1 diff --git a/tests/02-two/output/out.test.js b/tests/02-two/output/out.test.js index c8f3d85..5b65eb8 100644 --- a/tests/02-two/output/out.test.js +++ b/tests/02-two/output/out.test.js @@ -42,3 +42,25 @@ test('out-wrap', function (t) { t.equal(out, `before (few more words) after`, here + 'pre+post') t.end() }) + +test('out-wrap-punctuation', function (t) { + const arr = [ + [`"hello world" he said`, `"[hello world]" he said`], + [`he said "hello world" today`, `he said "[hello world]" today`], + [`he said "hello world"`, `he said "[hello world]"`], + [`(hello world) he said`, `([hello world]) he said`], + [`he said (hello world) today`, `he said ([hello world]) today`], + [`he said (hello world).`, `he said ([hello world]).`], + [`hello world, he said`, `[hello world], he said`], + [`he left. "hello world" she said`, `he left. "[hello world]" she said`], + [`"hello world."`, `"[hello world]."`], + ] + arr.forEach(function (a) { + const doc = nlp(a[0]) + t.equal(doc.out({ 'hello world': m => `[${m.text()}]` }), a[1], here + 'text: ' + a[0]) + t.equal(doc.wrap({ 'hello world': m => `[${m.out('normal')}]` }), a[1], here + 'normal: ' + a[0]) + }) + const out = nlp(`"Hello World" he said`).wrap({ 'hello world': m => `[${m.text('normal')}]` }) + t.equal(out, `"[hello world]" he said`, here + 'keeps text format') + t.end() +})