Add support for `imenu` and `which-func-mode`. Remember setting
[docutils/kirr.git] / docutils / tools / editors / emacs / tests / re.el
blob979a2b5c9df681680fb61b14b59e630b8442c70d
1 ;; Tests for the regular expression builder
3 (add-to-list 'load-path ".")
4 (load "init" nil t)
5 (init-rst-ert t)
7 (ert-deftest rst-re ()
8 "Tests `rst-re'."
9 (should (equal (rst-re "xy") "xy"))
10 (should (equal (rst-re ?A) "A"))
11 (should (equal (rst-re ?$) "\\$"))
12 (should (equal (rst-re 'exm-tag) "\\.\\."))
13 (should (equal (rst-re "xy" ?A ?$ 'exm-tag) "xyA\\$\\.\\."))
14 (should (equal (rst-re '(:seq "xy" ?A ?$ exm-tag)) "xyA\\$\\.\\."))
15 (should (equal (rst-re '(:shy "xy" ?A ?$ exm-tag)) "\\(?:xyA\\$\\.\\.\\)"))
16 (should (equal (rst-re '(:grp "xy" ?A ?$ exm-tag)) "\\(xyA\\$\\.\\.\\)"))
17 (should (equal (rst-re '(:alt "xy" ?A ?$ exm-tag))
18 "\\(?:xy\\|A\\|\\$\\|\\.\\.\\)"))
19 (should (equal (rst-re '(:seq (:seq "xy" ?A ?$ exm-tag))) "xyA\\$\\.\\."))
20 (should (equal (rst-re '(:grp (:alt "xy" ?A ?$ exm-tag)))
21 "\\(\\(?:xy\\|A\\|\\$\\|\\.\\.\\)\\)"))
22 (should (equal (rst-re '(:alt (:grp "xy" ?A ?$ exm-tag)))
23 "\\(?:\\(xyA\\$\\.\\.\\)\\)"))
24 (should (equal (rst-re '(:alt "xy" ?A) '(:grp ?$ exm-tag))
25 "\\(?:xy\\|A\\)\\(\\$\\.\\.\\)"))
26 (should-error (rst-re '(:unknown "xy")))
27 (should-error (rst-re [1]))
30 (defun re-equal-modify-orig (orig loc refactored repls)
31 (let ((case-fold-search nil))
32 (while (string-match "\\[ \t]" orig)
33 ;; Transpose horizontal whitespace
34 (setq orig (replace-match "[\t ]" t nil orig)))
35 (while (string-match "\\\\s \\*\\$" orig)
36 ;; Replace symbolic whitespace
37 (setq orig (replace-match "[\t ]*$" t nil orig)))
38 (dolist (regex-repl repls)
39 (if (string-match (car regex-repl) orig)
40 (setq orig (replace-match (cdr regex-repl) t t orig))
41 (error "Replacement regex /%s/ didn't match in '%s' for location '%s'"
42 (car regex-repl) orig loc)))
43 orig))
46 (defun re-equal (orig loc refactored &rest repls)
47 "Compare regex ORIG at location LOC to REFACTORED.
48 REPLS starts with a list of cons cells telling where regex in car
49 is replaced by cdr in ORIG."
50 (equal (re-equal-modify-orig orig loc refactored repls) refactored))
52 (defun re-equal-explain (orig loc refactored &rest repls)
53 (setq orig (re-equal-modify-orig orig loc refactored repls))
54 (ert--explain-not-equal orig refactored))
56 (put 're-equal 'ert-explainer 're-equal-explain)
58 (defun re-check-matches (orig loc refactored s pairs)
59 "Check matches and return those pairs which didn't work"
60 (let ((case-fold-search nil)
61 failed)
62 (dolist (pair pairs failed)
63 (let ((orig-mtc (if (string-match orig s)
64 (match-string (car pair) s)))
65 (refa-mtc (if (string-match refactored s)
66 (match-string (cdr pair) s))))
67 (if (not orig-mtc)
68 (error "Original regex '%s' didn't match string '%s' for location '%s'"
69 orig s loc)
70 (if (not refa-mtc)
71 (error "Refactored regex '%s' didn't match string '%s' for location '%s'"
72 refactored s loc)
73 (if (not (equal orig-mtc refa-mtc))
74 (push pair failed))))))))
76 (defun re-equal-matches (orig loc refactored matches &rest repls)
77 "Like `re-equal'. However, if MATCHES is non-nil it must be a
78 list with a string and cons cells each consisting of two numbers.
79 For each cons cell the string is matched with ORIG and REFACTORED
80 and the numbered matches are compared."
81 (and (equal (re-equal-modify-orig orig loc refactored repls) refactored)
82 (not (re-check-matches orig loc refactored
83 (car matches) (cdr matches)))))
85 (defun re-equal-matches-explain (orig loc refactored matches &rest repls)
86 (if (not (equal (re-equal-modify-orig orig loc refactored repls) refactored))
87 (apply 're-equal-explain orig loc refactored repls)
88 (let (result)
89 (dolist (failed (re-check-matches orig loc refactored
90 (car matches) (cdr matches)) result)
91 (push (list 'matchers-didnt-match (car failed) (cdr failed))
92 result)))))
94 (put 're-equal-matches 'ert-explainer 're-equal-matches-explain)
96 (ert-deftest rst-re-refactoring ()
97 "Test the refactorings done based on rst_el_1_68."
98 ;; Any comment or string "=== rst.el.~rst_el_1_68~:..." gives the line number
99 ;; of the refactored code in the original file for the previous expression.
100 (let* ((rst-bullets
101 '(?- ?* ?+))
102 ;; === rst.el.~rst_el_1_68~:451
103 (rst-re-bullets
104 (format "\\([%s][ \t]\\)[^ \t]" (regexp-quote (concat rst-bullets))))
105 ;; === rst.el.~rst_el_1_68~:1604
106 ;; More parameters
107 (c ?*)
108 (len 10)
109 (char ?+)
110 (adornment "$$$$")
111 (ado-re (regexp-quote adornment))
112 (fromchar ?.)
114 (should (re-equal
115 "^\\.\\. "
116 "=== rst.el.~rst_el_1_68~:398"
117 (rst-re "^" 'exm-sta)
118 (cons " $" "[ ]+") ;; Any whitespace may follow
120 (should (re-equal
121 "^[ \t]*\\S *\\w\\S *"
122 "=== rst.el.~rst_el_1_68~:567"
123 (rst-re 'lin-beg "\\S *\\w\\S *")
125 (should (re-equal
126 "::[ \t]*$"
127 "=== rst.el.~rst_el_1_68~:591"
128 (rst-re 'dcl-tag 'lin-end)
130 (should (re-equal
131 "\\.\\.\\.[ \t]*$"
132 "=== rst.el.~rst_el_1_68~:592"
133 (rst-re 'ell-tag 'lin-end)
135 (should (re-equal
136 ".[ \t]*$"
137 "=== rst.el.~rst_el_1_68~:594"
138 (rst-re "." 'lin-end)
140 (should (re-equal
141 "^[ \t]+"
142 "=== rst.el.~rst_el_1_68~:605"
143 (rst-re 'hws-sta)
144 (cons "^^" "") ;; No need to anchor for looking-at
146 (should (re-equal
147 "^[ \t]*$"
148 "=== rst.el.~rst_el_1_68~:744"
149 (rst-re 'lin-end)
150 (cons "^^" "") ;; No need to anchor for looking-at
152 (should (re-equal
153 "^[ \t]*$"
154 "=== rst.el.~rst_el_1_68~:1517"
155 (rst-re 'lin-end)
156 (cons "^^" "") ;; No need to anchor for looking-at
158 (should (re-equal
159 "^[ \t]*$"
160 "=== rst.el.~rst_el_1_68~:1545"
161 (rst-re 'lin-end)
162 (cons "^^" "") ;; No need to anchor for looking-at
164 (should (re-equal
165 "^[ \t]*$"
166 "=== rst.el.~rst_el_1_68~:1548"
167 (rst-re 'lin-end)
168 (cons "^^" "") ;; No need to anchor for looking-at
170 (should (re-equal
171 "[0-9]+"
172 "=== rst.el.~rst_el_1_68~:1657"
173 (rst-re 'num-tag)
175 (should (re-equal
176 "[IVXLCDMivxlcdm]+"
177 "=== rst.el.~rst_el_1_68~:1661"
178 (rst-re 'rom-tag)
180 (should (re-equal
181 "[IVXLCDMivxlcdm]+"
182 "=== rst.el.~rst_el_1_68~:1677"
183 (rst-re 'rom-tag)
185 (should (re-equal
186 "[a-zA-Z]"
187 "=== rst.el.~rst_el_1_68~:1685"
188 (rst-re 'ltr-tag)
190 (should (re-equal
191 "[ \t\n]*\\'"
192 "=== rst.el.~rst_el_1_68~:1762"
193 (rst-re "[ \t\n]*\\'")
195 (should (re-equal
196 "\\S .*\\S "
197 "=== rst.el.~rst_el_1_68~:1767"
198 (rst-re "\\S .*\\S ")
200 (should (re-equal
201 "[ \t]*$"
202 "=== rst.el.~rst_el_1_68~:2066"
203 (rst-re 'lin-end)
205 (should (re-equal
206 "[ \t]*$"
207 "=== rst.el.~rst_el_1_68~:2366"
208 (rst-re 'lin-end)
210 (should (re-equal
211 "^[ \t]*$"
212 "=== rst.el.~rst_el_1_68~:2414"
213 (rst-re 'lin-end)
214 (cons "^^" "") ;; No need to anchor for looking-at
216 (should (re-equal
217 "[ \t]*$"
218 "=== rst.el.~rst_el_1_68~:2610"
219 (rst-re 'lin-end)
221 (should (re-equal
222 "[ \t]*$"
223 "=== rst.el.~rst_el_1_68~:2612"
224 (rst-re 'lin-end)
226 (should (re-equal
227 "[ \t]*$"
228 "=== rst.el.~rst_el_1_68~:2645"
229 (rst-re 'lin-end)
231 (should (re-equal
232 "[^ \t]\\|[ \t]*\\.\\.[^ \t]\\|.*::$"
233 "=== rst.el.~rst_el_1_68~:3177"
234 (rst-re '(:alt
235 "[^ \t]"
236 (:seq hws-tag exm-tag "[^ \t]")
237 (:seq ".*" dcl-tag lin-end)))
238 (cons "^" "\\(?:") (cons "$" "\\)") ;; Add outermost shy group
239 (cons "::\\$" "::[ ]*$") ;; Allow trailing space after double
240 ;; colon
242 (should (re-equal
243 "\\s *$"
244 "=== rst.el.~rst_el_1_68~:3209"
245 (rst-re 'lin-end)
247 (should (re-equal
248 "^\\s *$"
249 "=== rst.el.~rst_el_1_68~:3215"
250 (rst-re 'linemp-tag)
252 (should (re-equal
253 "\\s *$"
254 "=== rst.el.~rst_el_1_68~:3253"
255 (rst-re 'lin-end)
257 (should (re-equal
258 "\\s *"
259 "=== rst.el.~rst_el_1_68~:3256"
260 (rst-re 'hws-tag)
261 (cons "\\\\s \\*" "[\t ]*") ;; Replace symbolic by real whitespace
263 (should (re-equal
264 "\\s *$"
265 "=== rst.el.~rst_el_1_68~:3261"
266 (rst-re 'lin-end)
268 (should (re-equal
269 "\\s *"
270 "=== rst.el.~rst_el_1_68~:3268"
271 (rst-re 'hws-tag)
272 (cons "\\\\s \\*" "[\t ]*") ;; Replace symbolic by real whitespace
274 (should (re-equal
275 (regexp-quote adornment)
276 "=== rst.el.~rst_el_1_68~:3346"
277 (rst-re (regexp-quote adornment))
279 (should (re-equal
280 "\\s *$"
281 "=== rst.el.~rst_el_1_68~:3354"
282 (rst-re 'lin-end)
284 (should (re-equal
285 "\\s *$"
286 "=== rst.el.~rst_el_1_68~:3358"
287 (rst-re 'lin-end)
289 (should (re-equal
290 "\\s *$"
291 "=== rst.el.~rst_el_1_68~:3374"
292 (rst-re 'lin-end)
294 (should (re-equal
295 (concat "\\(" ado-re "\\)\\s *$")
296 "=== rst.el.~rst_el_1_68~:3377"
297 (rst-re (list :grp
298 ado-re)
299 'lin-end)
301 (should (re-equal
302 (concat "\\(" ado-re "\\)\\s *$")
303 "=== rst.el.~rst_el_1_68~:3393"
304 (rst-re (list :grp
305 ado-re)
306 'lin-end)
308 (should (re-equal
309 (concat "^" (regexp-quote (string fromchar)) "+\\( *\\)$")
310 "=== rst.el.~rst_el_1_68~:3590"
311 (rst-re "^" fromchar "+\\( *\\)$")
313 (should (re-equal
314 "\f\\|>*[ \t]*$\\|>*[ \t]*[-+*] \\|>*[ \t]*[0-9#]+\\. "
315 "=== rst.el.~rst_el_1_68~:391"
316 (rst-re '(:alt
317 "\f"
318 lin-end
319 (:seq hws-tag itmany-sta-1)))
320 (cons "^" "\\(?:") (cons "$" "\\)") ;; Add outermost shy group
321 (cons (regexp-quote "[-+*] \\|>*[ ]*[0-9#]+\\. ")
322 "\\(\\(?:\\(?:\\(?:[a-zA-Z]\\|[0-9]+\\|[IVXLCDMivxlcdm]+\\|#\\)\\.\\|(?\\(?:[a-zA-Z]\\|[0-9]+\\|[IVXLCDMivxlcdm]+\\|#\\))\\)\\|[-*+\u2022\u2023\u2043]\\)\\)[ ]+"
323 ) ;; Now matches all items
324 (cons ">\\*" "") ;; Remove ">" prefix
325 (cons ">\\*" "") ;; Remove another ">" prefix
326 (cons "\\[\t ]\\+" "\\(?:[\t ]+\\|$\\)") ;; Item tag needs no
327 ;; trailing whitespace
329 (should (re-equal
330 (format "[%s]+[ \t]*$" (char-to-string c))
331 "=== rst.el.~rst_el_1_68~:587"
332 (rst-re c "+" 'lin-end)
333 (cons "\\[\\*]" "\\*") ;; Use quoting instead of char class
335 (should (re-equal
336 (concat "^"
337 (regexp-quote (make-string len char))
338 "$")
339 "=== rst.el.~rst_el_1_68~:941"
340 (rst-re "^" char (format "\\{%d\\}" len) "$")
341 (cons "\\(\\\\\\+\\)\\{9\\}\\$"
342 "\\{10\\}$") ;; Use regex repeat instead of explicit repeat
344 (should (re-equal
345 (format "#.\\|[%s]"
346 (regexp-quote (concat rst-bullets)))
347 "=== rst.el.~rst_el_1_68~:1653"
348 (rst-re '(:alt
349 enmaut-tag
350 bul-tag))
351 (cons "^" "\\(?:") (cons "$" "\\)") ;; Add outermost shy group
352 (cons (regexp-quote "[-\\*\\+]")
353 "[-*+\u2022\u2023\u2043]") ;; Wrongly quoted characters in
354 ;; class and more bullets
355 (cons "#\\." "\\(?:#\\.\\|(?#)\\)") ;; Use all auto enumerators
357 (should (re-equal
358 "[a-zA-Z]+"
359 "=== rst.el.~rst_el_1_68~:1672"
360 (rst-re 'ltr-tag)
361 (cons "\\+$" "") ;; Wrong in source
363 (should (re-equal
364 rst-re-bullets
365 "=== rst.el.~rst_el_1_68~:1735"
366 (rst-re 'bul-sta)
367 (cons (regexp-quote "[-\\*\\+]")
368 "[-*+\u2022\u2023\u2043]") ;; Wrongly quoted characters in
369 ;; class and more bullets
370 (cons "\\[^ \t]" "") ;; Accept bullets without content
371 (cons "^\\\\(" "") (cons "\\\\)" "") ;; Remove superfluous group
372 (cons "$" "+") ;; Allow more whitespace
373 (cons "\\[\t ]\\+" "\\(?:[\t ]+\\|$\\)") ;; Item tag needs no
374 ;; trailing whitespace
376 (should (re-equal
377 "^\\.\\. contents[ \t]*::\\(.*\\)\n\\([ \t]+:\\w+:.*\n\\)*\\.\\."
378 "=== rst.el.~rst_el_1_68~:2056"
379 (rst-re "^" 'exm-sta "contents" 'dcl-tag ".*\n"
380 "\\(?:" 'hws-sta 'fld-tag ".*\n\\)*" 'exm-tag)
381 (cons " contents\\[\t ]\\*"
382 "[\t ]+contents") ;; Any whitespace before but no after
383 (cons "\\\\(\\.\\*\\\\)" ".*") ;; Remove superfluous group
384 (cons "\\\\(" "\\(?:") ;; Make group shy
385 (cons ":\\\\w\\+:" ":\\(?:[^:\n]\\|\\\\:\\)+:") ;; Use improved
386 ;; field tag
388 (should (re-equal
389 "[ \t]+[^ \t]"
390 "=== rst.el.~rst_el_1_68~:2065"
391 (rst-re 'hws-sta "\\S ")
392 (cons "\\[^ \t]" "\\S ") ;; Require non-whitespace instead
393 ;; of only non-horizontal whitespace
397 (ert-deftest rst-re-refactoring-complicated ()
398 "Try to test complicated refactorings done based on rst_el_1_68."
399 :expected-result :failed ;; These have been reviewed logically and are ok
400 (let* ((rst-bullets
401 '(?- ?* ?+))
402 ;; === rst.el.~rst_el_1_68~:451
403 (rst-re-enumerator "\\(?:[a-zA-Z]\\|[0-9IVXLCDMivxlcdm]+\\)")
404 ;; === rst.el.~rst_el_1_68~:1608
405 (rst-re-enumerations
406 (format "^[ \t]*\\(%s.\\|(?%s)\\)[ \t]"
407 rst-re-enumerator
408 rst-re-enumerator))
409 ;; === rst.el.~rst_el_1_68~:1610
410 (rst-re-items
411 (format "^[ \t]*\\([%s]\\|\\(#\\|%s\\)\\.\\|(?%s)\\)[ \t]"
412 (regexp-quote (concat rst-bullets))
413 rst-re-enumerator
414 rst-re-enumerator))
415 ;; === rst.el.~rst_el_1_68~:1616
416 ;; More parameters
417 (char ?+)
419 (should (re-equal
420 rst-re-items
421 "=== rst.el.~rst_el_1_68~:2718"
422 (rst-re 'itmany-sta-1)
423 (cons "^^\\[\t ]\\*" "") ;; Wrongly anchored at the beginning of
424 ;; the line
425 (cons (regexp-quote "\\(#\\|\\(?:[a-zA-Z]\\|[0-9IVXLCDMivxlcdm]+\\)\\)")
426 "\\(?:[a-zA-Z]\\|[0-9]+\\|[IVXLCDMivxlcdm]+\\|#\\)"
427 ) ;; Replace counter for "\\."
428 (cons (regexp-quote "\\(?:[a-zA-Z]\\|[0-9IVXLCDMivxlcdm]+\\)")
429 "\\(?:[a-zA-Z]\\|[0-9]+\\|[IVXLCDMivxlcdm]+\\|#\\)"
430 ) ;; Replace counter for "(?)"
431 (cons "$" "+") ;; Allow more whitespace
432 (cons "^\\\\(" "\\(\\(?:") (cons "\\[\t ]\\+$" "\\)[\t ]+"
433 ) ;; Add superfluous shy group
434 (cons (regexp-quote "[-\\*\\+]\\|") "") ;; Remove wrongly quoted
435 ;; characters
436 (cons (regexp-quote "\\)\\)[\t ]+")
437 "\\|[-*+\u2022\u2023\u2043]\\)\\)[\t ]+"
438 ) ;; Re-add bullets
440 (should (re-equal
441 rst-re-items
442 "=== rst.el.~rst_el_1_68~:2724"
443 (rst-re 'itmany-beg-1)
445 (should (re-equal
446 rst-re-items
447 "=== rst.el.~rst_el_1_68~:1649"
448 (rst-re 'itmany-beg-1)
450 (should (re-equal
451 rst-re-enumerations
452 "=== rst.el.~rst_el_1_68~:1671"
453 (rst-re 'enmexp-beg)
455 (should (re-equal
456 rst-re-items
457 "=== rst.el.~rst_el_1_68~:1719"
458 (rst-re 'itmany-beg-1)
460 (should (re-equal
461 (concat
462 "\\(?:"
463 "\\(\\(?:[0-9a-zA-Z#]\\{1,3\\}[.):-]\\|[*+-]\\)[ \t]+\\)[^ \t\n]"
464 "\\|"
465 (format "\\(%s%s+[ \t]+\\)[^ \t\n]"
466 (regexp-quote (char-to-string char))
467 (regexp-quote (char-to-string char)))
468 "\\)")
469 "=== rst.el.~rst_el_1_68~:2430"
470 (rst-re
471 `(:grp
472 (:alt
473 itmany-tag
474 (:seq ,(char-after) "\\{2,\\}"))
475 hws-sta)
476 "\\S ")
477 (cons "^\\\\(\\?:" "") (cons "\\\\)$" "") ;; Remove superfluous
478 ;; shy group
479 (cons (regexp-quote "[0-9a-zA-Z#]\\{1,3\\}[.):-]\\|[*+-]")
480 "\\(\\(?:\\(?:\\(?:[a-zA-Z]\\|[0-9]+\\|[IVXLCDMivxlcdm]+\\|#\\)\\.\\|(?\\(?:[a-zA-Z]\\|[0-9]+\\|[IVXLCDMivxlcdm]+\\|#\\))\\)\\|[-*+\u2022\u2023\u2043]\\)\\)"
481 ) ;; Replace wrong item tag by correct one
482 (cons (regexp-quote "\\+\\++")
483 "\\+\\{2,\\}") ;; Use regex repeat instead of explicit repeat
484 (cons "\\[^ \t\n]" "\\S ") ;; Use symbolic non-whitespace
485 (cons "\\[^ \t\n]" "\\S ") ;; Use symbolic non-whitespace again
486 (cons "\\\\S " "") ;; Factor out symbolic non-whitespace
490 (ert-deftest rst-re-refactoring-font-lock ()
491 "Test the refactorings in font-lock done based on rst_el_1_68."
492 ;; Any comment or string "=== rst.el.~rst_el_1_68~:..." gives the line number
493 ;; of the refactored code in the original file for the previous expression.
494 (let* ((rst-use-char-classes t)
495 (rst-use-unicode t)
496 ;; horizontal white space
497 (re-hws "[\t ]")
498 ;; beginning of line with possible indentation
499 (re-bol (concat "^" re-hws "*"))
500 ;; Separates block lead-ins from their content
501 (re-blksep1 (concat "\\(" re-hws "+\\|$\\)"))
502 ;; explicit markup tag
503 (re-emt "\\.\\.")
504 ;; explicit markup start
505 (re-ems (concat re-emt re-hws "+"))
506 ;; inline markup prefix
507 (re-imp1 (concat "\\(^\\|" re-hws "\\|[-'\"([{<"
508 (if rst-use-unicode
509 "\u2018\u201c\u00ab\u2019"
511 "/:]\\)"))
512 ;; inline markup suffix
513 (re-ims1 (concat "\\(" re-hws "\\|[]-'\")}>"
514 (if rst-use-unicode
515 "\u2019\u201d\u00bb"
517 "/:.,;!?\\]\\|$\\)"))
518 ;; symbol character
519 (re-sym1 "\\(\\sw\\|\\s_\\)")
520 ;; inline markup content begin
521 (re-imbeg2 "\\(\\S \\|\\S \\([^")
523 ;; There seems to be a bug leading to error "Stack overflow in regexp
524 ;; matcher" when "|" or "\\*" are the characters searched for
525 (re-imendbegbeg
526 (if (< emacs-major-version 21)
528 "\\]\\|\\\\."))
529 ;; inline markup content end
530 (re-imendbeg (concat re-imendbegbeg "\\)\\{0,"
531 (format "%d" rst-max-inline-length)
532 "\\}[^\t "))
533 (re-imendend "\\\\]\\)")
534 ;; inline markup content without asterisk
535 (re-ima2 (concat re-imbeg2 "*" re-imendbeg "*" re-imendend))
536 ;; inline markup content without backquote
537 (re-imb2 (concat re-imbeg2 "`" re-imendbeg "`" re-imendend))
538 ;; inline markup content without vertical bar
539 (re-imv2 (concat re-imbeg2 "|" re-imendbeg "|" re-imendend))
540 ;; Supported URI schemes
541 (re-uris1 "\\(acap\\|cid\\|data\\|dav\\|fax\\|file\\|ftp\\|gopher\\|http\\|https\\|imap\\|ldap\\|mailto\\|mid\\|modem\\|news\\|nfs\\|nntp\\|pop\\|prospero\\|rtsp\\|service\\|sip\\|tel\\|telnet\\|tip\\|urn\\|vemmi\\|wais\\)")
542 ;; Line starting with adornment and optional whitespace; complete
543 ;; adornment is in (match-string 1); there must be at least 3
544 ;; characters because otherwise explicit markup start would be
545 ;; recognized
546 (re-ado2 (concat "^\\(\\(["
547 (if rst-use-char-classes
548 "^[:word:][:space:][:cntrl:]"
549 "^\\w \t\x00-\x1F")
550 "]\\)\\2\\2+\\)" re-hws "*$"))
552 (should (re-equal-matches
553 ;; `Bullet Lists`_
554 (concat re-bol "\\([-*+]" re-blksep1 "\\)")
555 "=== rst.el.~rst_el_1_68~:3011"
556 (rst-re 'lin-beg '(:grp bul-sta))
557 (list "*"
558 (cons 1 1))
559 (cons (regexp-quote "[-*+]")
560 "[-*+\u2022\u2023\u2043]") ;; More bullets
561 (cons "\\\\(\\[\t " "\\(?:[\t ") ;; Make a group shy
563 (should (re-equal-matches
564 ;; `Enumerated Lists`_
565 (concat re-bol "\\((?\\(#\\|[0-9]+\\|[A-Za-z]\\|[IVXLCMivxlcm]+\\)[.)]"
566 re-blksep1 "\\)")
567 "=== rst.el.~rst_el_1_68~:3015"
568 (rst-re 'lin-beg '(:grp enmany-sta))
569 (list " (#) Item"
570 (cons 1 1))
571 (cons (regexp-quote
572 "(?\\(#\\|[0-9]+\\|[A-Za-z]\\|[IVXLCMivxlcm]+\\)[.)]")
573 "\\(?:\\(?:[a-zA-Z]\\|[0-9]+\\|[IVXLCDMivxlcdm]+\\|#\\)\\.\\|(?\\(?:[a-zA-Z]\\|[0-9]+\\|[IVXLCDMivxlcdm]+\\|#\\))\\)"
574 ) ;; Enumeration tags are more sophisticated
575 (cons "\\\\(\\[\t " "\\(?:[\t ") ;; Make a group shy
577 (should (re-equal-matches
578 ;; `Field Lists`_
579 (concat re-bol "\\(:[^:\n]+:\\)" re-blksep1)
580 "=== rst.el.~rst_el_1_68~:3021"
581 (rst-re 'lin-beg '(:grp fld-tag) 'bli-sfx)
582 (list " :some field: "
583 (cons 1 1))
584 (cons "\\[^:\n]" "\\(?:[^:\n]\\|\\\\:\\)") ;; Field name more
585 ;; sophisticated
586 (cons "\\\\(\\[\t " "\\(?:[\t ") ;; Make a group shy
588 (should (re-equal-matches
589 ;; `Option Lists`_
590 (concat re-bol "\\(\\(\\(\\([-+/]\\|--\\)\\sw\\(-\\|\\sw\\)*"
591 "\\([ =]\\S +\\)?\\)\\(,[\t ]\\)?\\)+\\)\\($\\|[\t ]\\{2\\}\\)")
592 "=== rst.el.~rst_el_1_68~:3025"
593 (rst-re 'lin-beg '(:grp opt-tag (:shy optsep-tag opt-tag) "*")
594 '(:alt "$" (:seq hws-prt "\\{2\\}")))
595 (list " --len=length, -l length Explanation"
596 (cons 1 1))
597 (cons (regexp-quote "\\(\\(\\(\\([-+/]\\|--\\)\\sw\\(-\\|\\sw\\)*\\([ =]\\S +\\)?\\)\\(,[ ]\\)?\\)+\\)")
598 "\\(\\(?:\\(?:[-+/]\\|--\\)\\sw\\(?:-\\|\\sw\\)*\\(?:[ =]\\S +\\)?\\)\\(?:\\(?:,[ ]\\)\\(?:\\(?:[-+/]\\|--\\)\\sw\\(?:-\\|\\sw\\)*\\(?:[ =]\\S +\\)?\\)\\)*\\)"
599 ) ;; Option recognition more sophisticated
600 (cons "\\\\(\\$" "\\(?:$") ;; Make a group shy
602 (should (re-equal-matches
603 ;; `Line Blocks`_
604 (concat re-bol "\\(|" re-blksep1 "\\)[^|\n]*$")
605 "=== rst.el.~rst_el_1_68~:3030"
606 (rst-re 'lin-beg '(:grp "|" bli-sfx) "[^|\n]*$")
607 (list " | Some text"
608 (cons 1 1))
609 (cons "\\\\(\\[\t " "\\(?:[\t ") ;; Make a group shy
611 (should (re-equal-matches
612 ;; `Footnotes`_ / `Citations`_
613 (concat re-bol "\\(" re-ems "\\[[^[\n]+\\]\\)" re-blksep1)
614 "=== rst.el.~rst_el_1_68~:3038"
615 (rst-re 'lin-beg '(:grp exm-sta fnc-tag) 'bli-sfx)
616 (list ".. [#]"
617 (cons 1 1))
618 (cons "\\[^\\[" "[^]") ;; Error correction in old code
619 (cons "\\\\]" "]") ;; Remove superfluous quote
620 (cons "\\\\(\\[\t " "\\(?:[\t ") ;; Make a group shy
622 (should (re-equal-matches
623 ;; `Directives`_ / `Substitution Definitions`_
624 (concat re-bol "\\(" re-ems "\\)\\(\\(|[^|\n]+|[\t ]+\\)?\\)\\("
625 re-sym1 "+::\\)" re-blksep1)
626 "=== rst.el.~rst_el_1_68~:3042"
627 (rst-re 'lin-beg '(:grp exm-sta)
628 '(:grp (:shy subdef-tag hws-sta) "?")
629 '(:grp sym-tag dcl-tag) 'bli-sfx)
630 (list ".. |attr| replace:: val"
631 (cons 1 1)
632 (cons 2 2)
633 (cons 4 3))
634 (cons "\\\\(|" "\\(?:|") ;; Make a group shy
635 (cons "\\[^|\n]\\+" "\\(?:\\S \\|\\S \\(?:[^|\\\n]\\|\\\\.\\)\\{0,1000\\}[^ |\\]\\)"
636 ) ;; Symbol name more sophisticated
637 (cons (regexp-quote "\\(\\sw\\|\\s_\\)+")
638 "\\(?:\\sw+\\(?:[-+.:_]\\sw+\\)*\\)") ;; New syntax for
639 ;; symbols
640 (cons "\\\\(\\[\t " "\\(?:[\t ") ;; Make a group shy
642 (should (re-equal-matches
643 ;; `Hyperlink Targets`_
644 (concat re-bol "\\(" re-ems "_\\([^:\\`\n]\\|\\\\.\\|`[^`\n]+`\\)+:\\)"
645 re-blksep1)
646 "=== rst.el.~rst_el_1_68~:3049"
647 (rst-re 'lin-beg
648 '(:grp exm-sta "_" (:alt
649 (:seq "`" ilcbkqdef-tag "`")
650 (:seq (:alt "[^:\\\n]" "\\\\.") "+")) ":")
651 'bli-sfx)
652 (list ".. _`some\\: target`:"
653 (cons 1 1))
654 (cons (regexp-quote "\\([^:\\`\n]\\|\\\\.\\|`[^`\n]+`\\)+")
655 "\\(?:`\\(?:\\S \\|\\S \\(?:[^`\\\n]\\|\\\\.\\)\\{0,1000\\}[^ `\\]\\)`\\|\\(?:[^:\\\n]\\|\\\\.\\)+\\)"
656 ) ;; Hyperlink name recognition more sophisticated
657 (cons "\\\\(\\[\t " "\\(?:[\t ") ;; Make a group shy
659 (should (re-equal-matches
660 ;; `Hyperlink Targets`_
661 (concat re-bol "\\(__\\)" re-blksep1)
662 "=== rst.el.~rst_el_1_68~:3053"
663 (rst-re 'lin-beg '(:grp "__") 'bli-sfx)
664 (list " __"
665 (cons 1 1))
666 (cons "\\\\(\\[\t " "\\(?:[\t ") ;; Make a group shy
668 (should (re-equal-matches
669 ;; `Strong Emphasis`_
670 (concat re-imp1 "\\(\\*\\*" re-ima2 "\\*\\*\\)" re-ims1)
671 "=== rst.el.~rst_el_1_68~:3062"
672 (rst-re 'ilm-pfx '(:grp "\\*\\*" ilcast-tag "\\*\\*") 'ilm-sfx)
673 (list "abc **def** ghi"
674 (cons 2 1))
675 (cons "^\\\\(" "\\(?:") ;; Make a group shy
676 (cons "\\\\(\\\\S" "\\(?:\\S") ;; Make a group shy
677 (cons "\\\\(\\[^" "\\(?:[^") ;; Make a group shy
678 (cons (regexp-quote "\\\\]") "\\]") ;; Remove superfluous quote
679 (cons (regexp-quote "\\|$") "")
680 (cons (regexp-quote "\\([\t ]")
681 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
683 (should (re-equal-matches
684 ;; `Emphasis`_
685 (concat re-imp1 "\\(\\*" re-ima2 "\\*\\)" re-ims1)
686 "=== rst.el.~rst_el_1_68~:3066"
687 (rst-re 'ilm-pfx '(:grp "\\*" ilcast-tag "\\*") 'ilm-sfx)
688 (list "*x*"
689 (cons 2 1))
690 (cons "^\\\\(" "\\(?:") ;; Make a group shy
691 (cons "\\\\(\\\\S" "\\(?:\\S") ;; Make a group shy
692 (cons "\\\\(\\[^" "\\(?:[^") ;; Make a group shy
693 (cons (regexp-quote "\\\\]") "\\]") ;; Remove superfluous quote
694 (cons (regexp-quote "\\|$") "")
695 (cons (regexp-quote "\\([\t ]")
696 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
698 (should (re-equal-matches
699 ;; `Inline Literals`_
700 (concat re-imp1 "\\(``" re-imb2 "``\\)" re-ims1)
701 "=== rst.el.~rst_el_1_68~:3070"
702 (rst-re 'ilm-pfx '(:grp "``" ilcbkq-tag "``") 'ilm-sfx)
703 (list "``co de``"
704 (cons 2 1))
705 (cons "^\\\\(" "\\(?:") ;; Make a group shy
706 (cons "\\\\(\\\\S" "\\(?:\\S") ;; Make a group shy
707 (cons "\\\\(\\[^" "\\(?:[^") ;; Make a group shy
708 (cons (regexp-quote "\\\\]") "\\]") ;; Remove superfluous quote
709 (cons (regexp-quote "\\|$") "")
710 (cons (regexp-quote "\\([\t ]")
711 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
713 (should (re-equal-matches
714 ;; `Inline Internal Targets`_
715 (concat re-imp1 "\\(_`" re-imb2 "`\\)" re-ims1)
716 "=== rst.el.~rst_el_1_68~:3074"
717 (rst-re 'ilm-pfx '(:grp "_`" ilcbkq-tag "`") 'ilm-sfx)
718 (list "_`Inline\ntarget`"
719 (cons 2 1))
720 (cons "^\\\\(" "\\(?:") ;; Make a group shy
721 (cons "\\\\(\\\\S" "\\(?:\\S") ;; Make a group shy
722 (cons "\\\\(\\[^" "\\(?:[^") ;; Make a group shy
723 (cons (regexp-quote "\\\\]") "\\]") ;; Remove superfluous quote
724 (cons (regexp-quote "\\|$") "")
725 (cons (regexp-quote "\\([\t ]")
726 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
728 (should (re-equal-matches
729 ;; `Hyperlink References`_
730 (concat re-imp1 "\\(\\(`" re-imb2 "`\\|\\(\\sw\\(\\sw\\|-\\)+\\sw\\)\\)__?\\)" re-ims1)
731 "=== rst.el.~rst_el_1_68~:3079"
732 (rst-re 'ilm-pfx '(:grp (:alt (:seq "`" ilcbkq-tag "`")
733 (:seq "\\sw" (:alt "\\sw" "-") "+\\sw"))
734 "__?") 'ilm-sfx)
735 (list "<`xxx`__>"
736 (cons 2 1))
737 (cons "^\\\\(" "\\(?:") ;; Make a group shy
738 (cons "\\\\(\\\\S" "\\(?:\\S") ;; Make a group shy
739 (cons "\\\\(\\[^" "\\(?:[^") ;; Make a group shy
740 (cons (regexp-quote "\\\\]") "\\]") ;; Remove superfluous quote
741 (cons (regexp-quote "\\|$") "")
742 (cons (regexp-quote "\\([\t ]")
743 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
744 (cons "\\\\(`" "\\(?:`") ;; Make a group shy
745 (cons "\\\\(\\\\sw" "\\sw")
746 (cons "\\\\sw\\\\)" "\\sw") ;; Remove a group
747 (cons "sw\\\\(\\\\sw" "sw\\(?:\\sw") ;; Make a group shy
749 (should (re-equal-matches
750 ;; `Interpreted Text`_
751 (concat re-imp1 "\\(\\(:" re-sym1 "+:\\)?\\)\\(`" re-imb2 "`\\)\\(\\(:"
752 re-sym1 "+:\\)?\\)" re-ims1)
753 "=== rst.el.~rst_el_1_68~:3083"
754 (rst-re 'ilm-pfx '(:grp (:shy ":" sym-tag ":") "?")
755 '(:grp "`" ilcbkq-tag "`")
756 '(:grp (:shy ":" sym-tag ":") "?") 'ilm-sfx)
757 (list "`Interpreted`"
758 (cons 2 1)
759 (cons 5 2)
760 (cons 8 3))
761 (cons "^\\\\(" "\\(?:") ;; Make a group shy
762 (cons "\\\\(\\\\S" "\\(?:\\S") ;; Make a group shy
763 (cons "\\\\(\\[^" "\\(?:[^") ;; Make a group shy
764 (cons "\\\\(:" "\\(?::") ;; Make a group shy
765 (cons "\\\\(:" "\\(?::") ;; Make a group shy
766 (cons (regexp-quote "\\(\\sw\\|\\s_\\)+")
767 "\\(?:\\sw+\\(?:[-+.:_]\\sw+\\)*\\)") ;; New syntax for
768 ;; symbols
769 (cons (regexp-quote "\\(\\sw\\|\\s_\\)+")
770 "\\(?:\\sw+\\(?:[-+.:_]\\sw+\\)*\\)") ;; New syntax for
771 ;; symbols
772 (cons (regexp-quote "\\\\]") "\\]") ;; Remove superfluous quote
773 (cons (regexp-quote "\\|$") "")
774 (cons (regexp-quote "\\([\t ]")
775 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
777 (should (re-equal-matches
778 ;; `Footnote References`_ / `Citation References`_
779 (concat re-imp1 "\\(\\[[^]]+\\]_\\)" re-ims1)
780 "=== rst.el.~rst_el_1_68~:3090"
781 (rst-re 'ilm-pfx '(:grp fnc-tag "_") 'ilm-sfx)
782 (list "[1]_"
783 (cons 2 1))
784 (cons "^\\\\(" "\\(?:") ;; Make a group shy
785 (cons "]]" "]\n]") ;; A reference may not contain \n
786 (cons "\\\\]" "]") ;; Remove superfluous quote
787 (cons (regexp-quote "\\|$") "")
788 (cons (regexp-quote "\\([\t ]")
789 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
791 (should (re-equal-matches
792 ;; `Substitution References`_
793 (concat re-imp1 "\\(|" re-imv2 "|\\)" re-ims1)
794 "=== rst.el.~rst_el_1_68~:3094"
795 (rst-re 'ilm-pfx '(:grp sub-tag) 'ilm-sfx)
796 (list "|attr|"
797 (cons 2 1))
798 (cons "^\\\\(" "\\(?:") ;; Make a group shy
799 (cons "\\\\(\\\\S" "\\(?:\\S") ;; Make a group shy
800 (cons (regexp-quote "\\([^|") "\\(?:[^|") ;; Make a group shy
801 (cons "\\\\]" "]") ;; Remove superfluous quote
802 (cons "\\\\]" "]") ;; Remove superfluous quote
803 (cons "\\[^|]" "[^|\\]") ;; Improve recognition
804 (cons (regexp-quote "\\|$") "")
805 (cons (regexp-quote "\\([\t ]")
806 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
808 (should (re-equal-matches
809 ;; `Standalone Hyperlinks`_
810 (concat re-imp1 "\\(" re-uris1 ":\\S +\\)" re-ims1)
811 "=== rst.el.~rst_el_1_68~:3099"
812 (rst-re 'ilm-pfx '(:grp uri-tag ":\\S +") 'ilm-sfx)
813 (list "http://example.com/"
814 (cons 2 1))
815 (cons "^\\\\(" "\\(?:") ;; Make a group shy
816 (cons "\\\\(acap" "\\(?:acap") ;; Make a group shy
817 (cons (regexp-quote "\\|$") "")
818 (cons (regexp-quote "\\([\t ]")
819 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
821 (should (re-equal-matches
822 ;; `Standalone Hyperlinks`_
823 (concat re-imp1 "\\(" re-sym1 "+@" re-sym1 "+\\)" re-ims1)
824 "=== rst.el.~rst_el_1_68~:3102"
825 (rst-re 'ilm-pfx '(:grp sym-tag "@" sym-tag ) 'ilm-sfx)
826 (list "someone@example"
827 (cons 2 1))
828 (cons "^\\\\(" "\\(?:") ;; Make a group shy
829 (cons (regexp-quote "\\(\\sw\\|\\s_\\)+")
830 "\\(?:\\sw+\\(?:[-+.:_]\\sw+\\)*\\)") ;; New syntax for
831 ;; symbols
832 (cons (regexp-quote "\\(\\sw\\|\\s_\\)+")
833 "\\(?:\\sw+\\(?:[-+.:_]\\sw+\\)*\\)") ;; New syntax for
834 ;; symbols
835 (cons (regexp-quote "\\|$") "")
836 (cons (regexp-quote "\\([\t ]")
837 "\\(?:$\\|[\t ]") ;; Move "$" in regex and make a group shy
839 (should (re-equal
840 ;; Sections_ / Transitions_
841 re-ado2
842 "=== rst.el.~rst_el_1_68~:3109"
843 (rst-re 'ado-beg-2-1)
844 (cons "\\^\\[:word:]\\[:space:]\\[:cntrl:]"
845 "]!\"#$%&'()*+,./:;<=>?@[\\^_`{|}~-") ;; Use real adornment
846 ;; characters
847 (cons "2\\+" "{2,\\}") ;; Use repeat count
849 (should (re-equal
850 ;; `Comments`_
851 (concat re-bol "\\(" re-ems "\\)\[^[|_\n]\\([^:\n]\\|:\\([^:\n]\\|$\\)\\)*$")
852 "=== rst.el.~rst_el_1_68~:3128"
853 (rst-re 'lin-beg '(:grp exm-sta) "[^\[|_\n]"
854 '(:alt "[^:\n]" (:seq ":" (:alt "[^:\n]" "$"))) "*$")
855 (cons "\\\\(\\[^:" "\\(?:[^:") ;; Make a group shy
856 (cons "\\\\(\\[^:" "\\(?:[^:") ;; Make a group shy
858 (should (re-equal-matches
859 ;; `Comments`_
860 (concat re-bol "\\(" re-emt "\\)\\(\\s *\\)$")
861 "=== rst.el.~rst_el_1_68~:3135"
862 (rst-re 'lin-beg '(:grp exm-tag) '(:grp hws-tag) "$")
863 (list ".. "
864 (cons 1 1)
865 (cons 2 2))
866 (cons "\\\\s " "[\t ]") ;; Only horizontal space
868 (should (re-equal-matches
869 ;; `Literal Blocks`_
870 (concat re-bol "\\(\\([^.\n]\\|\\.[^.\n]\\).*\\)?\\(::\\)$")
871 "=== rst.el.~rst_el_1_68~:3145"
872 (rst-re 'lin-beg '(:shy (:alt "[^.\n]" "\\.[^.\n]") ".*") "?"
873 '(:grp dcl-tag) "$")
874 (list "Some text ::"
875 (cons 3 1))
876 (cons "\\\\(\\\\(" "\\(?:\\(?:") ;; Make two groups shy
878 (should (re-equal-matches
879 ;; `Doctest Blocks`_
880 (concat re-bol "\\(>>>\\|\\.\\.\\.\\)\\(.+\\)")
881 "=== rst.el.~rst_el_1_68~:3154"
882 (rst-re 'lin-beg '(:grp (:alt ">>>" ell-tag)) '(:grp ".+"))
883 (list ">>> content"
884 (cons 1 1)
885 (cons 2 2))
886 (cons ">>>" "\\(?:>>>") (cons "\\.\\\\)" ".\\)\\)") ;; Add a shy
887 ;; group