@rr0/cms 0.3.74 → 0.3.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,6 +31,11 @@ export type RR0TimeMessages = {
31
31
  * The word that, written right before an interval, asks for it to be rendered as `betweenAnd` ("between", "entre").
32
32
  */
33
33
  between: RegExp;
34
+ /**
35
+ * The words that, written right before a time, need it rendered in full: a relative wording can't follow them
36
+ * ("en l'année suivante", "in the year after").
37
+ */
38
+ preposition: RegExp;
34
39
  betweenAnd(startReplacement: string, endReplacement: string): string;
35
40
  on(approximate: boolean): string;
36
41
  in(approximate: boolean): string;
@@ -31,6 +31,7 @@ export declare class RR0TimeMessages_en implements RR0TimeMessages {
31
31
  in: (approximate: boolean) => string;
32
32
  fromTo: (startReplacement: string, endReplacement: string) => string;
33
33
  between: RegExp;
34
+ preposition: RegExp;
34
35
  betweenAnd: (startReplacement: string, endReplacement: string) => string;
35
36
  starting: (approximate: boolean) => string;
36
37
  }
@@ -34,6 +34,7 @@ export class RR0TimeMessages_en {
34
34
  this.in = (approximate) => (approximate ? "around " : "");
35
35
  this.fromTo = (startReplacement, endReplacement) => startReplacement + " to " + endReplacement;
36
36
  this.between = /\bbetween\s*$/i;
37
+ this.preposition = /\b(?:in|on|at|from|to|until|till|since|by|before|after|during|of|for|between|the)\s*$/i;
37
38
  this.betweenAnd = (startReplacement, endReplacement) => startReplacement + " and " + endReplacement;
38
39
  this.starting = (approximate) => "starting " + (approximate ? "" : "the ");
39
40
  }
@@ -31,6 +31,7 @@ export declare class RR0TimeMessages_fr implements RR0TimeMessages {
31
31
  in: (approximate: boolean) => string;
32
32
  fromTo: (startReplacement: string, endReplacement: string) => string;
33
33
  between: RegExp;
34
+ preposition: RegExp;
34
35
  betweenAnd: (startReplacement: string, endReplacement: string) => string;
35
36
  starting: (approximate: boolean) => string;
36
37
  }
@@ -34,6 +34,7 @@ export class RR0TimeMessages_fr {
34
34
  this.in = (approximate) => (approximate ? "vers " : "en ");
35
35
  this.fromTo = (startReplacement, endReplacement) => `${startReplacement} à ${endReplacement}`;
36
36
  this.between = /\bentre\s*$/i;
37
+ this.preposition = /(?:^|[^\p{L}])(?:(?:en|de|du|des|à|au|aux|jusque|dès|depuis|vers|avant|après|pour|par|fin|début|entre|le|la|les|ce|cet|cette)\s*|(?:d|l|jusqu|qu)['’]\s*|mi-\s*)$/iu;
37
38
  this.betweenAnd = (startReplacement, endReplacement) => `${startReplacement} et ${endReplacement}`;
38
39
  this.starting = (approximate) => "à partir " + (approximate ? "de " : "du ");
39
40
  }
@@ -33,11 +33,14 @@ export class TimeReplacer {
33
33
  const previousContext = origEl.dataset.context === "none" ? undefined : context.clone();
34
34
  const timeStr = origEl.textContent;
35
35
  const { prefix, value, suffix } = this.completer.split(timeStr);
36
- const between = context.messages.context.time.between.test(TimeReplacer.precedingText(origEl) + prefix);
36
+ const preceding = TimeReplacer.precedingText(origEl) + prefix;
37
+ const between = context.messages.context.time.between.test(preceding);
38
+ // "en l'année suivante" is not French: after a preposition, the time is rendered in full
39
+ const relativeWords = !context.messages.context.time.preposition.test(preceding);
37
40
  // A <time> already inside a link keeps that link: a link of its own would nest <a> in <a>, which the HTML
38
41
  // parser splits, closing the enclosing elements (a note, a source) early.
39
42
  const url = !origEl.closest("a");
40
- const options = { url, contentOnly: true, between };
43
+ const options = { url, contentOnly: true, between, relativeWords };
41
44
  try {
42
45
  const durations = /^(~?)P([^/]+)\/P?([^/]+)$/.exec(value.trim()); // "P10M/12M"
43
46
  if (durations) {
@@ -213,6 +213,30 @@ describe("TimeReplacer", async () => {
213
213
  const replacement2 = await replacer.replacement(context, original);
214
214
  expect(replacement2.outerHTML).toBe(`<span class="time-resolved"><a href="${cmsTestUtil.time.url("2/0/0/6/")}"><time datetime="${datetime}" title="2006">l'année suivante</time></a></span>`);
215
215
  });
216
+ describe("renders a time in full after a preposition", () => {
217
+ async function renderAfter(locale, html) {
218
+ const context = cmsTestUtil.time.newHtmlContext("1/9/9/0/08/index.html", "", locale);
219
+ const p = context.file.document.createElement("p");
220
+ p.innerHTML = html;
221
+ const times = p.querySelectorAll("time");
222
+ let replaced;
223
+ for (const time of times) {
224
+ replaced = await replacer.replacement(context, time);
225
+ }
226
+ return replaced.textContent;
227
+ }
228
+ test("in French", async () => {
229
+ expect(await renderAfter("fr", "<time>2005</time>. En <time>2006</time>")).toBe("2006");
230
+ expect(await renderAfter("fr", "<time>2005</time>, jusqu'à <time>2006</time>")).toBe("2006");
231
+ expect(await renderAfter("fr", "<time>2005</time>, d’<time>2006</time>")).toBe("2006");
232
+ });
233
+ test("in English", async () => {
234
+ expect(await renderAfter("en", "<time>2005</time>. In <time>2006</time>")).toBe("2006");
235
+ });
236
+ test("but not without one", async () => {
237
+ expect(await renderAfter("fr", "<time>2005</time>. Puis, <time>2006</time>")).toBe("l'année suivante");
238
+ });
239
+ });
216
240
  test("avoids linking to current file", async () => {
217
241
  const context = cmsTestUtil.time.newHtmlContext("1/9/9/0/08/index.html", "");
218
242
  const timeEl = context.file.document.createElement("time");
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@rr0/cms",
3
3
  "type": "module",
4
4
  "author": "Jérôme Beau <rr0@rr0.org> (https://rr0.org)",
5
- "version": "0.3.74",
5
+ "version": "0.3.75",
6
6
  "description": "RR0 Content Management System (CMS)",
7
7
  "exports": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",
@@ -31,7 +31,7 @@
31
31
  "dependencies": {
32
32
  "@javarome/fileutil": "^0.3.9",
33
33
  "@rr0/common": "^1.1.5",
34
- "@rr0/data": "^0.3.43",
34
+ "@rr0/data": "^0.3.45",
35
35
  "@rr0/lang": "^0.1.13",
36
36
  "@rr0/place": "^0.5.4",
37
37
  "@rr0/time": "^0.11.3",