@lblod/ember-rdfa-editor-lblod-plugins 2.0.1 → 2.1.1

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.
package/.release-it.json CHANGED
@@ -3,12 +3,14 @@
3
3
  "release": true
4
4
  },
5
5
  "plugins": {
6
- "@release-it-plugins/lerna-changelog": {
7
- "infile": "CHANGELOG.md",
8
- "launchEditor": true
6
+ "@release-it/keep-a-changelog": {
7
+ "filename": "CHANGELOG.md",
8
+ "addUnreleased": true,
9
+ "strictLatest": false,
10
+ "addVersionUrl": true
9
11
  }
10
12
  },
11
13
  "npm": {
12
14
  "publish": false
13
15
  }
14
- }
16
+ }
package/CHANGELOG.md CHANGED
@@ -1,22 +1,49 @@
1
+ # Changelog
1
2
 
3
+ All notable changes to this project will be documented in this file.
2
4
 
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
3
7
 
8
+ ## [Unreleased]
4
9
 
10
+ ## [2.1.1] - 2023-02-07
5
11
 
12
+ ### Changed
6
13
 
14
+ - move to keep-a-changelog for changelog management
15
+ - bump editor to v2.1.2
16
+ - bump editor to v2.1.1
7
17
 
18
+ ### Added
8
19
 
20
+ - add types for the `debug` lib
9
21
 
22
+ ### Fixed
10
23
 
24
+ - correctly set the date type as xsd:date or xsd:dateTime based on the date content
25
+ - Add the __rdfaId when manually creating decisions titles, decision articles or citations
26
+ - fix citation highlights not triggering correctly in various situations
11
27
 
28
+ ## [2.1.0] - 2023-02-06
12
29
 
30
+ #### :rocket: Enhancement
13
31
 
