ctags.rb 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. data/Gemfile +2 -0
  2. data/Rakefile +23 -0
  3. data/ctags.rb.gemspec +23 -0
  4. data/ext/.gitignore +3 -0
  5. data/ext/extconf.rb +15 -0
  6. data/ext/vendor/exuberant-ctags/.gitignore +6 -0
  7. data/ext/vendor/exuberant-ctags/.indent.pro +31 -0
  8. data/ext/vendor/exuberant-ctags/COPYING +340 -0
  9. data/ext/vendor/exuberant-ctags/EXTENDING.html +386 -0
  10. data/ext/vendor/exuberant-ctags/FAQ +371 -0
  11. data/ext/vendor/exuberant-ctags/INSTALL +215 -0
  12. data/ext/vendor/exuberant-ctags/INSTALL.oth +73 -0
  13. data/ext/vendor/exuberant-ctags/MAINTAINERS +88 -0
  14. data/ext/vendor/exuberant-ctags/Makefile.in +222 -0
  15. data/ext/vendor/exuberant-ctags/NEWS +871 -0
  16. data/ext/vendor/exuberant-ctags/README +73 -0
  17. data/ext/vendor/exuberant-ctags/ant.c +42 -0
  18. data/ext/vendor/exuberant-ctags/argproc.c +505 -0
  19. data/ext/vendor/exuberant-ctags/args.c +274 -0
  20. data/ext/vendor/exuberant-ctags/args.h +63 -0
  21. data/ext/vendor/exuberant-ctags/asm.c +387 -0
  22. data/ext/vendor/exuberant-ctags/asp.c +328 -0
  23. data/ext/vendor/exuberant-ctags/awk.c +81 -0
  24. data/ext/vendor/exuberant-ctags/basic.c +203 -0
  25. data/ext/vendor/exuberant-ctags/beta.c +321 -0
  26. data/ext/vendor/exuberant-ctags/c.c +2932 -0
  27. data/ext/vendor/exuberant-ctags/cobol.c +50 -0
  28. data/ext/vendor/exuberant-ctags/config.h.in +277 -0
  29. data/ext/vendor/exuberant-ctags/configure +7704 -0
  30. data/ext/vendor/exuberant-ctags/configure.ac +532 -0
  31. data/ext/vendor/exuberant-ctags/ctags.1 +1186 -0
  32. data/ext/vendor/exuberant-ctags/ctags.h +28 -0
  33. data/ext/vendor/exuberant-ctags/ctags.html +2087 -0
  34. data/ext/vendor/exuberant-ctags/ctags.spec +40 -0
  35. data/ext/vendor/exuberant-ctags/debug.c +113 -0
  36. data/ext/vendor/exuberant-ctags/debug.h +70 -0
  37. data/ext/vendor/exuberant-ctags/descrip.mms +68 -0
  38. data/ext/vendor/exuberant-ctags/dosbatch.c +42 -0
  39. data/ext/vendor/exuberant-ctags/e_amiga.h +24 -0
  40. data/ext/vendor/exuberant-ctags/e_djgpp.h +47 -0
  41. data/ext/vendor/exuberant-ctags/e_mac.h +143 -0
  42. data/ext/vendor/exuberant-ctags/e_msoft.h +76 -0
  43. data/ext/vendor/exuberant-ctags/e_os2.h +37 -0
  44. data/ext/vendor/exuberant-ctags/e_qdos.h +34 -0
  45. data/ext/vendor/exuberant-ctags/e_riscos.h +58 -0
  46. data/ext/vendor/exuberant-ctags/e_vms.h +31 -0
  47. data/ext/vendor/exuberant-ctags/eiffel.c +1352 -0
  48. data/ext/vendor/exuberant-ctags/entry.c +847 -0
  49. data/ext/vendor/exuberant-ctags/entry.h +103 -0
  50. data/ext/vendor/exuberant-ctags/erlang.c +189 -0
  51. data/ext/vendor/exuberant-ctags/flex.c +2243 -0
  52. data/ext/vendor/exuberant-ctags/fortran.c +2197 -0
  53. data/ext/vendor/exuberant-ctags/general.h +127 -0
  54. data/ext/vendor/exuberant-ctags/get.c +669 -0
  55. data/ext/vendor/exuberant-ctags/get.h +50 -0
  56. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/all-wcprops +47 -0
  57. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/entries +112 -0
  58. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/README.txt.svn-base +5 -0
  59. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regcomp.c.svn-base +3818 -0
  60. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.c.svn-base +74 -0
  61. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.h.svn-base +575 -0
  62. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.c.svn-base +1713 -0
  63. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.h.svn-base +773 -0
  64. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regexec.c.svn-base +4338 -0
  65. data/ext/vendor/exuberant-ctags/gnu_regex/README.txt +5 -0
  66. data/ext/vendor/exuberant-ctags/gnu_regex/regcomp.c +3818 -0
  67. data/ext/vendor/exuberant-ctags/gnu_regex/regex.c +74 -0
  68. data/ext/vendor/exuberant-ctags/gnu_regex/regex.h +575 -0
  69. data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.c +1713 -0
  70. data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.h +773 -0
  71. data/ext/vendor/exuberant-ctags/gnu_regex/regexec.c +4338 -0
  72. data/ext/vendor/exuberant-ctags/html.c +49 -0
  73. data/ext/vendor/exuberant-ctags/jscript.c +1572 -0
  74. data/ext/vendor/exuberant-ctags/keyword.c +258 -0
  75. data/ext/vendor/exuberant-ctags/keyword.h +34 -0
  76. data/ext/vendor/exuberant-ctags/lisp.c +139 -0
  77. data/ext/vendor/exuberant-ctags/lregex.c +704 -0
  78. data/ext/vendor/exuberant-ctags/lua.c +133 -0
  79. data/ext/vendor/exuberant-ctags/mac.c +273 -0
  80. data/ext/vendor/exuberant-ctags/magic.diff +21 -0
  81. data/ext/vendor/exuberant-ctags/main.c +584 -0
  82. data/ext/vendor/exuberant-ctags/main.h +32 -0
  83. data/ext/vendor/exuberant-ctags/maintainer.mak +476 -0
  84. data/ext/vendor/exuberant-ctags/make.c +217 -0
  85. data/ext/vendor/exuberant-ctags/matlab.c +44 -0
  86. data/ext/vendor/exuberant-ctags/mk_bc3.mak +46 -0
  87. data/ext/vendor/exuberant-ctags/mk_bc5.mak +49 -0
  88. data/ext/vendor/exuberant-ctags/mk_djg.mak +18 -0
  89. data/ext/vendor/exuberant-ctags/mk_manx.mak +65 -0
  90. data/ext/vendor/exuberant-ctags/mk_mingw.mak +31 -0
  91. data/ext/vendor/exuberant-ctags/mk_mpw.mak +130 -0
  92. data/ext/vendor/exuberant-ctags/mk_mvc.mak +40 -0
  93. data/ext/vendor/exuberant-ctags/mk_os2.mak +104 -0
  94. data/ext/vendor/exuberant-ctags/mk_qdos.mak +100 -0
  95. data/ext/vendor/exuberant-ctags/mk_sas.mak +63 -0
  96. data/ext/vendor/exuberant-ctags/mkinstalldirs +40 -0
  97. data/ext/vendor/exuberant-ctags/ocaml.c +1842 -0
  98. data/ext/vendor/exuberant-ctags/options.c +1842 -0
  99. data/ext/vendor/exuberant-ctags/options.h +155 -0
  100. data/ext/vendor/exuberant-ctags/parse.c +677 -0
  101. data/ext/vendor/exuberant-ctags/parse.h +129 -0
  102. data/ext/vendor/exuberant-ctags/parsers.h +63 -0
  103. data/ext/vendor/exuberant-ctags/pascal.c +267 -0
  104. data/ext/vendor/exuberant-ctags/perl.c +382 -0
  105. data/ext/vendor/exuberant-ctags/php.c +237 -0
  106. data/ext/vendor/exuberant-ctags/python.c +771 -0
  107. data/ext/vendor/exuberant-ctags/qdos.c +106 -0
  108. data/ext/vendor/exuberant-ctags/read.c +569 -0
  109. data/ext/vendor/exuberant-ctags/read.h +116 -0
  110. data/ext/vendor/exuberant-ctags/readtags.c +959 -0
  111. data/ext/vendor/exuberant-ctags/readtags.h +252 -0
  112. data/ext/vendor/exuberant-ctags/rexx.c +39 -0
  113. data/ext/vendor/exuberant-ctags/routines.c +891 -0
  114. data/ext/vendor/exuberant-ctags/routines.h +134 -0
  115. data/ext/vendor/exuberant-ctags/ruby.c +408 -0
  116. data/ext/vendor/exuberant-ctags/scheme.c +111 -0
  117. data/ext/vendor/exuberant-ctags/sh.c +115 -0
  118. data/ext/vendor/exuberant-ctags/slang.c +41 -0
  119. data/ext/vendor/exuberant-ctags/sml.c +212 -0
  120. data/ext/vendor/exuberant-ctags/sort.c +230 -0
  121. data/ext/vendor/exuberant-ctags/sort.h +32 -0
  122. data/ext/vendor/exuberant-ctags/source.mak +122 -0
  123. data/ext/vendor/exuberant-ctags/sql.c +2112 -0
  124. data/ext/vendor/exuberant-ctags/strlist.c +281 -0
  125. data/ext/vendor/exuberant-ctags/strlist.h +54 -0
  126. data/ext/vendor/exuberant-ctags/tcl.c +116 -0
  127. data/ext/vendor/exuberant-ctags/tex.c +524 -0
  128. data/ext/vendor/exuberant-ctags/verilog.c +340 -0
  129. data/ext/vendor/exuberant-ctags/vhdl.c +835 -0
  130. data/ext/vendor/exuberant-ctags/vim.c +636 -0
  131. data/ext/vendor/exuberant-ctags/vstring.c +232 -0
  132. data/ext/vendor/exuberant-ctags/vstring.h +85 -0
  133. data/ext/vendor/exuberant-ctags/yacc.c +40 -0
  134. data/lib/ctags/exuberant.rb +45 -0
  135. data/lib/ctags/version.rb +3 -0
  136. data/lib/ctags.rb +6 -0
  137. data/test/test_ctags.rb +24 -0
  138. metadata +233 -0
