@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 +6 -4
- package/CHANGELOG.md +32 -2
- package/addon/components/citation-plugin/citation-insert.ts +27 -7
- package/addon/components/rdfa-date-plugin/card.ts +5 -6
- package/addon/plugins/besluit-plugin/commands/insert-title.ts +2 -1
- package/addon/plugins/citation-plugin/index.ts +120 -37
- package/addon/plugins/citation-plugin/utils/cited-text.ts +2 -0
- package/addon/plugins/citation-plugin/utils/legislation-types.ts +2 -1
- package/addon/plugins/citation-plugin/utils/process-match.ts +12 -7
- package/addon/plugins/rdfa-date-plugin/utils.ts +6 -0
- package/addon/plugins/standard-template-plugin/utils/nodes.ts +15 -3
- package/components/citation-plugin/citation-insert.d.ts +3 -1
- package/package.json +6 -5
- package/plugins/citation-plugin/index.d.ts +7 -0
- package/plugins/rdfa-date-plugin/utils.d.ts +1 -0
package/.release-it.json
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
"release": true
|
|
4
4
|
},
|
|
5
5
|
"plugins": {
|
|
6
|
-
"@release-it
|
|
7
|
-
"
|
|
8
|
-
"
|
|
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 {
|
|
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 (
|
|
63
|
+
if (this.controller.inEmbeddedView) {
|
|
56
64
|
return true;
|
|
57
65
|
}
|
|
58
|
-
const {
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
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',
|
|
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',
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
136
|
-
return calculateCitationPluginState(
|
|
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
|
|
192
|
-
const
|
|
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:
|
|
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
|
|
236
|
-
const collector = collectDecorations(
|
|
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,
|
|
311
|
+
decorations: DecorationSet.create(doc, decorationsToAdd),
|
|
243
312
|
activeRanges: activeRanges,
|
|
244
313
|
};
|
|
245
314
|
}
|
|
246
315
|
|
|
247
316
|
function collectDecorations(
|
|
248
|
-
|
|
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
|
-
|
|
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/
|
|
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
|
|
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
|
|
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:
|
|
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]
|
|
61
|
+
} else if (/geco[oö]rdineerde[^\S\n]wet(ten)?/i.test(type)) {
|
|
61
62
|
typeLabel = 'gecoördineerde wetten';
|
|
62
|
-
} else if (/
|
|
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 =
|
|
75
|
+
typeLabel = type.toLowerCase().trim();
|
|
73
76
|
}
|
|
74
|
-
const typeUri =
|
|
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
|
-
{
|
|
190
|
+
{
|
|
191
|
+
resource: `http://data.lblod.info/articles/${uuid()}`,
|
|
192
|
+
__rdfaId: uuid(),
|
|
193
|
+
},
|
|
187
194
|
[
|
|
188
|
-
schema.node('besluit_article_header', {
|
|
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.
|
|
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.
|
|
66
|
+
"@lblod/ember-rdfa-editor": "^2.1.2",
|
|
67
67
|
"@rdfjs/types": "^1.1.0",
|
|
68
|
-
"@release-it
|
|
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.
|
|
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": "
|
|
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';
|