88#include "xtag.h"
99
1010
11+ typedef enum {
12+ K_TITLE ,
13+ K_SECTION ,
14+ K_SUBSECTION ,
15+ } ManKind ;
16+
17+
1118static void initializeManParser (const langType language )
1219{
1320 addLanguageOptscriptToHook (language , SCRIPT_HOOK_PRELUDE ,
14- "{{ % /replace SCOPE-ACTION -\n"
15- " % /push SCOPE-ACTION -\n"
16- " /scope-action {\n"
21+ "{{ % adjustment:int FILL-END-OF-SCOPE -\n"
22+ " %\n"
23+ " % Note: The group 1 of a regex matching is assumed.\n"
24+ " % An entry on the scope stack is assumed.\n"
25+ " /fill-end-of-scope {\n"
26+ " _scopetop pop exch\n"
27+ " % scope-top:int adjustment:int\n"
28+ " 1 /start _matchloc _matchloc2line exch\n"
29+ " % scope-top:int line adjustment:int\n"
30+ " 2 copy gt {\n"
31+ " sub end:\n"
32+ " } {\n"
33+ " pop pop pop\n"
34+ " } ifelse\n"
35+ " } def\n"
36+ " % adjustment:int /replace HEADING-ACTION -\n"
37+ " % /push HEADING-ACTION -\n"
38+ " /heading-action {\n"
1739 " /replace eq {\n"
18- " _scopetop pop 1 /start _matchloc _matchloc2line dup 2 gt {\n"
19- " 2 sub end:\n"
20- " } {\n"
21- " pop\n"
22- " pop\n"
23- " } ifelse\n"
40+ " %\n"
41+ " % Before removing the tag at the top of the scope stack,\n"
42+ " % fill the end field of the tag.\n"
43+ " %\n"
44+ " % input0.man\n"
45+ " % ----------------------------------------------------\n"
46+ " % .SH SEC1\n"
47+ " % ...\n"
48+ " %E: This is the end of the SEC1.\n"
49+ " % .SH\n"
50+ " %C: SEC2\n"
51+ " %\n"
52+ " % ----------------------------------------------------\n"
53+ " %\n"
54+ " % C represents the current input line. The parser must\n"
55+ " % fill the end field of \"SEC1\", the tag at the top,\n"
56+ " % with the line number of E.\n"
57+ " %\n"
58+ " % E = C - 2\n"
59+ " %\n"
60+ " % input1.man\n"
61+ " % ----------------------------------------------------\n"
62+ " % .SH SEC3\n"
63+ " % ...\n"
64+ " %E: This is the end of the SEC1.\n"
65+ " %C: .SH SEC4\n"
66+ " %\n"
67+ " % ----------------------------------------------------\n"
68+ " %\n"
69+ " % In this case\n"
70+ " %\n"
71+ " % E = C - 1\n"
72+ " %\n"
73+ " % The offset for the adjustment depends on the conctxt.\n"
74+ " %\n"
75+ " fill-end-of-scope\n"
2476 " _scopepop\n"
2577 " } if\n"
2678 "\n"
@@ -34,6 +86,8 @@ static void initializeManParser (const langType language)
3486 addLanguageRegexTable (language , "main" );
3587 addLanguageRegexTable (language , "section" );
3688 addLanguageRegexTable (language , "sectionheading" );
89+ addLanguageRegexTable (language , "subsection" );
90+ addLanguageRegexTable (language , "subsectionheading" );
3791 addLanguageRegexTable (language , "EOF" );
3892 addLanguageRegexTable (language , "SKIP" );
3993 addLanguageRegexTable (language , "REST" );
@@ -76,10 +130,22 @@ static void initializeManParser (const langType language)
76130 "^\\.SH[\t ]+([^\n]+)\n" ,
77131 "\\1" , "s" , "{icase}{scope=replace}" , NULL );
78132 addLanguageTagMultiTableRegex (language , "section" ,
79- "^\\.SH[\t ]*\n" ,
80- "" , "" , "{icase}{tenter =sectionheading}"
133+ "^( \\.SH) [\t ]*\n" ,
134+ "" , "" , "{icase}{tjump =sectionheading}"
81135 "{{\n"
82- " /replace\n"
136+ " 2 /replace\n"
137+ "}}" , NULL );
138+ addLanguageTagMultiTableRegex (language , "section" ,
139+ "^\\.SS[\t ]+\"([^\"\n]+)\"[^\n]*\n" ,
140+ "\\1" , "S" , "{icase}{scope=push}{tenter=subsection}" , NULL );
141+ addLanguageTagMultiTableRegex (language , "section" ,
142+ "^\\.SS[\t ]+([^\n]+)\n" ,
143+ "\\1" , "S" , "{icase}{scope=push}{tenter=subsection}" , NULL );
144+ addLanguageTagMultiTableRegex (language , "section" ,
145+ "^\\.SS[\t ]*\n" ,
146+ "" , "" , "{icase}{tenter=subsectionheading}"
147+ "{{\n"
148+ " /push\n"
83149 "}}" , NULL );
84150 addLanguageTagMultiTableRegex (language , "section" ,
85151 "^[^\n]*\n|[^\n]+" ,
@@ -89,16 +155,56 @@ static void initializeManParser (const langType language)
89155 "" , "" , "{scope=clear}{tquit}" , NULL );
90156 addLanguageTagMultiTableRegex (language , "sectionheading" ,
91157 "^[ \t]*([^\n]+)\n" ,
92- "\\1" , "s" , "{tleave }"
158+ "\\1" , "s" , "{tjump=section }"
93159 "{{\n"
94- " scope -action\n"
160+ " heading -action\n"
95161 "}}" , NULL );
96162 addLanguageTagMultiTableRegex (language , "sectionheading" ,
97163 "^[^\n]*\n|[^\n]+" ,
98164 "" , "" , "" , NULL );
99165 addLanguageTagMultiTableRegex (language , "sectionheading" ,
100166 "^" ,
101167 "" , "" , "{scope=clear}{tquit}" , NULL );
168+ addLanguageTagMultiTableRegex (language , "subsection" ,
169+ "^([^\n.]|\\.[^\nst])[^\n]*\n" ,
170+ "" , "" , "{icase}" , NULL );
171+ addLanguageTagMultiTableRegex (language , "subsection" ,
172+ "^\\.SS[\t ]+\"([^\"\n]+)\"[^\n]*\n" ,
173+ "\\1" , "S" , "{icase}{scope=replace}" , NULL );
174+ addLanguageTagMultiTableRegex (language , "subsection" ,
175+ "^\\.SS[\t ]+([^\n]+)\n" ,
176+ "\\1" , "S" , "{icase}{scope=replace}" , NULL );
177+ addLanguageTagMultiTableRegex (language , "subsection" ,
178+ "^\\.SS[\t ]*\n" ,
179+ "" , "" , "{icase}{tjump=subsectionheading}"
180+ "{{\n"
181+ " 2 /replace\n"
182+ "}}" , NULL );
183+ addLanguageTagMultiTableRegex (language , "subsection" ,
184+ "^(\\.SH)" ,
185+ "" , "" , "{icase}{_advanceTo=0start}{tleave}"
186+ "{{\n"
187+ " 1 fill-end-of-scope\n"
188+ " _scopepop\n"
189+ "}}" , NULL );
190+ addLanguageTagMultiTableRegex (language , "subsection" ,
191+ "^[^\n]*\n|[^\n]+" ,
192+ "" , "" , "" , NULL );
193+ addLanguageTagMultiTableRegex (language , "subsection" ,
194+ "^" ,
195+ "" , "" , "{scope=clear}{tquit}" , NULL );
196+ addLanguageTagMultiTableRegex (language , "subsectionheading" ,
197+ "^[ \t]*([^\n]+)\n" ,
198+ "\\1" , "S" , "{tjump=subsection}"
199+ "{{\n"
200+ " heading-action\n"
201+ "}}" , NULL );
202+ addLanguageTagMultiTableRegex (language , "subsectionheading" ,
203+ "^[^\n]*\n|[^\n]+" ,
204+ "" , "" , "" , NULL );
205+ addLanguageTagMultiTableRegex (language , "subsectionheading" ,
206+ "^" ,
207+ "" , "" , "{scope=clear}{tquit}" , NULL );
102208 addLanguageTagMultiTableRegex (language , "EOF" ,
103209 "^" ,
104210 "" , "" , "{scope=clear}{tquit}" , NULL );
@@ -149,6 +255,9 @@ extern parserDefinition* ManParser (void)
149255 {
150256 true, 's' , "section" , "sections" ,
151257 },
258+ {
259+ true, 'S' , "subsection" , "sub sections" ,
260+ },
152261 };
153262
154263 parserDefinition * const def = parserNew ("Man" );
@@ -161,6 +270,7 @@ extern parserDefinition* ManParser (void)
161270 def -> useCork = CORK_QUEUE ;
162271 def -> kindTable = ManKindTable ;
163272 def -> kindCount = ARRAY_SIZE (ManKindTable );
273+ def -> defaultScopeSeparator = "\"\"" ;
164274 def -> initialize = initializeManParser ;
165275
166276 return def ;
0 commit comments