@@ -0,0 +1,524 @@
1
+ /*
2
+ * $Id: tex.c 666 2008-05-15 17:47:31Z dfishburn $
3
+ *
4
+ * Copyright (c) 2008, David Fishburn
5
+ *
6
+ * This source code is released for free distribution under the terms of the
7
+ * GNU General Public License.
8
+ *
9
+ * This module contains functions for generating tags for TeX language files.
10
+ *
11
+ * Tex language reference:
12
+ * http://en.wikibooks.org/wiki/TeX#The_Structure_of_TeX
13
+ */
14
+
15
+ /*
16
+ * INCLUDE FILES
17
+ */
18
+ #include "general.h" /* must always come first */
19
+ #include <ctype.h> /* to define isalpha () */
20
+ #include <setjmp.h>
21
+ #ifdef DEBUG
22
+ #include <stdio.h>
23
+ #endif
24
+
25
+ #include "debug.h"
26
+ #include "entry.h"
27
+ #include "keyword.h"
28
+ #include "parse.h"
29
+ #include "read.h"
30
+ #include "routines.h"
31
+ #include "vstring.h"
32
+
33
+ /*
34
+ * MACROS
35
+ */
36
+ #define isType(token,t) (boolean) ((token)->type == (t))
37
+ #define isKeyword(token,k) (boolean) ((token)->keyword == (k))
38
+
39
+ /*
40
+ * DATA DECLARATIONS
41
+ */
42
+
43
+ typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
44
+
45
+ /*
46
+ * Used to specify type of keyword.
47
+ */
48
+ typedef enum eKeywordId {
49
+ KEYWORD_NONE = -1,
50
+ KEYWORD_chapter,
51
+ KEYWORD_section,
52
+ KEYWORD_subsection,
53
+ KEYWORD_subsubsection,
54
+ KEYWORD_part,
55
+ KEYWORD_paragraph,
56
+ KEYWORD_subparagraph
57
+ } keywordId;
58
+
59
+ /* Used to determine whether keyword is valid for the token language and
60
+ * what its ID is.
61
+ */
62
+ typedef struct sKeywordDesc {
63
+ const char *name;
64
+ keywordId id;
65
+ } keywordDesc;
66
+
67
+ typedef enum eTokenType {
68
+ TOKEN_UNDEFINED,
69
+ TOKEN_CHARACTER,
70
+ TOKEN_CLOSE_PAREN,
71
+ TOKEN_SEMICOLON,
72
+ TOKEN_COLON,
73
+ TOKEN_COMMA,
74
+ TOKEN_KEYWORD,
75
+ TOKEN_OPEN_PAREN,
76
+ TOKEN_OPERATOR,
77
+ TOKEN_IDENTIFIER,
78
+ TOKEN_STRING,
79
+ TOKEN_PERIOD,
80
+ TOKEN_OPEN_CURLY,
81
+ TOKEN_CLOSE_CURLY,
82
+ TOKEN_EQUAL_SIGN,
83
+ TOKEN_EXCLAMATION,
84
+ TOKEN_FORWARD_SLASH,
85
+ TOKEN_OPEN_SQUARE,
86
+ TOKEN_CLOSE_SQUARE,
87
+ TOKEN_OPEN_MXML,
88
+ TOKEN_CLOSE_MXML,
89
+ TOKEN_CLOSE_SGML,
90
+ TOKEN_LESS_THAN,
91
+ TOKEN_GREATER_THAN,
92
+ TOKEN_QUESTION_MARK,
93
+ TOKEN_STAR
94
+ } tokenType;
95
+
96
+ typedef struct sTokenInfo {
97
+ tokenType type;
98
+ keywordId keyword;
99
+ vString * string;
100
+ vString * scope;
101
+ unsigned long lineNumber;
102
+ fpos_t filePosition;
103
+ } tokenInfo;
104
+
105
+ /*
106
+ * DATA DEFINITIONS
107
+ */
108
+
109
+ static langType Lang_js;
110
+
111
+ static jmp_buf Exception;
112
+
113
+ typedef enum {
114
+ TEXTAG_CHAPTER,
115
+ TEXTAG_SECTION,
116
+ TEXTAG_SUBSECTION,
117
+ TEXTAG_SUBSUBSECTION,
118
+ TEXTAG_PART,
119
+ TEXTAG_PARAGRAPH,
120
+ TEXTAG_SUBPARAGRAPH,
121
+ TEXTAG_COUNT
122
+ } texKind;
123
+
124
+ static kindOption TexKinds [] = {
125
+ { TRUE, 'c', "chapter", "chapters" },
126
+ { TRUE, 's', "section", "sections" },
127
+ { TRUE, 'u', "subsection", "subsections" },
128
+ { TRUE, 'b', "subsubsection", "subsubsections" },
129
+ { TRUE, 'p', "part", "parts" },
130
+ { TRUE, 'P', "paragraph", "paragraphs" },
131
+ { TRUE, 'G', "subparagraph", "subparagraphs" }
132
+ };
133
+
134
+ static const keywordDesc TexKeywordTable [] = {
135
+ /* keyword keyword ID */
136
+ { "chapter", KEYWORD_chapter },
137
+ { "section", KEYWORD_section },
138
+ { "subsection", KEYWORD_subsection },
139
+ { "subsubsection", KEYWORD_subsubsection },
140
+ { "part", KEYWORD_part },
141
+ { "paragraph", KEYWORD_paragraph },
142
+ { "subparagraph", KEYWORD_subparagraph }
143
+ };
144
+
145
+ /*
146
+ * FUNCTION DEFINITIONS
147
+ */
148
+
149
+ static boolean isIdentChar (const int c)
150
+ {
151
+ return (boolean)
152
+ (isalpha (c) || isdigit (c) || c == '$' ||
153
+ c == '_' || c == '#');
154
+ }
155
+
156
+ static void buildTexKeywordHash (void)
157
+ {
158
+ const size_t count = sizeof (TexKeywordTable) /
159
+ sizeof (TexKeywordTable [0]);
160
+ size_t i;
161
+ for (i = 0 ; i < count ; ++i)
162
+ {
163
+ const keywordDesc* const p = &TexKeywordTable [i];
164
+ addKeyword (p->name, Lang_js, (int) p->id);
165
+ }
166
+ }
167
+
168
+ static tokenInfo *newToken (void)
169
+ {
170
+ tokenInfo *const token = xMalloc (1, tokenInfo);
171
+
172
+ token->type = TOKEN_UNDEFINED;
173
+ token->keyword = KEYWORD_NONE;
174
+ token->string = vStringNew ();
175
+ token->scope = vStringNew ();
176
+ token->lineNumber = getSourceLineNumber ();
177
+ token->filePosition = getInputFilePosition ();
178
+
179
+ return token;
180
+ }
181
+
182
+ static void deleteToken (tokenInfo *const token)
183
+ {
184
+ vStringDelete (token->string);
185
+ vStringDelete (token->scope);
186
+ eFree (token);
187
+ }
188
+
189
+ /*
190
+ * Tag generation functions
191
+ */
192
+
193
+ static void makeConstTag (tokenInfo *const token, const texKind kind)
194
+ {
195
+ if (TexKinds [kind].enabled )
196
+ {
197
+ const char *const name = vStringValue (token->string);
198
+ tagEntryInfo e;
199
+ initTagEntry (&e, name);
200
+
201
+ e.lineNumber = token->lineNumber;
202
+ e.filePosition = token->filePosition;
203
+ e.kindName = TexKinds [kind].name;
204
+ e.kind = TexKinds [kind].letter;
205
+
206
+ makeTagEntry (&e);
207
+ }
208
+ }
209
+
210
+ static void makeTexTag (tokenInfo *const token, texKind kind)
211
+ {
212
+ vString * fulltag;
213
+
214
+ if (TexKinds [kind].enabled)
215
+ {
216
+ /*
217
+ * If a scope has been added to the token, change the token
218
+ * string to include the scope when making the tag.
219
+ */
220
+ if ( vStringLength (token->scope) > 0 )
221
+ {
222
+ fulltag = vStringNew ();
223
+ vStringCopy (fulltag, token->scope);
224
+ vStringCatS (fulltag, ".");
225
+ vStringCatS (fulltag, vStringValue (token->string));
226
+ vStringTerminate (fulltag);
227
+ vStringCopy (token->string, fulltag);
228
+ vStringDelete (fulltag);
229
+ }
230
+ makeConstTag (token, kind);
231
+ }
232
+ }
233
+
234
+ /*
235
+ * Parsing functions
236
+ */
237
+
238
+ static void parseString (vString *const string, const int delimiter)
239
+ {
240
+ boolean end = FALSE;
241
+ while (! end)
242
+ {
243
+ int c = fileGetc ();
244
+ if (c == EOF)
245
+ end = TRUE;
246
+ else if (c == '\\')
247
+ {
248
+ c = fileGetc(); /* This maybe a ' or ". */
249
+ vStringPut (string, c);
250
+ }
251
+ else if (c == delimiter)
252
+ end = TRUE;
253
+ else
254
+ vStringPut (string, c);
255
+ }
256
+ vStringTerminate (string);
257
+ }
258
+
259
+ /*
260
+ * Read a C identifier beginning with "firstChar" and places it into
261
+ * "name".
262
+ */
263
+ static void parseIdentifier (vString *const string, const int firstChar)
264
+ {
265
+ int c = firstChar;
266
+ Assert (isIdentChar (c));
267
+ do
268
+ {
269
+ vStringPut (string, c);
270
+ c = fileGetc ();
271
+ } while (isIdentChar (c));
272
+
273
+ vStringTerminate (string);
274
+ if (!isspace (c))
275
+ fileUngetc (c); /* unget non-identifier character */
276
+ }
277
+
278
+ static void readToken (tokenInfo *const token)
279
+ {
280
+ int c;
281
+
282
+ token->type = TOKEN_UNDEFINED;
283
+ token->keyword = KEYWORD_NONE;
284
+ vStringClear (token->string);
285
+
286
+ getNextChar:
287
+ do
288
+ {
289
+ c = fileGetc ();
290
+ token->lineNumber = getSourceLineNumber ();
291
+ token->filePosition = getInputFilePosition ();
292
+ }
293
+ while (c == '\t' || c == ' ' || c == '\n');
294
+
295
+ switch (c)
296
+ {
297
+ case EOF: longjmp (Exception, (int)ExceptionEOF); break;
298
+ case '(': token->type = TOKEN_OPEN_PAREN; break;
299
+ case ')': token->type = TOKEN_CLOSE_PAREN; break;
300
+ case ';': token->type = TOKEN_SEMICOLON; break;
301
+ case ',': token->type = TOKEN_COMMA; break;
302
+ case '.': token->type = TOKEN_PERIOD; break;
303
+ case ':': token->type = TOKEN_COLON; break;
304
+ case '{': token->type = TOKEN_OPEN_CURLY; break;
305
+ case '}': token->type = TOKEN_CLOSE_CURLY; break;
306
+ case '=': token->type = TOKEN_EQUAL_SIGN; break;
307
+ case '[': token->type = TOKEN_OPEN_SQUARE; break;
308
+ case ']': token->type = TOKEN_CLOSE_SQUARE; break;
309
+ case '?': token->type = TOKEN_QUESTION_MARK; break;
310
+ case '*': token->type = TOKEN_STAR; break;
311
+
312
+ case '\'':
313
+ case '"':
314
+ token->type = TOKEN_STRING;
315
+ parseString (token->string, c);
316
+ token->lineNumber = getSourceLineNumber ();
317
+ token->filePosition = getInputFilePosition ();
318
+ break;
319
+
320
+ case '\\':
321
+ /*
322
+ * All Tex tags start with a backslash.
323
+ * Check if the next character is an alpha character
324
+ * else it is not a potential tex tag.
325
+ */
326
+ c = fileGetc ();
327
+ if (! isalpha (c))
328
+ fileUngetc (c);
329
+ else
330
+ {
331
+ parseIdentifier (token->string, c);
332
+ token->lineNumber = getSourceLineNumber ();
333
+ token->filePosition = getInputFilePosition ();
334
+ token->keyword = analyzeToken (token->string, Lang_js);
335
+ if (isKeyword (token, KEYWORD_NONE))
336
+ token->type = TOKEN_IDENTIFIER;
337
+ else
338
+ token->type = TOKEN_KEYWORD;
339
+ }
340
+ break;
341
+
342
+ case '%':
343
+ fileSkipToCharacter ('\n'); /* % are single line comments */
344
+ goto getNextChar;
345
+ break;
346
+
347
+ default:
348
+ if (! isIdentChar (c))
349
+ token->type = TOKEN_UNDEFINED;
350
+ else
351
+ {
352
+ parseIdentifier (token->string, c);
353
+ token->lineNumber = getSourceLineNumber ();
354
+ token->filePosition = getInputFilePosition ();
355
+ token->type = TOKEN_IDENTIFIER;
356
+ }
357
+ break;
358
+ }
359
+ }
360
+
361
+ static void copyToken (tokenInfo *const dest, tokenInfo *const src)
362
+ {
363
+ dest->lineNumber = src->lineNumber;
364
+ dest->filePosition = src->filePosition;
365
+ dest->type = src->type;
366
+ dest->keyword = src->keyword;
367
+ vStringCopy (dest->string, src->string);
368
+ vStringCopy (dest->scope, src->scope);
369
+ }
370
+
371
+ /*
372
+ * Scanning functions
373
+ */
374
+
375
+ static boolean parseTag (tokenInfo *const token, texKind kind)
376
+ {
377
+ tokenInfo *const name = newToken ();
378
+ vString * fullname;
379
+ boolean useLongName = TRUE;
380
+
381
+ fullname = vStringNew ();
382
+ vStringClear (fullname);
383
+
384
+ /*
385
+ * Tex tags are of these formats:
386
+ * \keyword{any number of words}
387
+ * \keyword[short desc]{any number of words}
388
+ * \keyword*[short desc]{any number of words}
389
+ *
390
+ * When a keyword is found, loop through all words within
391
+ * the curly braces for the tag name.
392
+ */
393
+
394
+ if (isType (token, TOKEN_KEYWORD))
395
+ {
396
+ copyToken (name, token);
397
+ readToken (token);
398
+ }
399
+
400
+ if (isType (token, TOKEN_OPEN_SQUARE))
401
+ {
402
+ useLongName = FALSE;
403
+
404
+ readToken (token);
405
+ while (! isType (token, TOKEN_CLOSE_SQUARE) )
406
+ {
407
+ if (isType (token, TOKEN_IDENTIFIER))
408
+ {
409
+ if (fullname->length > 0)
410
+ vStringCatS (fullname, " ");
411
+ vStringCatS (fullname, vStringValue (token->string));
412
+ }
413
+ readToken (token);
414
+ }
415
+ vStringTerminate (fullname);
416
+ vStringCopy (name->string, fullname);
417
+ makeTexTag (name, kind);
418
+ }
419
+
420
+ if (isType (token, TOKEN_STAR))
421
+ {
422
+ readToken (token);
423
+ }
424
+
425
+ if (isType (token, TOKEN_OPEN_CURLY))
426
+ {
427
+ readToken (token);
428
+ while (! isType (token, TOKEN_CLOSE_CURLY) )
429
+ {
430
+ if (isType (token, TOKEN_IDENTIFIER) && useLongName)
431
+ {
432
+ if (fullname->length > 0)
433
+ vStringCatS (fullname, " ");
434
+ vStringCatS (fullname, vStringValue (token->string));
435
+ }
436
+ readToken (token);
437
+ }
438
+ if (useLongName)
439
+ {
440
+ vStringTerminate (fullname);
441
+ vStringCopy (name->string, fullname);
442
+ makeTexTag (name, kind);
443
+ }
444
+ }
445
+
446
+ deleteToken (name);
447
+ vStringDelete (fullname);
448
+ return TRUE;
449
+ }
450
+
451
+ static void parseTexFile (tokenInfo *const token)
452
+ {
453
+ do
454
+ {
455
+ readToken (token);
456
+
457
+ if (isType (token, TOKEN_KEYWORD))
458
+ {
459
+ switch (token->keyword)
460
+ {
461
+ case KEYWORD_chapter:
462
+ parseTag (token, TEXTAG_CHAPTER);
463
+ break;
464
+ case KEYWORD_section:
465
+ parseTag (token, TEXTAG_SECTION);
466
+ break;
467
+ case KEYWORD_subsection:
468
+ parseTag (token, TEXTAG_SUBSUBSECTION);
469
+ break;
470
+ case KEYWORD_subsubsection:
471
+ parseTag (token, TEXTAG_SUBSUBSECTION);
472
+ break;
473
+ case KEYWORD_part:
474
+ parseTag (token, TEXTAG_PART);
475
+ break;
476
+ case KEYWORD_paragraph:
477
+ parseTag (token, TEXTAG_PARAGRAPH);
478
+ break;
479
+ case KEYWORD_subparagraph:
480
+ parseTag (token, TEXTAG_SUBPARAGRAPH);
481
+ break;
482
+ default:
483
+ break;
484
+ }
485
+ }
486
+ } while (TRUE);
487
+ }
488
+
489
+ static void initialize (const langType language)
490
+ {
491
+ Assert (sizeof (TexKinds) / sizeof (TexKinds [0]) == TEXTAG_COUNT);
492
+ Lang_js = language;
493
+ buildTexKeywordHash ();
494
+ }
495
+
496
+ static void findTexTags (void)
497
+ {
498
+ tokenInfo *const token = newToken ();
499
+ exception_t exception;
500
+
501
+ exception = (exception_t) (setjmp (Exception));
502
+ while (exception == ExceptionNone)
503
+ parseTexFile (token);
504
+
505
+ deleteToken (token);
506
+ }
507
+
508
+ /* Create parser definition stucture */
509
+ extern parserDefinition* TexParser (void)
510
+ {
511
+ static const char *const extensions [] = { "tex", NULL };
512
+ parserDefinition *const def = parserNew ("Tex");
513
+ def->extensions = extensions;
514
+ /*
515
+ * New definitions for parsing instead of regex
516
+ */
517
+ def->kinds = TexKinds;
518
+ def->kindCount = KIND_COUNT (TexKinds);
519
+ def->parser = findTexTags;
520
+ def->initialize = initialize;
521
+
522
+ return def;
523
+ }
524
+ /* vi:set tabstop=4 shiftwidth=4 noexpandtab: */