@@ -63,7 +63,7 @@ function lex<T>(parser: Parser<T>): Parser<T> {
63
63
return parser . skip ( spaces ) ;
64
64
}
65
65
const backtick = matchString ( "`" , "backtick" ) ;
66
- const word = allAtLeastOnce (
66
+ const unescapedWord = allAtLeastOnce (
67
67
choiceOnlyOne (
68
68
match ( WORDS , "word" ) ,
69
69
backtick
@@ -76,8 +76,8 @@ const word = allAtLeastOnce(
76
76
. map ( ( word ) => word . join ( "" ) . replaceAll ( / \s + / g, " " ) . trim ( ) )
77
77
. filter ( ( word ) =>
78
78
word !== "" || throwError ( new ArrayResultError ( "missing word" ) )
79
- )
80
- . map ( escapeHtml ) ;
79
+ ) ;
80
+ const word = unescapedWord . map ( escapeHtml ) ;
81
81
const slash = lex ( matchString ( "/" , "slash" ) ) ;
82
82
const forms = sequence ( word , all ( slash . with ( word ) ) )
83
83
. map ( ( [ first , rest ] ) => [ first , ...rest ] ) ;
@@ -131,70 +131,90 @@ function detectRepetition(
131
131
`"${ source . join ( "/" ) } " has no repetition pattern found` ,
132
132
) ;
133
133
}
134
- const nounOnly = sequence (
135
- word ,
136
- optionalAll ( slash . with ( word ) ) ,
137
- tag (
138
- keyword ( "n" )
139
- . with ( sequence ( optionalAll ( keyword ( "gerund" ) ) , optionalNumber ) ) ,
140
- ) ,
141
- )
142
- . map < NounForms & { gerund : boolean } > ( ( [ first , second , [ gerund , number ] ] ) => {
143
- let singular : null | string ;
144
- let plural : null | string ;
145
- switch ( number ) {
146
- case null : {
147
- if ( second == null ) {
148
- const sentence = nlp ( first ) ;
149
- sentence . tag ( "Noun" ) ;
150
- singular = sentence
151
- . nouns ( )
152
- . toSingular ( )
153
- . text ( ) ;
154
- plural = sentence
155
- . nouns ( )
156
- . toPlural ( )
157
- . text ( ) ;
158
- if ( singular === "" || plural === "" ) {
159
- throw new ArrayResultError (
160
- `no singular or plural form found for "${ first } ". consider ` +
161
- "providing both singular and plural forms instead" ,
162
- ) ;
163
- }
164
- if ( first !== singular ) {
165
- throw new ArrayResultError (
166
- `conjugation error: "${ first } " is not "${ singular } ". ` +
167
- "consider providing both singular and plural forms instead" ,
168
- ) ;
169
- }
170
- } else {
171
- singular = first ;
172
- plural = second ;
134
+ const nounOnly = choiceOnlyOne (
135
+ sequence (
136
+ unescapedWord ,
137
+ tag (
138
+ keyword ( "n" )
139
+ . with ( optionalAll ( keyword ( "gerund" ) ) ) ,
140
+ ) ,
141
+ )
142
+ . map < NounForms & { gerund : boolean } > (
143
+ ( [ noun , gerund ] ) => {
144
+ const sentence = nlp ( noun ) ;
145
+ sentence . tag ( "Noun" ) ;
146
+ const singular = sentence
147
+ . nouns ( )
148
+ . toSingular ( )
149
+ . text ( ) ;
150
+ const plural = sentence
151
+ . nouns ( )
152
+ . toPlural ( )
153
+ . text ( ) ;
154
+ if ( singular === "" || plural === "" ) {
155
+ throw new ArrayResultError (
156
+ `no singular or plural form found for "${ noun } ". consider ` +
157
+ "providing both singular and plural forms instead" ,
158
+ ) ;
173
159
}
174
- break ;
175
- }
176
- case "singular" :
177
- case "plural" :
178
- if ( second != null ) {
160
+ if ( noun !== singular ) {
179
161
throw new ArrayResultError (
180
- "number inside tag may not be provided when two forms of noun " +
181
- "are already provided " ,
162
+ `conjugation error: " ${ noun } " is not " ${ singular } ". ` +
163
+ "consider providing both singular and plural forms instead " ,
182
164
) ;
183
165
}
166
+ return {
167
+ singular : escapeHtml ( singular ) ,
168
+ plural : escapeHtml ( plural ) ,
169
+ gerund : gerund != null ,
170
+ } ;
171
+ } ,
172
+ ) ,
173
+ sequence (
174
+ word ,
175
+ tag (
176
+ keyword ( "n" )
177
+ . with ( sequence ( optionalAll ( keyword ( "gerund" ) ) , number ) ) ,
178
+ ) ,
179
+ )
180
+ . map < NounForms & { gerund : boolean } > (
181
+ ( [ noun , [ gerund , number ] ] ) => {
182
+ let singular : null | string ;
183
+ let plural : null | string ;
184
184
switch ( number ) {
185
185
case "singular" :
186
- singular = first ;
187
- plural = null ;
188
- break ;
189
186
case "plural" :
190
- singular = null ;
191
- plural = first ;
187
+ switch ( number ) {
188
+ case "singular" :
189
+ singular = noun ;
190
+ plural = null ;
191
+ break ;
192
+ case "plural" :
193
+ singular = null ;
194
+ plural = noun ;
195
+ break ;
196
+ }
192
197
break ;
193
198
}
194
- break ;
195
- }
196
- return { singular, plural, gerund : gerund != null } ;
197
- } ) ;
199
+ return { singular, plural, gerund : gerund != null } ;
200
+ } ,
201
+ ) ,
202
+ sequence (
203
+ word ,
204
+ optionalAll ( slash . with ( word ) ) ,
205
+ tag (
206
+ keyword ( "n" )
207
+ . with ( optionalAll ( keyword ( "gerund" ) ) ) ,
208
+ ) ,
209
+ )
210
+ . map < NounForms & { gerund : boolean } > (
211
+ ( [ singular , plural , gerund ] ) => ( {
212
+ singular,
213
+ plural,
214
+ gerund : gerund != null ,
215
+ } ) ,
216
+ ) ,
217
+ ) ;
198
218
const determinerType = choiceOnlyOne (
199
219
keyword ( "article" ) ,
200
220
keyword ( "demonstrative" ) ,
@@ -285,7 +305,7 @@ function verbOnly(tagInside: Parser<unknown>): Parser<VerbForms> {
285
305
presentSingular,
286
306
past,
287
307
} ) ) ,
288
- word
308
+ unescapedWord
289
309
. skip ( tag ( tagInside ) )
290
310
. map ( ( verb ) => {
291
311
const sentence = nlp ( verb ) ;
@@ -308,9 +328,9 @@ function verbOnly(tagInside: Parser<unknown>): Parser<VerbForms> {
308
328
) ;
309
329
}
310
330
return {
311
- presentPlural : conjugations . Infinitive ,
312
- presentSingular : conjugations . PresentTense ,
313
- past : conjugations . PastTense ,
331
+ presentPlural : escapeHtml ( conjugations . Infinitive ) ,
332
+ presentSingular : escapeHtml ( conjugations . PresentTense ) ,
333
+ past : escapeHtml ( conjugations . PastTense ) ,
314
334
} ;
315
335
} ) ,
316
336
) ;
0 commit comments