@lblod/ember-rdfa-editor-lblod-plugins 16.0.0 → 16.1.0

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.
Files changed (33) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +9 -0
  3. package/addon/components/article-structure-plugin/structure-card.hbs +33 -0
  4. package/addon/components/article-structure-plugin/structure-card.ts +53 -0
  5. package/addon/plugins/article-structure-plugin/commands/index.ts +1 -0
  6. package/addon/plugins/article-structure-plugin/commands/recalculate-structure-numbers.ts +7 -0
  7. package/addon/plugins/article-structure-plugin/commands/set-structure-start-number.ts +43 -0
  8. package/addon/plugins/article-structure-plugin/index.ts +10 -0
  9. package/addon/plugins/article-structure-plugin/structures/article-paragraph.ts +23 -18
  10. package/addon/plugins/article-structure-plugin/structures/article.ts +19 -19
  11. package/addon/plugins/article-structure-plugin/structures/chapter.ts +3 -7
  12. package/addon/plugins/article-structure-plugin/structures/section.ts +3 -7
  13. package/addon/plugins/article-structure-plugin/structures/structure-header.ts +22 -15
  14. package/addon/plugins/article-structure-plugin/structures/subsection.ts +3 -7
  15. package/addon/plugins/article-structure-plugin/structures/title.ts +3 -7
  16. package/addon/plugins/article-structure-plugin/utils/romanize.ts +85 -0
  17. package/addon/plugins/article-structure-plugin/utils/structure.ts +133 -51
  18. package/addon/plugins/standard-template-plugin/utils/nodes.ts +31 -23
  19. package/addon/plugins/template-comments-plugin/node.ts +4 -3
  20. package/addon/utils/translation.ts +35 -0
  21. package/app/styles/citaten-plugin.scss +0 -2
  22. package/app/styles/confidentiality-plugin.scss +0 -2
  23. package/app/styles/template-comments-plugin.scss +3 -2
  24. package/components/article-structure-plugin/structure-card.d.ts +7 -0
  25. package/package.json +4 -4
  26. package/plugins/article-structure-plugin/commands/index.d.ts +1 -0
  27. package/plugins/article-structure-plugin/commands/set-structure-start-number.d.ts +4 -0
  28. package/plugins/article-structure-plugin/index.d.ts +13 -0
  29. package/plugins/article-structure-plugin/utils/romanize.d.ts +5 -0
  30. package/plugins/article-structure-plugin/utils/structure.d.ts +16 -3
  31. package/translations/en-US.yaml +4 -0
  32. package/translations/nl-BE.yaml +4 -0
  33. package/utils/translation.d.ts +5 -0
