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