update devDependencies, fix lint issues
[squeep-web-linking] / lib / rfc8288-web-linking.peggy
1 {{
2 /* Generated code is not pretty, ignore a lot of this horrorstyle. */
3 /* eslint-disable no-control-regex */
4 /* eslint-disable security/detect-object-injection */
5 /* eslint-disable brace-style */
6 /* eslint-disable comma-dangle */
7 /* eslint-disable vars-on-top */
8 /* eslint-disable no-unused-vars */
9 /* eslint-disable camelcase */
10 /* eslint-disable indent */
11 /* eslint-disable semi */
12 /* eslint-disable jsdoc/require-jsdoc */
13 /* eslint-disable sonarjs/cognitive-complexity */
14 /* eslint-disable sonarjs/no-identical-functions */
15
16 function makeString(o) {
17 return o.join('');
18 }
19
20 const onlyFirstAttributes = [
21 'media',
22 'rel',
23 'title',
24 'title*',
25 'type',
26 ];
27
28 }}
29
30 {
31 // Per-parsing tracking of attributes which should be ignored after first occurrence.
32 let seenAttributes = [];
33 }
34
35 links 'links'
36 = links:linkValue+ {
37 return links;
38 }
39
40 linkValue 'link-value'
41 = uriReference:uriReference OWS attributes:attributes ','? OWS {
42 seenAttributes = [];
43 return {
44 target: uriReference,
45 attributes,
46 };
47 }
48
49 uriReference 'uri-reference'
50 = '<' uri:uri '>' ';' {
51 return uri;
52 }
53
54 uri 'uri'
55 = uri:[^>]+ {
56 return makeString(uri);
57 }
58
59 attributes 'attributes'
60 = attrs:linkParam+ {
61 return attrs.filter((a) => a);
62 }
63
64 linkParam 'link-param'
65 = name:name BWS '=' BWS value:value ';'? OWS {
66 if (onlyFirstAttributes.includes(name.name)) {
67 if (seenAttributes.includes(name.name)) {
68 // Repeat of singleton attribute, ignore it.
69 return;
70 }
71 seenAttributes.push(name.name);
72 }
73 return {
74 ...name,
75 ...value,
76 };
77 }
78 / name:name BWS ';'? OWS {
79 return {
80 ...name,
81 value: null,
82 }
83 }
84
85 name 'name'
86 = name:[a-zA-Z]+ extended:'*'? {
87 return {
88 name: makeString(name.concat(extended)).toLowerCase(),
89 extended: !!extended,
90 };
91 }
92
93 value 'value'
94 = ["] value:[^"]+ ["] {
95 return {
96 value: makeString(value),
97 };
98 }
99 / value:[^";,]+ {
100 return {
101 value: makeString(value),
102 };
103 }
104
105 OWS 'whitespace'
106 = spaces:[ ]*
107
108 BWS 'bad whitespace'
109 = OWS
110
111 // This is also an alternate startRule.
112 extendedValue 'extended-value'
113 = encoding:[^']* ['] language:[^']* ['] value:.* {
114 return {
115 encoding: encoding.length ? makeString(encoding) : 'UTF-8',
116 language: language.length ? makeString(language) : null,
117 value: decodeURIComponent(makeString(value)),
118 };
119 }
120 / value:.* {
121 return {
122 encoding: null,
123 language: null,
124 value: makeString(value),
125 };
126 }