@@ -0,0 +1,85 @@
1
+ export function romanize(num: number) {
2
+ if (isNaN(num)) throw new Error('Provided number is NaN');
3
+ const digits = String(+num).split('');
4
+ const key = [
5
+ '',
6
+ 'C',
7
+ 'CC',
8
+ 'CCC',
9
+ 'CD',
10
+ 'D',
11
+ 'DC',
12
+ 'DCC',
13
+ 'DCCC',
14
+ 'CM',
15
+ '',
16
+ 'X',
17
+ 'XX',
18
+ 'XXX',
19
+ 'XL',
20
+ 'L',
21
+ 'LX',
22
+ 'LXX',
23
+ 'LXXX',
24
+ 'XC',
25
+ '',
26
+ 'I',
27
+ 'II',
28
+ 'III',
29
+ 'IV',
30
+ 'V',
31
+ 'VI',
32
+ 'VII',
33
+ 'VIII',
34
+ 'IX',
35
+ ];
36
+ let roman = '';
37
+ let i = 3;
38
+ while (i--) {
39
+ const digit = digits.pop();
40
+ if (digit) {
41
+ roman = (key[Number(digit) + i * 10] || '') + roman;
42
+ }
43
+ }
44
+ return Array(+digits.join('') + 1).join('M') + roman;
45
+ }
46
+
47
+ const subs: Record<string, string> = {
48
+ V: 'I',
49
+ X: 'I',
50
+ L: 'X',
51
+ C: 'X',
52
+ D: 'C',
53
+ M: 'C',
54
+ };
55
+
56
+ const lookup: Record<string, number> = {
57
+ I: 1,
58
+ V: 5,
59
+ X: 10,
60
+ L: 50,
61
+ C: 100,
62
+ D: 500,
63
+ M: 1000,
64
+ };
65
+
66
+ /**
67
+ * @link https://gist.github.com/briansunter/ec7af91065d79a2f790fcd76a2a08a84
68
+ */
69
+ export function romanToInt(romanString: string) {
70
+ let total = 0;
71
+
72
+ for (let x = 0; x < romanString.length; x++) {
73
+ const fst = romanString[x];
74
+ const snd = romanString[x + 1];
75
+ if (fst === subs[snd]) {
76
+ total = total + lookup[snd] - lookup[fst];
77
+ x++;
78
+ } else if (!snd) {
79
+ total = total + lookup[fst];
80
+ } else {
81
+ total = total + lookup[fst];
82
+ }
83
+ }
84
+ return total;
85
+ }
@@ -1,4 +1,5 @@
1
1
  import {
2
+ DOMOutputSpec,
2
3
  NodeSpec,
3
4
  NodeType,
4
5
  PNode,
@@ -10,11 +11,18 @@ import {
10
11
  ELI,
11
12
  RDF,
12
13
  SAY,
14
+ XSD,
13
15
  } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
14
16
  import {
15
17
  hasRDFaAttribute,
16
18
  Resource,
17
19
  } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
20
+ import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
21
+ import { StructureSpec } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/article-structure-plugin';
22
+ import {
23
+ romanize,
24
+ romanToInt,
25
+ } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/article-structure-plugin/utils/romanize';
18
26
 
19
27
  export function constructStructureNodeSpec(config: {
20
28
  type: Resource;
@@ -120,63 +128,59 @@ export function findAncestorOfType(selection: Selection, ...types: NodeType[]) {
120
128
  return;
121
129
  }
122
130
 
123
- export function getStructureHeaderAttrs(element: HTMLElement) {
124
- const numberNode = element.querySelector(
125
- `[property~="${ELI('number').prefixed}"],
126
- [property~="${ELI('number').full}"]`,
127
- );
128
- if (hasRDFaAttribute(element, 'property', SAY('heading')) && numberNode) {
131
+ export function getNumberAttributeFromElement(
132
+ containerElement: Element,
133
+ numberElement: Element,
134
+ ): {
135
+ number: number;
136
+ numberDisplayStyle: string;
137
+ startNumber: number | null;
138
+ } {
139
+ // Storing the number in the content attribute was not introduced straight away,
140
+ // so we need to check for both the content attribute and the textContent.
141
+ const contentAttribute = numberElement.getAttribute('content');
142
+
143
+ // If the content attribute is present, we can assume it is the correct number.
144
+ if (contentAttribute) {
129
145
  return {
130
- number: numberNode.textContent,
146
+ number: parseInt(contentAttribute, 10),
147
+ ...getNodeNumberAttrsFromElement(containerElement),
131
148
  };
132
149
  }
133
- return false;
150
+
151
+ const textContentNumber = numberElement.textContent;
152
+
153
+ if (!textContentNumber) {
154
+ return { number: 1, ...getNodeNumberAttrsFromElement(containerElement) };
155
+ }
156
+
157
+ // If the textContent is a number, we can assume it is the correct number.
158
+ if (/^[0-9]+$/.exec(textContentNumber)) {
159
+ return {
160
+ number: parseInt(textContentNumber, 10),
161
+ ...getNodeNumberAttrsFromElement(containerElement),
162
+ };
163
+ }
164
+
165
+ // Otherwise, we assume it is a roman number.
166
+ return {
167
+ number: romanToInt(textContentNumber),
168
+ ...getNodeNumberAttrsFromElement(containerElement),
169
+ numberDisplayStyle: 'roman',
170
+ };
134
171
  }
135
172
 
136
- export function romanize(num: number) {
137
- if (isNaN(num)) throw new Error('Provided number is NaN');
138
- const digits = String(+num).split('');
139
- const key = [
140
- '',
141
- 'C',
142
- 'CC',
143
- 'CCC',
144
- 'CD',
145
- 'D',
146
- 'DC',
147
- 'DCC',
148
- 'DCCC',
149
- 'CM',
150
- '',
151
- 'X',
152
- 'XX',
153
- 'XXX',
154
- 'XL',
155
- 'L',
156
- 'LX',
157
- 'LXX',
158
- 'LXXX',
159
- 'XC',
160
- '',
161
- 'I',
162
- 'II',
163
- 'III',
164
- 'IV',
165
- 'V',
166
- 'VI',
167
- 'VII',
168
- 'VIII',
169
- 'IX',
170
- ];
171
- let roman = '';
172
- let i = 3;
173
- while (i--) {
174
- const digit = digits.pop();
175
- if (digit) {
176
- roman = (key[Number(digit) + i * 10] || '') + roman;
177
- }
173
+ export function getStructureHeaderAttrs(element: HTMLElement) {
174
+ const numberElement = element.querySelector(
175
+ `[property~="${ELI('number').prefixed}"],
176
+ [property~="${ELI('number').full}"]`,
177
+ );
178
+
179
+ if (hasRDFaAttribute(element, 'property', SAY('heading')) && numberElement) {
180
+ return getNumberAttributeFromElement(element, numberElement);
178
181
  }
179
- return Array(+digits.join('') + 1).join('M') + roman;
182
+
183
+ return false;
180
184
  }
181
185
 
182
186
  export function containsOnlyPlaceholder(schema: Schema, node: PNode) {
@@ -186,3 +190,81 @@ export function containsOnlyPlaceholder(schema: Schema, node: PNode) {
186
190
  node.firstChild.firstChild?.type === schema.nodes['placeholder']
187
191
  );
188
192
  }
193
+
194
+ export const getNumberAttributesFromNode = (node: PNode) => ({
195
+ ['data-start-number']: node.attrs.startNumber
196
+ ? `${node.attrs.startNumber}`
197
+ : null,
198
+ ['data-number-display-style']: node.attrs.numberDisplayStyle as string,
199
+ });
200
+
201
+ export const getNumberDocSpecFromNode = (node: PNode): DOMOutputSpec => [
202
+ 'span',
203
+ {
204
+ property: ELI('number').prefixed,
205
+ datatype: XSD('integer').prefixed,
206
+ content: node.attrs.number as string,
207
+ contenteditable: false,
208
+ },
209
+ node.attrs.numberDisplayStyle === 'roman'
210
+ ? romanize(node.attrs.number ?? '1')
211
+ : `${node.attrs.number ?? '1'}`,
212
+ ];
213
+
214
+ const getNodeNumberAttrsFromElement = (element: Element) => {
215
+ const startNumber = element.getAttribute('data-start-number');
216
+ const numberDisplayStyle = element.getAttribute('data-number-display-style');
217
+
218
+ return {
219
+ numberDisplayStyle: numberDisplayStyle ?? 'decimal',
220
+ startNumber: startNumber ? parseInt(startNumber, 10) : null,
221
+ };
222
+ };
223
+
224
+ export const getNumberUtils = (
225
+ // Offset for the position of the node where the starting number is stored.
226
+ // For structures with `structure_header` it will usually be +1,
227
+ // for `articleParagraph` it is 0.
228
+ offset = 0,
229
+ ): Pick<
230
+ StructureSpec,
231
+ 'setStartNumber' | 'getStartNumber' | 'getNumber' | 'updateNumber'
232
+ > => ({
233
+ updateNumber: ({ number, pos, transaction }) => {
234
+ return transaction.setNodeAttribute(pos + offset, 'number', number);
235
+ },
236
+ getNumber: ({ pos, transaction }) => {
237
+ const node = unwrap(transaction.doc.nodeAt(pos + offset));
238
+ const number = node.attrs.number as string | number | undefined | null;
239
+
240
+ if (typeof number === 'string' && number.length > 0) {
241
+ return parseInt(number, 10);
242
+ }
243
+
244
+ if (typeof number === 'number') {
245
+ return number;
246
+ }
247
+
248
+ return null;
249
+ },
250
+ getStartNumber: ({ pos, transaction }) => {
251
+ const node = unwrap(transaction.doc.nodeAt(pos + offset));
252
+ const startNumber = node.attrs.startNumber as
253
+ | string
254
+ | number
255
+ | undefined
256
+ | null;
257
+
258
+ if (typeof startNumber === 'string' && startNumber.length > 0) {
259
+ return parseInt(startNumber, 10);
260
+ }
261
+
262
+ if (typeof startNumber === 'number') {
263
+ return startNumber;
264
+ }
265
+
266
+ return null;
267
+ },
268
+ setStartNumber: ({ number, pos, transaction }) =>
269
+ transaction.setNodeAttribute(pos + offset, 'startNumber', number),
270
+ });
@@ -1,21 +1,21 @@
1
- import {
2
- getRdfaAttrs,
3
- NodeSpec,
4
- rdfaAttrs,
5
- Transaction,
6
- } from '@lblod/ember-rdfa-editor';
1
+ import { getRdfaAttrs, NodeSpec, rdfaAttrs } from '@lblod/ember-rdfa-editor';
7
2
  import {
8
3
  BESLUIT,
9
4
  ELI,
10
5
  PROV,
11
6
  SKOS,
12
- XSD,
13
7
  } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
14
8
  import { hasRDFaAttribute } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
15
9
  import { StructureSpec } from '../../article-structure-plugin';
16
10
  import { v4 as uuid } from 'uuid';
17
11
  import { unwrap } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
18
12
  import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
13
+ import {
14
+ getNumberAttributeFromElement,
15
+ getNumberAttributesFromNode,
16
+ getNumberDocSpecFromNode,
17
+ getNumberUtils,
18
+ } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/article-structure-plugin/utils/structure';
19
19
 
20
20
  export const besluit_title: NodeSpec = {
21
21
  content: 'paragraph+',
@@ -183,7 +183,6 @@ export const besluitArticleStructure: StructureSpec = {
183
183
  limitTo: 'besluit',
184
184
  constructor: ({ schema, number, content, intl, state }) => {
185
185
  const translationWithDocLang = getTranslationFunction(state);
186
- const numberConverted = number?.toString() ?? '1';
187
186
  const node = schema.node(
188
187
  `besluit_article`,
189
188
  {
@@ -191,7 +190,7 @@ export const besluitArticleStructure: StructureSpec = {
191
190
  },
192
191
  [
193
192
  schema.node('besluit_article_header', {
194
- number: numberConverted,
193
+ number: number ?? 1,
195
194
  }),
196
195
  schema.node(
197
196
  `besluit_article_content`,
@@ -223,10 +222,7 @@ export const besluitArticleStructure: StructureSpec = {
223
222
  selectionConfig,
224
223
  };
225
224
  },
226
- updateNumber: function ({ number, pos, transaction }): Transaction {
227
- transaction.setNodeAttribute(pos + 1, 'number', number.toString());
228
- return transaction;
229
- },
225
+ ...getNumberUtils(1),
230
226
  content: ({ pos, state }) => {
231
227
  const node = unwrap(state.doc.nodeAt(pos));
232
228
  return unwrap(node.lastChild).content;
@@ -240,7 +236,13 @@ export const besluit_article_header: NodeSpec = {
240
236
  attrs: {
241
237
  ...rdfaAttrs,
242
238
  number: {
243
- default: '1',
239
+ default: 1,
240
+ },
241
+ numberDisplayStyle: {
242
+ default: 'decimal', // decimal, roman
243
+ },
244
+ startNumber: {
245
+ default: null,
244
246
  },
245
247
  },
246
248
  toDOM(node) {
@@ -249,29 +251,35 @@ export const besluit_article_header: NodeSpec = {
249
251
  delete toplevelAttrs.datatype;
250
252
  return [
251
253
  'div',
252
- { ...toplevelAttrs, contenteditable: false },
254
+ {
255
+ ...toplevelAttrs,
256
+ contenteditable: false,
257
+ ...getNumberAttributesFromNode(node),
258
+ },
253
259
  'Artikel ',
254
- [
255
- 'span',
256
- { property: ELI('number').prefixed, datatype: XSD('string').prefixed },
257
- node.attrs.number,
258
- ],
260
+ getNumberDocSpecFromNode(node),
259
261
  ];
260
262
  },
261
263
  parseDOM: [
262
264
  {
263
265
  tag: 'p,div',
264
266
  getAttrs(element: HTMLElement) {
265
- const numberNode = element.querySelector(
267
+ const numberElement = element.querySelector(
266
268
  `span[property~='${ELI('number').prefixed}'],
267
269
  span[property~='${ELI('number').full}']`,
268
270
  );
269
- if (numberNode) {
271
+
272
+ const numberAttributes =
273
+ numberElement &&
274
+ getNumberAttributeFromElement(element, numberElement);
275
+
276
+ if (numberAttributes) {
270
277
  return {
271
278
  ...getRdfaAttrs(element),
272
- number: numberNode.textContent,
279
+ ...numberAttributes,
273
280
  };
274
281
  }
282
+
275
283
  return false;
276
284
  },
277
285
  },
@@ -24,16 +24,17 @@ export const emberNodeConfig: () => EmberNodeConfig = () => {
24
24
  serialize(_, state) {
25
25
  const t = getTranslationFunction(state);
26
26
  const heading = t(
27
- 'template-comments-plugin.heading',
28
- 'toelichtingsbepaling',
27
+ 'template-comments-plugin.long-title',
28
+ 'Toelichtings- of voorbeeldbepaling',
29
29
  );
30
30
 
31
31
  return [
32
32
  'div',
33
33
  {
34
34
  typeof: EXT('TemplateComment').prefixed,
35
+ class: 'say-template-comment',
35
36
  },
36
- ['h3', {}, heading],
37
+ ['p', {}, ['strong', {}, heading]],
37
38
  ['div', { property: EXT('content').prefixed }, 0],
38
39
  ];
39
40
  },
@@ -21,3 +21,38 @@ export const getTranslationFunction = (state?: EditorState) => {
21
21
  return intl.t(key, { ...options, htmlSafe: false, locale });
22
22
  };
23
23
  };
24
+
25
+ /**
26
+ * Helper function to help pick supported locales for ember-intl.
27
+ * Returns exact matches first, then language matches, then the default.
28
+ **/
29
+ export function decentLocaleMatch(
30
+ userLocales: string[] | readonly string[],
31
+ supportedLocales: string[],
32
+ defaultLocale: string,
33
+ ) {
34
+ // Ember-intl lowercases locales so we can make comparisons easier by doing the same
35
+ const userLocs = userLocales.map((locale) => locale.toLowerCase());
36
+ const supportedLocs = supportedLocales.map((locale) => locale.toLowerCase());
37
+
38
+ // First find exact matches. Use a set to avoid duplicates while preserving insert order.
39
+ const matches = new Set(
40
+ userLocs.filter((locale) => supportedLocs.includes(locale)),
41
+ );
42
+
43
+ // Then look for locales that just match based on language,
44
+ // e.g. match en or en-US if looking for en-GB
45
+ const languageMap: Record<string, string[] | undefined> = {};
46
+ supportedLocs.forEach((locale) => {
47
+ const lang = locale.split('-')[0];
48
+ languageMap[lang] = [...(languageMap[lang] || []), locale];
49
+ });
50
+ userLocs.forEach((locale) => {
51
+ const looseMatches = languageMap[locale.split('-')[0]] ?? [];
52
+ looseMatches.forEach((match) => matches.add(match));
53
+ });
54
+
55
+ // Add the default so we always have something
56
+ matches.add(defaultLocale.toLowerCase());
57
+ return [...matches];
58
+ }
@@ -1,5 +1,3 @@
1
- @import "ember-appuniversum";
2
-
3
1
  .citaten--decision-list {
4
2
  max-height: 35vh;
5
3
  overflow: auto;
@@ -1,5 +1,3 @@
1
- @import 'ember-appuniversum';
2
-
3
1
  .rdfa-annotations {
4
2
  [property='ext:redacted'] {
5
3
  background-color: var(--au-red-200);
@@ -1,7 +1,8 @@
1
- @import "ember-appuniversum";
2
-
3
1
  .say-template-comment {
4
2
  color: var(--au-blue-900);
3
+ padding: $au-unit-small;
4
+ border-radius: var(--au-radius);
5
+ border: 0.1rem solid var(--au-gray-300);
5
6
 
6
7
  .au-c-alert__content {
7
8
  margin-top: 0;
@@ -9,8 +9,15 @@ type Args = {
9
9
  export default class EditorPluginsStructureCardComponent extends Component<Args> {
10
10
  intl: IntlService;
11
11
  removeStructureContent: boolean;
12
+ startNumber: number | null;
12
13
  get controller(): SayController;
13
14
  moveStructure(direction: 'up' | 'down'): void;
15
+ setStructureStartNumber(): void;
16
+ resetStructureStartNumber(): void;
17
+ get structureNumber(): number | null | undefined;
18
+ get structureStartNumber(): number | null | undefined;
19
+ get startNumberInputValue(): number | "";
20
+ onStartNumberChange: (event: InputEvent) => void;
14
21
  removeStructure(withContent: boolean): void;
15
22
  setRemoveStructureContent(value: boolean): void;
16
23
  get structureTypes(): ArticleStructurePluginOptions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lblod/ember-rdfa-editor-lblod-plugins",
3
- "version": "16.0.0",
3
+ "version": "16.1.0",
4
4
  "description": "Ember addon providing lblod specific plugins for the ember-rdfa-editor",
5
5
  "keywords": [
6
6
  "ember-addon",
@@ -71,7 +71,7 @@
71
71
  "@glimmer/component": "^1.1.2",
72
72
  "@glimmer/tracking": "^1.1.2",
73
73
  "@glint/template": "1.1.0",
74
- "@lblod/ember-rdfa-editor": "9.0.0",
74
+ "@lblod/ember-rdfa-editor": "9.0.2",
75
75
  "@rdfjs/types": "^1.1.0",
76
76
  "@release-it/keep-a-changelog": "^3.1.0",
77
77
  "@tsconfig/ember": "^3.0.0",
@@ -113,7 +113,7 @@
113
113
  "ember-cli-terser": "^4.0.2",
114
114
  "ember-cli-typescript": "^5.2.1",
115
115
  "ember-disable-prototype-extensions": "^1.1.3",
116
- "ember-intl": "6.1.0",
116
+ "ember-intl": "5.7.2",
117
117
  "ember-load-initializers": "^2.1.2",
118
118
  "ember-modifier": "3.2.7",
119
119
  "ember-page-title": "^8.0.0",
@@ -148,7 +148,7 @@
148
148
  "@glint/template": "^1.1.0",
149
149
  "@lblod/ember-rdfa-editor": "^9.0.0",
150
150
  "ember-concurrency": "^2.3.7 || ^3.1.0",
151
- "ember-intl": "^6.1.0",
151
+ "ember-intl": "^5.7.2 || ^6.1.0",
152
152
  "ember-modifier": "^3.2.7",
153
153
  "ember-power-select": "6.x || 7.x",
154
154
  "ember-source": "^4.12.0"
@@ -4,3 +4,4 @@ export { default as recalculateStructureNumbers } from './recalculate-structure-
4
4
  export { default as removeStructure } from './remove-structure';
5
5
  export { default as unwrapStructure } from './unwrap-structure';
6
6
  export { default as wrapStructureContent } from './wrap-structure-content';
7
+ export { default as setStructureStartNumber } from './set-structure-start-number';
@@ -0,0 +1,4 @@
1
+ import { Command } from '@lblod/ember-rdfa-editor';
2
+ import type { ArticleStructurePluginOptions } from '..';
3
+ declare const setStructureStartNumber: (options: ArticleStructurePluginOptions, startNumber: number | null) => Command;
4
+ export default setStructureStartNumber;
@@ -30,6 +30,19 @@ export type StructureSpec = {
30
30
  pos: number;
31
31
  transaction: Transaction;
32
32
  }) => Transaction;
33
+ getNumber: (args: {
34
+ pos: number;
35
+ transaction: Transaction;
36
+ }) => number | null;
37
+ setStartNumber: (args: {
38
+ number: number | null;
39
+ pos: number;
40
+ transaction: Transaction;
41
+ }) => Transaction;
42
+ getStartNumber: (args: {
43
+ pos: number;
44
+ transaction: Transaction;
45
+ }) => number | null;
33
46
  content?: (args: {
34
47
  pos: number;
35
48
  state: EditorState;
@@ -0,0 +1,5 @@
1
+ export declare function romanize(num: number): string;
2
+ /**
3
+ * @link https://gist.github.com/briansunter/ec7af91065d79a2f790fcd76a2a08a84
4
+ */
5
+ export declare function romanToInt(romanString: string): number;
@@ -1,5 +1,6 @@
1
- import { NodeSpec, NodeType, PNode, Schema, Selection } from '@lblod/ember-rdfa-editor';
1
+ import { DOMOutputSpec, NodeSpec, NodeType, PNode, Schema, Selection } from '@lblod/ember-rdfa-editor';
2
2
  import { Resource } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
3
+ import { StructureSpec } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/article-structure-plugin';
3
4
  export declare function constructStructureNodeSpec(config: {
4
5
  type: Resource;
5
6
  content: string;
@@ -16,8 +17,20 @@ export declare function findAncestorOfType(selection: Selection, ...types: NodeT
16
17
  depth: number;
17
18
  node: PNode;
18
19
  } | undefined;
20
+ export declare function getNumberAttributeFromElement(containerElement: Element, numberElement: Element): {
21
+ number: number;
22
+ numberDisplayStyle: string;
23
+ startNumber: number | null;
24
+ };
19
25
  export declare function getStructureHeaderAttrs(element: HTMLElement): false | {
20
- number: string | null;
26
+ number: number;
27
+ numberDisplayStyle: string;
28
+ startNumber: number | null;
21
29
  };
22
- export declare function romanize(num: number): string;
23
30
  export declare function containsOnlyPlaceholder(schema: Schema, node: PNode): boolean;
31
+ export declare const getNumberAttributesFromNode: (node: PNode) => {
32
+ "data-start-number": string | null;
33
+ "data-number-display-style": string;
34
+ };
35
+ export declare const getNumberDocSpecFromNode: (node: PNode) => DOMOutputSpec;
36
+ export declare const getNumberUtils: (offset?: number) => Pick<StructureSpec, 'setStartNumber' | 'getStartNumber' | 'getNumber' | 'updateNumber'>;
@@ -22,6 +22,10 @@ article-structure-plugin:
22
22
  chapter: Move chapter down
23
23
  section: Move section down
24
24
  subsection: Move subsection down
25
+ start-number:
26
+ start-number: Start number
27
+ set: Set start number
28
+ reset: Reset
25
29
  title:
26
30
  structure-card: Structure Card
27
31
  remove:
@@ -22,6 +22,10 @@ article-structure-plugin:
22
22
  section: Afdeling naar beneden verplaatsen
23
23
  subsection: Onderafdeling naar beneden verplaatsen
24
24
  default: Structuur naar beneden verplaatsen
25
+ start-number:
26
+ start-number: Startnummer
27
+ set: Startnummer instellen
28
+ reset: Resetten
25
29
  title:
26
30
  structure-card: Structuur card
27
31
  remove:
@@ -1,3 +1,8 @@
1
1
  import type { EditorState } from '@lblod/ember-rdfa-editor';
2
2
  import { type TOptions } from 'ember-intl/services/intl';
3
3
  export declare const getTranslationFunction: (state?: EditorState) => (key: string, fallback: string, options?: TOptions) => string;
4
+ /**
5
+ * Helper function to help pick supported locales for ember-intl.
6
+ * Returns exact matches first, then language matches, then the default.
7
+ **/
8
+ export declare function decentLocaleMatch(userLocales: string[] | readonly string[], supportedLocales: string[], defaultLocale: string): string[];