32
+ * [#98](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/98) Improve citation plugin regex and improve
33
+ citation type matching ([@elpoelma](https://github.com/elpoelma))
14
34
 
35
+ #### :bug: Bug Fix
15
36
 
37
+ * [#96](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/96) Fix insert-citation button not being enabled
38
+ in correct context. ([@elpoelma](https://github.com/elpoelma))
39
+ * [#100](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/100) Prevent splitting of besluit related nodes ([@elpoelma](https://github.com/elpoelma))
40
+ * [#97](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/97) Fix: disallow splitting of besluit node ([@elpoelma](https://github.com/elpoelma))
16
41
 
42
+ #### :house: Internal
43
+ * [#99](https://github.com/lblod/ember-rdfa-editor-lblod-plugins/pull/99) Update editor to 2.1.0 ([@elpoelma](https://github.com/elpoelma))
17
44
 
18
-
19
-
45
+ #### Committers: 1
46
+ - Elena Poelman ([@elpoelma](https://github.com/elpoelma))
20
47
 
21
48
  ## 2.0.1 (2023-02-06)
22
49
 
@@ -288,3 +315,6 @@ add onclick handler to pencil icon in variable plugin
288
315
  - Elena Poelman ([@elpoelma](https://github.com/elpoelma))
289
316
 
290
317
  # Changelog
318
+
319
+ [unreleased]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v2.1.1...HEAD
320
+ [2.1.1]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v2.1.0...v2.1.1
@@ -12,16 +12,20 @@ import {
12
12
  Decision,
13
13
  } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin/utils/vlaamse-codex';
14
14
  import { citedText } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin/utils/cited-text';
15
- import { CitationPlugin } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin';
15
+ import {
16
+ CitationPlugin,
17
+ CitationPluginConfig,
18
+ } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin';
16
19
  import {
17
20
  LEGISLATION_TYPE_CONCEPTS,
18
21
  LEGISLATION_TYPES,
19
22
  } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin/utils/legislation-types';
20
23
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
24
+ import { findParentNodeOfType } from '@curvenote/prosemirror-utils';
21
25
 
22
26
  interface Args {
23
27
  controller: ProseController;
24
- widgetArgs: { plugin: CitationPlugin };
28
+ widgetArgs: { plugin: CitationPlugin; config: CitationPluginConfig };
25
29
  }
26
30
 
27
31
  export default class EditorPluginsCitationInsertComponent extends Component<Args> {
@@ -30,6 +34,10 @@ export default class EditorPluginsCitationInsertComponent extends Component<Args
30
34
  @tracked text = '';
31
35
  @tracked legislationType: string | null = null;
32
36
 
37
+ get config() {
38
+ return this.args.widgetArgs.config;
39
+ }
40
+
33
41
  get selectedLegislationTypeUri(): string {
34
42
  return this.selectedLegislationType.value;
35
43
  }
@@ -52,13 +60,25 @@ export default class EditorPluginsCitationInsertComponent extends Component<Args
52
60
  }
53
61
 
54
62
  get disableInsert() {
55
- if (!this.activeRanges || this.controller.inEmbeddedView) {
63
+ if (this.controller.inEmbeddedView) {
56
64
  return true;
57
65
  }
58
- const { from } = this.controller.state.selection;
59
- return !this.activeRanges.some(
60
- ([start, end]) => from > start && from < end
61
- );
66
+ const { selection } = this.controller.state;
67
+ if (this.config.type === 'ranges') {
68
+ const ranges = this.config.activeInRanges(this.controller.state);
69
+ for (const range of ranges) {
70
+ if (selection.from > range[0] && selection.from < range[1]) {
71
+ return false;
72
+ }
73
+ }
74
+ return true;
75
+ } else {
76
+ const nodeTypes = this.config.activeInNodeTypes(
77
+ this.controller.schema,
78
+ this.controller.state
79
+ );
80
+ return !findParentNodeOfType([...nodeTypes])(selection);
81
+ }
62
82
  }
63
83
 
64
84
  get plugin() {
@@ -5,6 +5,7 @@ import { ProseController } from '@lblod/ember-rdfa-editor/core/prosemirror';
5
5
  import { NodeSelection, PNode } from '@lblod/ember-rdfa-editor';
6
6
  import { DateFormat } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/rdfa-date-plugin';
7
7
  import {
8
+ formatContainsTime,
8
9
  validateDateFormat,
9
10
  ValidationError,
10
11
  } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/rdfa-date-plugin/utils';
@@ -28,7 +29,6 @@ type Args = {
28
29
  };
29
30
  };
30
31
  };
31
- const TIME_CHAR_REGEX = new RegExp('[abBhHkKmsStTp]');
32
32
  const SECONDS_REGEX = new RegExp('[sStT]|p{2,}');
33
33
  export default class RdfaDatePluginCardComponent extends Component<Args> {
34
34
  @service
@@ -84,8 +84,7 @@ export default class RdfaDatePluginCardComponent extends Component<Args> {
84
84
  return optionMapOr(
85
85
  false,
86
86
  (node) => {
87
- const format = node.attrs.format as string;
88
- return !TIME_CHAR_REGEX.test(format);
87
+ return !formatContainsTime(node.attrs.format);
89
88
  },
90
89
  this.selectedDateNode
91
90
  );
@@ -96,7 +95,7 @@ export default class RdfaDatePluginCardComponent extends Component<Args> {
96
95
  false,
97
96
  (node) => {
98
97
  const format = node.attrs.format as string;
99
- return SECONDS_REGEX.test(format);
98
+ return SECONDS_REGEX.test(format.replace(/'[^']*'|"[^"]*"/g, ''));
100
99
  },
101
100
  this.selectedDateNode
102
101
  );
@@ -209,7 +208,7 @@ export default class RdfaDatePluginCardComponent extends Component<Args> {
209
208
  return tr
210
209
  .setNodeAttribute(pos, 'format', dateFormat)
211
210
  .setNodeAttribute(pos, 'custom', custom)
212
- .setNodeAttribute(pos, 'onlyDate', this.onlyDate);
211
+ .setNodeAttribute(pos, 'onlyDate', !formatContainsTime(dateFormat));
213
212
  }, true);
214
213
  }
215
214
 
@@ -243,7 +242,7 @@ export default class RdfaDatePluginCardComponent extends Component<Args> {
243
242
  this.controller.withTransaction((tr) => {
244
243
  return tr
245
244
  .setNodeAttribute(pos, 'format', format)
246
- .setNodeAttribute(pos, 'onlyDate', this.onlyDate);
245
+ .setNodeAttribute(pos, 'onlyDate', !formatContainsTime(format));
247
246
  }, true);
248
247
  }
249
248
  }
@@ -1,6 +1,7 @@
1
1
  import { findParentNodeOfType } from '@curvenote/prosemirror-utils';
2
2
  import { Command, NodeSelection } from '@lblod/ember-rdfa-editor';
3
3
  import IntlService from 'ember-intl/services/intl';
4
+ import { v4 as uuid } from 'uuid';
4
5
 
5
6
  export default function insertTitle(intl: IntlService): Command {
6
7
  return function (state, dispatch) {
@@ -19,7 +20,7 @@ export default function insertTitle(intl: IntlService): Command {
19
20
  besluit.pos + 1,
20
21
  schema.node(
21
22
  'title',
22
- null,
23
+ { __rdfaId: uuid() },
23
24
  schema.node(
24
25
  'paragraph',
25
26
  null,
@@ -19,31 +19,82 @@ import { changedDescendants } from '@lblod/ember-rdfa-editor-lblod-plugins/utils
19
19
 
20
20
  const BASIC_MULTIPLANE_CHARACTER = '\u0021-\uFFFF'; // most of the characters used around the world
21
21
 
22
- // Regex nicely structured:
23
- // (
24
- // (
25
- // \w*decreet |
26
- // omzendbrief |
27
- // verdrag |
28
- // grondwetswijziging |
29
- // samenwerkingsakkoord |
30
- // \w*wetboek |
31
- // protocol |
32
- // besluit[^\S\n]van[^\S\n]de[^\S\n]vlaamse[^\S\n]regering |
33
- // geco[öo]rdineerde wetten |
34
- // \w*wet |
35
- // koninklijk[^\S\n]?besluit |
36
- // ministerieel[^\S\n]?besluit |
37
- // genummerd[^\S\n]?koninklijk[^\S\n]?besluit
38
- // )
39
- // [^\S\n]*
40
- // (
41
- // ([^\S\n] | [\u0021-\uFFFF\d;:'"()&\-_]){3,}
42
- // )?
43
- // )
22
+ /**
23
+ * regex for non-newline whitespace
24
+ */
44
25
  const NNWS = '[^\\S\\n]';
26
+
27
+ /**
28
+ * match for a "decree"
29
+ * the "t" at the end is not a typo
30
+ */
31
+ const DECREE = `\\w*decreet`;
32
+
33
+ /**
34
+ * literally "letter that gets sent around"
35
+ */
36
+ const MEMO = `omzendbrief`;
37
+ const TREATY = `verdrag`;
38
+ const CONSTITUTION_CHANGE = `grondwetswijziging`;
39
+ /**
40
+ * literally "agreement to collaborate"
41
+ */
42
+ const COLLAB = `samenwerkingsakkoord`;
43
+ /**
44
+ * Literally "book of law", I suppose that's called a codex?
45
+ */
46
+ const BOOK = `\\w*wetboek`;
47
+ const PROTOCOL = `protocol`;
48
+ /**
49
+ * match for the literal "of the flemish government"
50
+ */
51
+ const VVR = `${NNWS}van${NNWS}de${NNWS}vlaamse${NNWS}regering`;
52
+ /**
53
+ * match for the literal "decision of the flemish government"
54
+ */
55
+ const FLEMGOV = `besluit${VVR}`;
56
+ /**
57
+ * match for "coordinated laws"
58
+ * whatever that may be
59
+ */
60
+ const COORD = `geco[öo]rdineerde${NNWS}wet(ten)?`;
61
+ /**
62
+ * literally "special law"
63
+ */
64
+ const SPECIAL = `bijzondere${NNWS}wet`;
65
+ /**
66
+ * Matches any kind of law
67
+ */
68
+ const LAW = `\\w*wet`;
69
+ /**
70
+ * match for the literal "royal decision"
71
+ * "royal decree" might be a more meaningful translation to english, but don't read too much into these
72
+ * translations anyway
73
+ */
74
+ const ROYAL = `koninklijk${NNWS}?besluit`;
75
+ /**
76
+ * same thing as above, but for ministers
77
+ */
78
+ const MINISTERIAL = `ministerieel${NNWS}?besluit`;
79
+ /**
80
+ * match for "enumerated royal decision"
81
+ * no, we don't know the difference either
82
+ */
83
+ const ENUM_ROYAL = `genummerd${NNWS}?${ROYAL}`;
84
+
85
+ /**
86
+ * The type of citation that we need to search for
87
+ */
88
+ const TYPE = `${DECREE}|${MEMO}|${TREATY}|${CONSTITUTION_CHANGE}|${COLLAB}|${BOOK}|${PROTOCOL}|${FLEMGOV}|${COORD}|${SPECIAL}|${LAW}|${ROYAL}|${MINISTERIAL}|${ENUM_ROYAL}`;
89
+ /**
90
+ * The monster regex that makes the citation plugin trigger.
91
+ * In restructuring, I've made sure that I didn't abstract away any of the capturing groups,
92
+ * only their content, so you can still see what's going on
93
+ *
94
+ * This regex uses named capturing groups, that's the "?<name>" syntax, for easy parsing later
95
+ */
45
96
  export const CITATION_REGEX = new RegExp(
46
- `((?<type>\\w*decreet|omzendbrief|verdrag|grondwetswijziging|samenwerkingsakkoord|\\w*wetboek|protocol|besluit${NNWS}van${NNWS}de${NNWS}vlaamse${NNWS}regering|geco[öo]rdineerde${NNWS}wetten|\\w*wet|koninklijk${NNWS}?besluit|ministerieel${NNWS}?besluit|genummerd${NNWS}?koninklijk${NNWS}?besluit|\\w*${NNWS}?besluit)${NNWS}*(?<searchTerms>(${NNWS}|[${BASIC_MULTIPLANE_CHARACTER};:'"()&-_]){3,})?)`,
97
+ `((?<type>${TYPE})${NNWS}*(?<searchTerms>(${NNWS}|[${BASIC_MULTIPLANE_CHARACTER};:'"()&-_]){3,})?)`,
47
98
  'uidg'
48
99
  );
49
100
  export type CitationSchema = Schema<string, 'citation'>;
@@ -116,6 +167,7 @@ export function setupCitationPlugin(
116
167
  desiredLocation: 'insertSidebar',
117
168
  componentName: 'citation-plugin/citation-insert',
118
169
  widgetArgs: {
170
+ config,
119
171
  plugin,
120
172
  },
121
173
  },
@@ -132,8 +184,13 @@ function citationPlugin(config: CitationPluginConfig): CitationPlugin {
132
184
  init(stateConfig: EditorStateConfig, state: EditorState) {
133
185
  return calculateCitationPluginState(state, config);
134
186
  },
135
- apply(tr, set, oldState, newState) {
136
- return calculateCitationPluginState(newState, config, oldState);
187
+ apply(tr, oldPluginState, oldState, newState) {
188
+ return calculateCitationPluginState(
189
+ newState,
190
+ config,
191
+ oldState,
192
+ oldPluginState.highlights.map(tr.mapping, tr.doc)
193
+ );
137
194
  },
138
195
  },
139
196
  props: {
@@ -148,7 +205,8 @@ function citationPlugin(config: CitationPluginConfig): CitationPlugin {
148
205
  function calculateCitationPluginState(
149
206
  state: EditorState,
150
207
  config: CitationPluginConfig,
151
- oldState?: EditorState
208
+ oldState?: EditorState,
209
+ oldDecs?: DecorationSet
152
210
  ) {
153
211
  const { doc, schema } = state;
154
212
  let activeRanges;
@@ -169,7 +227,8 @@ function calculateCitationPluginState(
169
227
  schema,
170
228
  nodes,
171
229
  doc,
172
- oldState?.doc
230
+ oldState?.doc,
231
+ oldDecs
173
232
  );
174
233
  activeRanges = calculatedDecs.activeRanges;
175
234
  highlights = calculatedDecs.decorations;
@@ -185,11 +244,19 @@ function calculateDecorationsInNodes(
185
244
  schema: CitationSchema,
186
245
  nodes: Set<NodeType>,
187
246
  newDoc: PNode,
188
- oldDoc?: PNode
247
+ oldDoc?: PNode,
248
+ oldDecorations?: DecorationSet
189
249
  ): { decorations: DecorationSet; activeRanges: [number, number][] } {
190
250
  const activeRanges: [number, number][] = [];
191
- const decorations: Decoration[] = [];
192
- const collector = collectDecorations(decorations, schema, config.regex);
251
+ const decsToAdd: Decoration[] = [];
252
+ const decsToRemove: Decoration[] = [];
253
+ const collector = collectDecorations(
254
+ decsToAdd,
255
+ schema,
256
+ config.regex,
257
+ decsToRemove,
258
+ oldDecorations
259
+ );
193
260
  if (nodes.has(newDoc.type)) {
194
261
  oldDoc
195
262
  ? changedDescendants(oldDoc, newDoc, 0, collector)
@@ -221,7 +288,9 @@ function calculateDecorationsInNodes(
221
288
  });
222
289
  }
223
290
  return {
224
- decorations: DecorationSet.create(newDoc, decorations),
291
+ decorations: oldDecorations
292
+ ? oldDecorations.remove(decsToRemove).add(newDoc, decsToAdd)
293
+ : DecorationSet.create(newDoc, decsToAdd),
225
294
  activeRanges,
226
295
  };
227
296
  }
@@ -232,22 +301,24 @@ function calculateDecorationsInRanges(
232
301
  doc: PNode,
233
302
  activeRanges: [number, number][]
234
303
  ): { decorations: DecorationSet; activeRanges: [number, number][] } {
235
- const decorations: Decoration[] = [];
236
- const collector = collectDecorations(decorations, schema, config.regex);
304
+ const decorationsToAdd: Decoration[] = [];
305
+ const collector = collectDecorations(decorationsToAdd, schema, config.regex);
237
306
 
238
307
  for (const [start, end] of activeRanges) {
239
308
  doc.nodesBetween(start, end, collector);
240
309
  }
241
310
  return {
242
- decorations: DecorationSet.create(doc, decorations),
311
+ decorations: DecorationSet.create(doc, decorationsToAdd),
243
312
  activeRanges: activeRanges,
244
313
  };
245
314
  }
246
315
 
247
316
  function collectDecorations(
248
- decorations: Decoration[],
317
+ decsToAdd: Decoration[],
249
318
  schema: CitationSchema,
250
- regex: RegExp = CITATION_REGEX
319
+ regex: RegExp = CITATION_REGEX,
320
+ decsToRemove?: Decoration[],
321
+ oldDecs?: DecorationSet
251
322
  ) {
252
323
  return function (node: PNode, pos: number): boolean {
253
324
  if (
@@ -255,6 +326,17 @@ function collectDecorations(
255
326
  node.text &&
256
327
  !schema.marks.citation.isInSet(node.marks)
257
328
  ) {
329
+ if (decsToRemove && oldDecs) {
330
+ decsToRemove.push(
331
+ ...oldDecs.find(
332
+ pos,
333
+ pos + node.nodeSize,
334
+ (spec) =>
335
+ (spec as Record<string, string>).name === 'citationHighlight'
336
+ )
337
+ );
338
+ }
339
+
258
340
  for (const match of node.text.matchAll(regex)) {
259
341
  const processedMatch = processMatch(
260
342
  match as RegexpMatchArrayWithIndices
@@ -265,7 +347,7 @@ function collectDecorations(
265
347
  const { start: matchStart, end: matchEnd } = searchTextMatch;
266
348
  const decorationStart = pos + matchStart;
267
349
  const decorationEnd = pos + matchEnd;
268
- decorations.push(
350
+ decsToAdd.push(
269
351
  Decoration.inline(
270
352
  decorationStart,
271
353
  decorationEnd,
@@ -274,6 +356,7 @@ function collectDecorations(
274
356
  'data-editor-highlight': 'true',
275
357
  },
276
358
  {
359
+ name: 'citationHighlight',
277
360
  searchText: text,
278
361
  legislationTypeUri,
279
362
  }
@@ -1,6 +1,7 @@
1
1
  import { PNode } from '@lblod/ember-rdfa-editor';
2
2
  import { CitationSchema } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin';
3
3
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
4
+ import { v4 as uuid } from 'uuid';
4
5
 
5
6
  export function citedText(
6
7
  schema: CitationSchema,
@@ -12,6 +13,7 @@ export function citedText(
12
13
  href: uri,
13
14
  property: 'eli:cites',
14
15
  typeof: 'eli:LegalExpression',
16
+ __rdfaId: uuid(),
15
17
  }),
16
18
  ]);
17
19
  }
@@ -16,8 +16,9 @@ const LEGISLATION_TYPES = {
16
16
  samenwerkingsakkoord:
17
17
  'https://data.vlaanderen.be/id/concept/AardWetgeving/Samenwerkingsakkoord',
18
18
  wetboek: 'https://data.vlaanderen.be/id/concept/AardWetgeving/Wetboek',
19
+ // do not change this url without doublechecking, yes they actually did encode the ö in the url
19
20
  'gecoördineerde wetten':
20
- 'https://data.vlaanderen.be/id/concept/AardWetgeving/GecoordineerdeWetten',
21
+ 'https://data.vlaanderen.be/id/concept/AardWetgeving/Geco%C3%B6rdineerde+Wet',
21
22
  'bijzondere wet':
22
23
  'https://data.vlaanderen.be/id/concept/AardWetgeving/BijzondereWet',
23
24
  'genummerd koninklijk besluit':
@@ -1,11 +1,12 @@
1
1
  import { isBlank } from '@ember/utils';
2
- import { LEGISLATION_TYPES, LegislationKey } from './legislation-types';
2
+ import { LEGISLATION_TYPES } from './legislation-types';
3
3
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
4
4
 
5
5
  const STOP_WORDS = ['het', 'de', 'van', 'tot', 'dat'];
6
6
  const DATE_REGEX = new RegExp('(\\d{1,2})\\s(\\w+)\\s(\\d{2,4})', 'g');
7
7
  const INVISIBLE_SPACE = '\u200B';
8
- const SPACES_REGEX = new RegExp('[\\s${UNBREAKABLE_SPACE}]+');
8
+ const UNBREAKABLE_SPACE = '\u00A0';
9
+ const SPACES_REGEX = new RegExp(`[\\s${UNBREAKABLE_SPACE}]+`);
9
10
  export type RegexpMatchArrayWithIndices = RegExpMatchArray & {
10
11
  indices: Array<[number, number]> & {
11
12
  groups: { [key: string]: [number, number] };
@@ -46,7 +47,7 @@ export default function processMatch(
46
47
  )
47
48
  .join(' ');
48
49
  if (type) {
49
- let typeLabel: LegislationKey;
50
+ let typeLabel: string;
50
51
  if (/\w+decreet/i.test(type)) {
51
52
  typeLabel = 'decreet';
52
53
  cleanedSearchTerms = `${type} ${cleanedSearchTerms}`;
@@ -57,21 +58,25 @@ export default function processMatch(
57
58
  cleanedSearchTerms = `${type} ${cleanedSearchTerms}`;
58
59
  } else if (/wetboek/i.test(type)) {
59
60
  typeLabel = 'wetboek';
60
- } else if (/geco[oö]rdineerde[^\S\n]wetten/i.test(type)) {
61
+ } else if (/geco[oö]rdineerde[^\S\n]wet(ten)?/i.test(type)) {
61
62
  typeLabel = 'gecoördineerde wetten';
62
- } else if (/grondwetswijziging/i.test(type)) {
63
+ } else if (/grondwets?wijziging/i.test(type)) {
63
64
  typeLabel = 'grondwetswijziging';
64
65
  } else if (/grondwet/i.test(type)) {
65
66
  typeLabel = 'grondwet';
67
+ } else if (/bijzondere[^\S\n]wet/i.test(type)) {
68
+ typeLabel = 'bijzondere wet';
66
69
  } else if (/\w+wet/i.test(type)) {
67
70
  typeLabel = 'wet';
68
71
  cleanedSearchTerms = `${type} ${cleanedSearchTerms}`;
69
72
  } else if (/wet/i.test(type)) {
70
73
  typeLabel = 'wet';
71
74
  } else {
72
- typeLabel = 'decreet';
75
+ typeLabel = type.toLowerCase().trim();
73
76
  }
74
- const typeUri = LEGISLATION_TYPES[typeLabel];
77
+ const typeUri =
78
+ (LEGISLATION_TYPES as Record<string, string>)[typeLabel] ||
79
+ LEGISLATION_TYPES['decreet'];
75
80
  return {
76
81
  text: cleanedSearchTerms,
77
82
  legislationTypeUri: typeUri,
@@ -2,6 +2,8 @@ import { formatWithOptions } from 'date-fns/fp';
2
2
  import { nlBE } from 'date-fns/locale';
3
3
  import { RegexpMatchArrayWithIndices } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin/utils/process-match';
4
4
 
5
+ const TIME_CHAR_REGEX = new RegExp('[abBhHkKmsStTp]');
6
+
5
7
  export function formatDate(date: Date, format: string) {
6
8
  try {
7
9
  return formatWithOptions({ locale: nlBE }, format)(date);
@@ -10,6 +12,10 @@ export function formatDate(date: Date, format: string) {
10
12
  }
11
13
  }
12
14
 
15
+ export function formatContainsTime(format: string) {
16
+ return TIME_CHAR_REGEX.test(format.replace(/'[^']*'|"[^"]*"/g, ''));
17
+ }
18
+
13
19
  type ValidationErrorType =
14
20
  | 'date'
15
21
  | 'locale'
@@ -20,6 +20,7 @@ export const title: NodeSpec = {
20
20
  content: 'paragraph+',
21
21
  inline: false,
22
22
  defining: true,
23
+ canSplit: false,
23
24
  attrs: {
24
25
  ...rdfaAttrs,
25
26
  property: {
@@ -49,6 +50,7 @@ export const description: NodeSpec = {
49
50
  group: 'block',
50
51
  content: 'block+',
51
52
  inline: false,
53
+ canSplit: false,
52
54
  attrs: {
53
55
  ...rdfaAttrs,
54
56
  property: {
@@ -78,6 +80,7 @@ export const motivering: NodeSpec = {
78
80
  group: 'block',
79
81
  content: 'block+',
80
82
  inline: false,
83
+ canSplit: false,
81
84
  attrs: {
82
85
  ...rdfaAttrs,
83
86
  property: {
@@ -107,6 +110,7 @@ export const article_container: NodeSpec = {
107
110
  group: 'block',
108
111
  content: '(block|besluit_article)+',
109
112
  inline: false,
113
+ canSplit: false,
110
114
  attrs: {
111
115
  ...rdfaAttrs,
112
116
  property: {
@@ -183,12 +187,18 @@ export const besluitArticleStructure: StructureSpec = {
183
187
  const numberConverted = number?.toString() ?? '1';
184
188
  const node = schema.node(
185
189
  `besluit_article`,
186
- { resource: `http://data.lblod.info/articles/${uuid()}` },
190
+ {
191
+ resource: `http://data.lblod.info/articles/${uuid()}`,
192
+ __rdfaId: uuid(),
193
+ },
187
194
  [
188
- schema.node('besluit_article_header', { number: numberConverted }),
195
+ schema.node('besluit_article_header', {
196
+ number: numberConverted,
197
+ __rdfaId: uuid(),
198
+ }),
189
199
  schema.node(
190
200
  `besluit_article_content`,
191
- {},
201
+ { __rdfaId: uuid() },
192
202
  content ??
193
203
  schema.node(
194
204
  'paragraph',
@@ -301,6 +311,8 @@ export const besluit: NodeSpec = {
301
311
  content: 'block*title?block*description?block*motivering?block*',
302
312
  inline: false,
303
313
  defining: true,
314
+ isolating: true,
315
+ canSplit: false,
304
316
  attrs: {
305
317
  ...rdfaAttrs,
306
318
  property: {
@@ -1,11 +1,12 @@
1
1
  import Component from '@glimmer/component';
2
2
  import { ProseController } from '@lblod/ember-rdfa-editor';
3
3
  import { Article, Decision } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin/utils/vlaamse-codex';
4
- import { CitationPlugin } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin';
4
+ import { CitationPlugin, CitationPluginConfig } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/citation-plugin';
5
5
  interface Args {
6
6
  controller: ProseController;
7
7
  widgetArgs: {
8
8
  plugin: CitationPlugin;
9
+ config: CitationPluginConfig;
9
10
  };
10
11
  }
11
12
  export default class EditorPluginsCitationInsertComponent extends Component<Args> {
@@ -13,6 +14,7 @@ export default class EditorPluginsCitationInsertComponent extends Component<Args
13
14
  legislationTypeUri: string;
14
15
  text: string;
15
16
  legislationType: string | null;
17
+ get config(): CitationPluginConfig;
16
18
  get selectedLegislationTypeUri(): string;
17
19
  get selectedLegislationType(): {
18
20
  label: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lblod/ember-rdfa-editor-lblod-plugins",
3
- "version": "2.0.1",
3
+ "version": "2.1.1",
4
4
  "description": "Ember addon providing lblod specific plugins for the ember-rdfa-editor",
5
5
  "keywords": [
6
6
  "ember-addon",
@@ -63,10 +63,11 @@
63
63
  "@embroider/test-setup": "^1.6.0",
64
64
  "@glimmer/component": "^1.1.2",
65
65
  "@glimmer/tracking": "^1.1.2",
66
- "@lblod/ember-rdfa-editor": "^2.0.1",
66
+ "@lblod/ember-rdfa-editor": "^2.1.2",
67
67
  "@rdfjs/types": "^1.1.0",
68
- "@release-it-plugins/lerna-changelog": "^5.0.0",
68
+ "@release-it/keep-a-changelog": "^3.1.0",
69
69
  "@tsconfig/ember": "^1.0.1",
70
+ "@types/debug": "^4.1.7",
70
71
  "@types/ember": "^4.0.2",
71
72
  "@types/ember__application": "^4.0.4",
72
73
  "@types/ember__array": "^4.0.3",
@@ -145,14 +146,14 @@
145
146
  },
146
147
  "peerDependencies": {
147
148
  "@appuniversum/ember-appuniversum": "^2.2.0",
148
- "@lblod/ember-rdfa-editor": "^2.0.1",
149
+ "@lblod/ember-rdfa-editor": "^2.1.2",
149
150
  "ember-concurrency": "^2.3.7"
150
151
  },
151
152
  "engines": {
152
153
  "node": "12.* || 14.* || >= 16"
153
154
  },
154
155
  "volta": {
155
- "node": "16.18.1"
156
+ "node": "18.14.0"
156
157
  },
157
158
  "ember": {
158
159
  "edition": "octane"
@@ -1,4 +1,11 @@
1
1
  import { Decoration, DecorationSet, EditorState, InlineDecorationSpec, MarkSpec, NodeType, ProsePlugin, Schema, WidgetSpec } from '@lblod/ember-rdfa-editor';
2
+ /**
3
+ * The monster regex that makes the citation plugin trigger.
4
+ * In restructuring, I've made sure that I didn't abstract away any of the capturing groups,
5
+ * only their content, so you can still see what's going on
6
+ *
7
+ * This regex uses named capturing groups, that's the "?<name>" syntax, for easy parsing later
8
+ */
2
9
  export declare const CITATION_REGEX: RegExp;
3
10
  export type CitationSchema = Schema<string, 'citation'>;
4
11
  export interface CitationDecorationSpec extends InlineDecorationSpec {
@@ -1,4 +1,5 @@
1
1
  export declare function formatDate(date: Date, format: string): string;
2
+ export declare function formatContainsTime(format: string): boolean;
2
3
  type ValidationErrorType = 'date' | 'locale' | 'use-yyyy' | 'use-yy' | 'use-d' | 'use-dd' | 'character' | 'required' | 'fractions' | 'unknown';
3
4
  interface ValidationOk {
4
5
  type: 'ok';