13ae02089SMasatake YAMATO /*
23ae02089SMasatake YAMATO * Copyright (c) 2008, David Fishburn
33ae02089SMasatake YAMATO * Copyright (c) 2012, Jan Larres
43ae02089SMasatake YAMATO *
53ae02089SMasatake YAMATO * This source code is released for free distribution under the terms of the
60ce38835Sviccuad * GNU General Public License version 2 or (at your option) any later version.
73ae02089SMasatake YAMATO *
83ae02089SMasatake YAMATO * This module contains functions for generating tags for TeX language files.
93ae02089SMasatake YAMATO *
103ae02089SMasatake YAMATO * Tex language reference:
113ae02089SMasatake YAMATO * http://en.wikibooks.org/wiki/TeX#The_Structure_of_TeX
123ae02089SMasatake YAMATO */
133ae02089SMasatake YAMATO
143ae02089SMasatake YAMATO /*
153ae02089SMasatake YAMATO * INCLUDE FILES
163ae02089SMasatake YAMATO */
173ae02089SMasatake YAMATO #include "general.h" /* must always come first */
183ae02089SMasatake YAMATO #include <ctype.h> /* to define isalpha () */
193ae02089SMasatake YAMATO #ifdef DEBUG
203ae02089SMasatake YAMATO #include <stdio.h>
213ae02089SMasatake YAMATO #endif
22015ab54cSMasatake YAMATO #include <string.h>
233ae02089SMasatake YAMATO
243ae02089SMasatake YAMATO #include "debug.h"
253ae02089SMasatake YAMATO #include "entry.h"
263ae02089SMasatake YAMATO #include "keyword.h"
273ae02089SMasatake YAMATO #include "parse.h"
283ae02089SMasatake YAMATO #include "read.h"
293ae02089SMasatake YAMATO #include "routines.h"
303ae02089SMasatake YAMATO #include "vstring.h"
313ae02089SMasatake YAMATO
323b13813cSMasatake YAMATO #include "tex.h"
333b13813cSMasatake YAMATO
343ae02089SMasatake YAMATO /*
353ae02089SMasatake YAMATO * MACROS
363ae02089SMasatake YAMATO */
37ce990805SThomas Braun #define isType(token,t) (bool) ((token)->type == (t))
38ce990805SThomas Braun #define isKeyword(token,k) (bool) ((token)->keyword == (k))
392b28d0e0SJiří Techet #define isIdentChar(c) \
40b2e27320SColomban Wendling (isalpha (c) || isdigit (c) || (c) >= 0x80 || (c) == '$' || \
412b28d0e0SJiří Techet (c) == '_' || (c) == '#' || (c) == '-' || (c) == '.' || (c) == ':')
423ae02089SMasatake YAMATO
433ae02089SMasatake YAMATO /*
443ae02089SMasatake YAMATO * DATA DECLARATIONS
453ae02089SMasatake YAMATO */
463ae02089SMasatake YAMATO
473ae02089SMasatake YAMATO /*
483ae02089SMasatake YAMATO * Used to specify type of keyword.
493ae02089SMasatake YAMATO */
504faa2076SColomban Wendling enum eKeywordId {
513ae02089SMasatake YAMATO KEYWORD_part,
523ae02089SMasatake YAMATO KEYWORD_chapter,
533ae02089SMasatake YAMATO KEYWORD_section,
543ae02089SMasatake YAMATO KEYWORD_subsection,
553ae02089SMasatake YAMATO KEYWORD_subsubsection,
563ae02089SMasatake YAMATO KEYWORD_paragraph,
573ae02089SMasatake YAMATO KEYWORD_subparagraph,
583ae02089SMasatake YAMATO KEYWORD_label,
591cfa869bSMasatake YAMATO KEYWORD_include,
60f7be3a35SMasatake YAMATO KEYWORD_input,
611cfa869bSMasatake YAMATO KEYWORD_begin,
621cfa869bSMasatake YAMATO KEYWORD_end,
63b3ac7a43SMasatake YAMATO KEYWORD_bibitem,
6447b7253cSMasatake YAMATO KEYWORD_bibliography,
653e2c7ce9SMasatake YAMATO KEYWORD_newcommand,
66c359e13dSJiří Techet KEYWORD_renewcommand,
67c359e13dSJiří Techet KEYWORD_providecommand,
6804d5c984SJiří Techet KEYWORD_def,
69952983dbSJiří Techet KEYWORD_declaremathoperator,
70bcf90eddSJiří Techet KEYWORD_newenvironment,
71bcf90eddSJiří Techet KEYWORD_renewenvironment,
72aa63a3eaSJiří Techet KEYWORD_newtheorem,
733859e610SMasatake YAMATO KEYWORD_newcounter,
744faa2076SColomban Wendling };
754faa2076SColomban Wendling typedef int keywordId; /* to allow KEYWORD_NONE */
763ae02089SMasatake YAMATO
7774756360SColomban Wendling enum eTokenType {
7874756360SColomban Wendling /* 0..255 are the byte's value. Some are named for convenience */
7974756360SColomban Wendling TOKEN_OPEN_PAREN = '(',
8074756360SColomban Wendling TOKEN_CLOSE_PAREN = ')',
8174756360SColomban Wendling TOKEN_OPEN_CURLY = '{',
8274756360SColomban Wendling TOKEN_CLOSE_CURLY = '}',
8374756360SColomban Wendling TOKEN_OPEN_SQUARE = '[',
8474756360SColomban Wendling TOKEN_CLOSE_SQUARE = ']',
8574756360SColomban Wendling TOKEN_STAR = '*',
8674756360SColomban Wendling /* above is special types */
8774756360SColomban Wendling TOKEN_UNDEFINED = 256,
883ae02089SMasatake YAMATO TOKEN_KEYWORD,
893ae02089SMasatake YAMATO TOKEN_IDENTIFIER,
903ae02089SMasatake YAMATO TOKEN_STRING,
9174756360SColomban Wendling };
9274756360SColomban Wendling typedef int tokenType;
933ae02089SMasatake YAMATO
943ae02089SMasatake YAMATO typedef struct sTokenInfo {
953ae02089SMasatake YAMATO tokenType type;
963ae02089SMasatake YAMATO keywordId keyword;
973ae02089SMasatake YAMATO vString * string;
983ae02089SMasatake YAMATO vString * scope;
993ae02089SMasatake YAMATO unsigned long lineNumber;
100509a47dbSJiří Techet MIOPos filePosition;
1013ae02089SMasatake YAMATO } tokenInfo;
1023ae02089SMasatake YAMATO
1033ae02089SMasatake YAMATO /*
1043ae02089SMasatake YAMATO * DATA DEFINITIONS
1053ae02089SMasatake YAMATO */
1063ae02089SMasatake YAMATO
107970f6116SJiří Techet static langType Lang_tex;
1083ae02089SMasatake YAMATO
1093ae02089SMasatake YAMATO static vString *lastPart;
1103ae02089SMasatake YAMATO static vString *lastChapter;
1113ae02089SMasatake YAMATO static vString *lastSection;
1123ae02089SMasatake YAMATO static vString *lastSubS;
1133ae02089SMasatake YAMATO static vString *lastSubSubS;
1143ae02089SMasatake YAMATO
1153ae02089SMasatake YAMATO typedef enum {
1163ae02089SMasatake YAMATO TEXTAG_PART,
1173ae02089SMasatake YAMATO TEXTAG_CHAPTER,
1183ae02089SMasatake YAMATO TEXTAG_SECTION,
1193ae02089SMasatake YAMATO TEXTAG_SUBSECTION,
1203ae02089SMasatake YAMATO TEXTAG_SUBSUBSECTION,
1213ae02089SMasatake YAMATO TEXTAG_PARAGRAPH,
1223ae02089SMasatake YAMATO TEXTAG_SUBPARAGRAPH,
1233ae02089SMasatake YAMATO TEXTAG_LABEL,
124f7be3a35SMasatake YAMATO TEXTAG_XINPUT,
125b3ac7a43SMasatake YAMATO TEXTAG_BIBITEM,
1263e2c7ce9SMasatake YAMATO TEXTAG_COMMAND,
127952983dbSJiří Techet TEXTAG_OPERATOR,
128bcf90eddSJiří Techet TEXTAG_ENVIRONMENT,
129aa63a3eaSJiří Techet TEXTAG_THEOREM,
1303859e610SMasatake YAMATO TEXTAG_COUNTER,
1313ae02089SMasatake YAMATO TEXTAG_COUNT
1323ae02089SMasatake YAMATO } texKind;
1333ae02089SMasatake YAMATO
134f7be3a35SMasatake YAMATO typedef enum {
135f7be3a35SMasatake YAMATO TEX_XINPUT_INCLUDED,
136f7be3a35SMasatake YAMATO TEX_XINPUT_INPUT,
13747b7253cSMasatake YAMATO TEX_XINPUT_BIBLIOGRAPHY,
138f7be3a35SMasatake YAMATO } texInputRole;
139f7be3a35SMasatake YAMATO
1406e18762eSJiří Techet typedef enum {
1416e18762eSJiří Techet TEX_ENVIRONMENT_USED,
1426e18762eSJiří Techet } texEnvironmentRole;
1436e18762eSJiří Techet
144f7be3a35SMasatake YAMATO static roleDefinition TexInputRoles [] = {
145f7be3a35SMasatake YAMATO { true, "included",
146f7be3a35SMasatake YAMATO "external input file specified with \\include" },
147f7be3a35SMasatake YAMATO { true, "input",
148f7be3a35SMasatake YAMATO "external input file specified with \\input" },
14947b7253cSMasatake YAMATO { true, "bibliography",
15047b7253cSMasatake YAMATO "bibliography (.bib) file" },
151f7be3a35SMasatake YAMATO };
152f7be3a35SMasatake YAMATO
1536e18762eSJiří Techet static roleDefinition TexEnvironmentRoles [] = {
1546e18762eSJiří Techet { false, "used", "environment usage introduced by \\begin{MyEnv}" },
1556e18762eSJiří Techet };
1566e18762eSJiří Techet
157e112e8abSMasatake YAMATO static kindDefinition TexKinds [] = {
158ce990805SThomas Braun { true, 'p', "part", "parts" },
159ce990805SThomas Braun { true, 'c', "chapter", "chapters" },
160ce990805SThomas Braun { true, 's', "section", "sections" },
161ce990805SThomas Braun { true, 'u', "subsection", "subsections" },
162ce990805SThomas Braun { true, 'b', "subsubsection", "subsubsections" },
163ce990805SThomas Braun { true, 'P', "paragraph", "paragraphs" },
164ce990805SThomas Braun { true, 'G', "subparagraph", "subparagraphs" },
165ce990805SThomas Braun { true, 'l', "label", "labels" },
166f7be3a35SMasatake YAMATO { true, 'i', "xinput", "external input files",
167f7be3a35SMasatake YAMATO .referenceOnly = true, ATTACH_ROLES(TexInputRoles) },
168b3ac7a43SMasatake YAMATO { true, 'B', "bibitem", "bibliography items" },
1693e2c7ce9SMasatake YAMATO { true, 'C', "command", "command created with \\newcommand" },
170952983dbSJiří Techet { true, 'o', "operator", "math operator created with \\DeclareMathOperator" },
1716e18762eSJiří Techet { true, 'e', "environment", "environment created with \\newenvironment",
1726e18762eSJiří Techet .referenceOnly = false, ATTACH_ROLES(TexEnvironmentRoles) },
173aa63a3eaSJiří Techet { true, 't', "theorem", "theorem created with \\newtheorem" },
1743859e610SMasatake YAMATO { true, 'N', "counter", "counter created with \\newcounter" },
1753ae02089SMasatake YAMATO };
1763ae02089SMasatake YAMATO
17782c11d8cSRich Siegel static const keywordTable TexKeywordTable [] = {
1783ae02089SMasatake YAMATO /* keyword keyword ID */
1793ae02089SMasatake YAMATO { "part", KEYWORD_part },
1803ae02089SMasatake YAMATO { "chapter", KEYWORD_chapter },
1813ae02089SMasatake YAMATO { "section", KEYWORD_section },
1823ae02089SMasatake YAMATO { "subsection", KEYWORD_subsection },
1833ae02089SMasatake YAMATO { "subsubsection", KEYWORD_subsubsection },
1843ae02089SMasatake YAMATO { "paragraph", KEYWORD_paragraph },
1853ae02089SMasatake YAMATO { "subparagraph", KEYWORD_subparagraph },
1863ae02089SMasatake YAMATO { "label", KEYWORD_label },
1871cfa869bSMasatake YAMATO { "include", KEYWORD_include },
188f7be3a35SMasatake YAMATO { "input", KEYWORD_input },
1891cfa869bSMasatake YAMATO { "begin", KEYWORD_begin },
1901cfa869bSMasatake YAMATO { "end", KEYWORD_end },
191b3ac7a43SMasatake YAMATO { "bibitem", KEYWORD_bibitem },
19247b7253cSMasatake YAMATO { "bibliography", KEYWORD_bibliography },
1933e2c7ce9SMasatake YAMATO { "newcommand", KEYWORD_newcommand },
194c359e13dSJiří Techet { "renewcommand", KEYWORD_renewcommand },
195c359e13dSJiří Techet { "providecommand", KEYWORD_providecommand },
19604d5c984SJiří Techet { "def", KEYWORD_def },
197952983dbSJiří Techet { "DeclareMathOperator", KEYWORD_declaremathoperator },
198bcf90eddSJiří Techet { "newenvironment", KEYWORD_newenvironment },
199bcf90eddSJiří Techet { "renewenvironment", KEYWORD_renewenvironment},
200aa63a3eaSJiří Techet { "newtheorem", KEYWORD_newtheorem },
2013859e610SMasatake YAMATO { "newcounter", KEYWORD_newcounter },
2023ae02089SMasatake YAMATO };
2033ae02089SMasatake YAMATO
2043ae02089SMasatake YAMATO /*
2053b13813cSMasatake YAMATO * FUNCTION DECLARATIONS
2063b13813cSMasatake YAMATO */
2073b13813cSMasatake YAMATO
2083b13813cSMasatake YAMATO static bool notifyReadingIdentifier (tokenInfo *id_token, bool *tokenUnprocessed);
2091cfa869bSMasatake YAMATO static bool notifyReadingBeginEnvironment (tokenInfo *token, vString *envName, bool *tokenUnprocessed);
2101cfa869bSMasatake YAMATO static bool notifyReadingEndEnvironment (vString *envName);
2113b13813cSMasatake YAMATO
2123b13813cSMasatake YAMATO
2133b13813cSMasatake YAMATO /*
2143ae02089SMasatake YAMATO * FUNCTION DEFINITIONS
2153ae02089SMasatake YAMATO */
2163ae02089SMasatake YAMATO
newToken(void)2173ae02089SMasatake YAMATO static tokenInfo *newToken (void)
2183ae02089SMasatake YAMATO {
2193ae02089SMasatake YAMATO tokenInfo *const token = xMalloc (1, tokenInfo);
2203ae02089SMasatake YAMATO
2213ae02089SMasatake YAMATO token->type = TOKEN_UNDEFINED;
2223ae02089SMasatake YAMATO token->keyword = KEYWORD_NONE;
2233ae02089SMasatake YAMATO token->string = vStringNew ();
2243ae02089SMasatake YAMATO token->scope = vStringNew ();
225a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
2263ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
2273ae02089SMasatake YAMATO
2283ae02089SMasatake YAMATO return token;
2293ae02089SMasatake YAMATO }
2303ae02089SMasatake YAMATO
deleteToken(tokenInfo * const token)2313ae02089SMasatake YAMATO static void deleteToken (tokenInfo *const token)
2323ae02089SMasatake YAMATO {
2333ae02089SMasatake YAMATO vStringDelete (token->string);
2343ae02089SMasatake YAMATO vStringDelete (token->scope);
2353ae02089SMasatake YAMATO eFree (token);
2363ae02089SMasatake YAMATO }
2373ae02089SMasatake YAMATO
getScopeInfo(texKind kind,vString * const parentName)238f92e6bf2SMasatake YAMATO static int getScopeInfo(texKind kind, vString *const parentName)
2393ae02089SMasatake YAMATO {
240f92e6bf2SMasatake YAMATO int parentKind = KIND_GHOST_INDEX;
2413ae02089SMasatake YAMATO int i;
2423ae02089SMasatake YAMATO
2433ae02089SMasatake YAMATO /*
2443ae02089SMasatake YAMATO * Put labels separately instead of under their scope.
2453ae02089SMasatake YAMATO * Is this The Right Thing To Do?
2463ae02089SMasatake YAMATO */
2473ae02089SMasatake YAMATO if (kind >= TEXTAG_LABEL) {
248f92e6bf2SMasatake YAMATO goto out;
2493ae02089SMasatake YAMATO }
2503ae02089SMasatake YAMATO
2513ae02089SMasatake YAMATO /*
2523ae02089SMasatake YAMATO * This abuses the enum internals somewhat, but it should be ok in this
2533ae02089SMasatake YAMATO * case.
2543ae02089SMasatake YAMATO */
255f92e6bf2SMasatake YAMATO /* TODO: This loop and conditions can be squashed. */
2563ae02089SMasatake YAMATO for (i = kind - 1; i >= TEXTAG_PART; --i) {
2573ae02089SMasatake YAMATO if (i == TEXTAG_SUBSECTION && vStringLength(lastSubS) > 0) {
258f92e6bf2SMasatake YAMATO parentKind = i;
2593ae02089SMasatake YAMATO break;
2603ae02089SMasatake YAMATO } else if (i == TEXTAG_SECTION && vStringLength(lastSection) > 0) {
261f92e6bf2SMasatake YAMATO parentKind = i;
2623ae02089SMasatake YAMATO break;
2633ae02089SMasatake YAMATO } else if (i == TEXTAG_CHAPTER && vStringLength(lastChapter) > 0) {
264f92e6bf2SMasatake YAMATO parentKind = i;
2653ae02089SMasatake YAMATO break;
2663ae02089SMasatake YAMATO } else if (i == TEXTAG_PART && vStringLength(lastPart) > 0) {
267f92e6bf2SMasatake YAMATO parentKind = i;
2683ae02089SMasatake YAMATO break;
2693ae02089SMasatake YAMATO }
2703ae02089SMasatake YAMATO }
2713ae02089SMasatake YAMATO
2723ae02089SMasatake YAMATO /*
2733ae02089SMasatake YAMATO * Is '""' the best way to separate scopes? It has to be something that
2743ae02089SMasatake YAMATO * should ideally never occur in normal LaTeX text.
2753ae02089SMasatake YAMATO */
2763ae02089SMasatake YAMATO for (i = TEXTAG_PART; i < (int)kind; ++i) {
2773ae02089SMasatake YAMATO if (i == TEXTAG_PART && vStringLength(lastPart) > 0) {
2783ae02089SMasatake YAMATO vStringCat(parentName, lastPart);
2793ae02089SMasatake YAMATO } else if (i == TEXTAG_CHAPTER && vStringLength(lastChapter) > 0) {
2803ae02089SMasatake YAMATO if (vStringLength(parentName) > 0) {
2813ae02089SMasatake YAMATO vStringCatS(parentName, "\"\"");
2823ae02089SMasatake YAMATO }
2833ae02089SMasatake YAMATO vStringCat(parentName, lastChapter);
2843ae02089SMasatake YAMATO } else if (i == TEXTAG_SECTION && vStringLength(lastSection) > 0) {
2853ae02089SMasatake YAMATO if (vStringLength(parentName) > 0) {
2863ae02089SMasatake YAMATO vStringCatS(parentName, "\"\"");
2873ae02089SMasatake YAMATO }
2883ae02089SMasatake YAMATO vStringCat(parentName, lastSection);
2893ae02089SMasatake YAMATO } else if (i == TEXTAG_SUBSECTION && vStringLength(lastSubS) > 0) {
2903ae02089SMasatake YAMATO if (vStringLength(parentName) > 0) {
2913ae02089SMasatake YAMATO vStringCatS(parentName, "\"\"");
2923ae02089SMasatake YAMATO }
2933ae02089SMasatake YAMATO vStringCat(parentName, lastSubS);
2943ae02089SMasatake YAMATO }
2953ae02089SMasatake YAMATO }
296f92e6bf2SMasatake YAMATO out:
297f92e6bf2SMasatake YAMATO return parentKind;
2983ae02089SMasatake YAMATO }
2993ae02089SMasatake YAMATO
3003ae02089SMasatake YAMATO /*
3013ae02089SMasatake YAMATO * Tag generation functions
3023ae02089SMasatake YAMATO */
303f67e271cSMasatake YAMATO
304f67e271cSMasatake YAMATO struct symbolData {
305f67e271cSMasatake YAMATO langType lang;
306f67e271cSMasatake YAMATO int kind;
307f67e271cSMasatake YAMATO int *corkQueue;
308f67e271cSMasatake YAMATO };
309f67e271cSMasatake YAMATO
findTheName(int corkIndex,tagEntryInfo * entry,void * data)3103afb5475SMasatake YAMATO static bool findTheName (int corkIndex, tagEntryInfo *entry, void *data)
311f67e271cSMasatake YAMATO {
312f67e271cSMasatake YAMATO struct symbolData *symbolData = data;
313f67e271cSMasatake YAMATO
314f67e271cSMasatake YAMATO if (entry->langType == symbolData->lang && entry->kindIndex == symbolData->kind)
315f67e271cSMasatake YAMATO {
316f67e271cSMasatake YAMATO /* TODO: The case operation should be removed */
3173afb5475SMasatake YAMATO *symbolData->corkQueue = corkIndex;
318f67e271cSMasatake YAMATO return false;
319f67e271cSMasatake YAMATO }
320f67e271cSMasatake YAMATO return true;
321f67e271cSMasatake YAMATO }
322f67e271cSMasatake YAMATO
makeTexTag(tokenInfo * const token,int kind,int roleIndex,bool unique,int scopeIndex)323ed565083SMasatake YAMATO static int makeTexTag (tokenInfo *const token, int kind,
324f67e271cSMasatake YAMATO int roleIndex, bool unique, int scopeIndex)
3253ae02089SMasatake YAMATO {
326c28568d6SMasatake YAMATO int corkQueue = CORK_NIL;
3273ae02089SMasatake YAMATO const char *const name = vStringValue (token->string);
328f67e271cSMasatake YAMATO
329f67e271cSMasatake YAMATO if (unique)
330f67e271cSMasatake YAMATO {
331f67e271cSMasatake YAMATO struct symbolData data = {
332f67e271cSMasatake YAMATO .lang = getInputLanguage(),
333f67e271cSMasatake YAMATO .kind = kind,
334f67e271cSMasatake YAMATO .corkQueue = &corkQueue,
335f67e271cSMasatake YAMATO };
336f67e271cSMasatake YAMATO /* TODO: The case operation should be removed */
3373afb5475SMasatake YAMATO if (foreachEntriesInScope (scopeIndex, name, findTheName, (void *)&data) == false)
338f67e271cSMasatake YAMATO return *data.corkQueue;
339f67e271cSMasatake YAMATO }
340f67e271cSMasatake YAMATO
3413ae02089SMasatake YAMATO tagEntryInfo e;
34216a2541cSMasatake YAMATO initTagEntry (&e, name, kind);
3433ae02089SMasatake YAMATO
3443ae02089SMasatake YAMATO e.lineNumber = token->lineNumber;
3453ae02089SMasatake YAMATO e.filePosition = token->filePosition;
3463ae02089SMasatake YAMATO
347ed565083SMasatake YAMATO vString *parentName = NULL;
348ed565083SMasatake YAMATO
349f67e271cSMasatake YAMATO
350f67e271cSMasatake YAMATO if (unique)
351f67e271cSMasatake YAMATO e.extensionFields.scopeIndex = scopeIndex;
352f67e271cSMasatake YAMATO
353ed565083SMasatake YAMATO /* Filling e.extensionFields.scopeKindIndex and
354f67e271cSMasatake YAMATO * e.extensionFields.scopeName can be filled from "kind" parameter
355f67e271cSMasatake YAMATO * of this function only when Tex parser calls this function. The
356f67e271cSMasatake YAMATO * fields cannot be filled with a kind defined in a subparser.
357f67e271cSMasatake YAMATO * Subparsers may fill the scope after running strategy. So in the
358f67e271cSMasatake YAMATO * context of a subparser, filling the scope fields here is not
359f67e271cSMasatake YAMATO * needed.
360ed565083SMasatake YAMATO */
361ed565083SMasatake YAMATO if (Lang_tex == getInputLanguage ())
362ed565083SMasatake YAMATO {
363ed565083SMasatake YAMATO int parentKind = KIND_GHOST_INDEX;
364ed565083SMasatake YAMATO parentName = vStringNew();
365f92e6bf2SMasatake YAMATO parentKind = getScopeInfo(kind, parentName);
366f92e6bf2SMasatake YAMATO if (parentKind != KIND_GHOST_INDEX) {
367f92e6bf2SMasatake YAMATO e.extensionFields.scopeKindIndex = parentKind;
368015ab54cSMasatake YAMATO e.extensionFields.scopeName = vStringValue(parentName);
3693ae02089SMasatake YAMATO }
370ed565083SMasatake YAMATO }
3713ae02089SMasatake YAMATO
372993d4289SMasatake YAMATO assignRole (&e, roleIndex);
373993d4289SMasatake YAMATO
374c28568d6SMasatake YAMATO corkQueue = makeTagEntry (&e);
375ed565083SMasatake YAMATO vStringDelete (parentName); /* NULL is o.k. */
376f67e271cSMasatake YAMATO
3773671ad72SMasatake YAMATO if (unique && corkQueue != CORK_NIL)
378f67e271cSMasatake YAMATO registerEntry (corkQueue);
379f67e271cSMasatake YAMATO
380c28568d6SMasatake YAMATO return corkQueue;
3813ae02089SMasatake YAMATO }
3823ae02089SMasatake YAMATO
3833ae02089SMasatake YAMATO /*
3843ae02089SMasatake YAMATO * Parsing functions
3853ae02089SMasatake YAMATO */
3863ae02089SMasatake YAMATO
3873ae02089SMasatake YAMATO /*
3883ae02089SMasatake YAMATO * Read a C identifier beginning with "firstChar" and places it into
3893ae02089SMasatake YAMATO * "name".
3903ae02089SMasatake YAMATO */
parseIdentifier(vString * const string,const int firstChar)3913ae02089SMasatake YAMATO static void parseIdentifier (vString *const string, const int firstChar)
3923ae02089SMasatake YAMATO {
3933ae02089SMasatake YAMATO int c = firstChar;
3943ae02089SMasatake YAMATO Assert (isIdentChar (c));
3953ae02089SMasatake YAMATO do
3963ae02089SMasatake YAMATO {
3973ae02089SMasatake YAMATO vStringPut (string, c);
398018bce0bSMasatake YAMATO c = getcFromInputFile ();
399b2e27320SColomban Wendling } while (c != EOF && isIdentChar (c));
4003ae02089SMasatake YAMATO
40174756360SColomban Wendling if (c != EOF)
40261f14fa5SMasatake YAMATO ungetcToInputFile (c); /* unget non-identifier character */
4033ae02089SMasatake YAMATO }
4043ae02089SMasatake YAMATO
readTokenFull(tokenInfo * const token,const bool includeWhitespaces)40574756360SColomban Wendling static bool readTokenFull (tokenInfo *const token, const bool includeWhitespaces)
4063ae02089SMasatake YAMATO {
4073ae02089SMasatake YAMATO int c;
40874756360SColomban Wendling int whitespaces = -1;
4093ae02089SMasatake YAMATO
4103ae02089SMasatake YAMATO token->type = TOKEN_UNDEFINED;
4113ae02089SMasatake YAMATO token->keyword = KEYWORD_NONE;
4123ae02089SMasatake YAMATO vStringClear (token->string);
4133ae02089SMasatake YAMATO
4143ae02089SMasatake YAMATO getNextChar:
41574756360SColomban Wendling
4163ae02089SMasatake YAMATO do
4173ae02089SMasatake YAMATO {
418018bce0bSMasatake YAMATO c = getcFromInputFile ();
41974756360SColomban Wendling whitespaces++;
4203ae02089SMasatake YAMATO }
4213ae02089SMasatake YAMATO while (c == '\t' || c == ' ' || c == '\n');
4223ae02089SMasatake YAMATO
423a0dc727aSColomban Wendling token->lineNumber = getInputLineNumber ();
424a0dc727aSColomban Wendling token->filePosition = getInputFilePosition ();
425a0dc727aSColomban Wendling
42674756360SColomban Wendling if (includeWhitespaces && whitespaces > 0 && c != '%' && c != EOF)
42774756360SColomban Wendling {
42874756360SColomban Wendling ungetcToInputFile (c);
42974756360SColomban Wendling c = ' ';
43074756360SColomban Wendling }
43174756360SColomban Wendling
43274756360SColomban Wendling token->type = (unsigned char) c;
4333ae02089SMasatake YAMATO switch (c)
4343ae02089SMasatake YAMATO {
435969a87f4SMasatake YAMATO case EOF: return false;
4363ae02089SMasatake YAMATO
4373ae02089SMasatake YAMATO case '\\':
4383ae02089SMasatake YAMATO /*
4393ae02089SMasatake YAMATO * All Tex tags start with a backslash.
4403ae02089SMasatake YAMATO * Check if the next character is an alpha character
4413ae02089SMasatake YAMATO * else it is not a potential tex tag.
4423ae02089SMasatake YAMATO */
443018bce0bSMasatake YAMATO c = getcFromInputFile ();
4443ae02089SMasatake YAMATO if (! isalpha (c))
44561f14fa5SMasatake YAMATO ungetcToInputFile (c);
4463ae02089SMasatake YAMATO else
4473ae02089SMasatake YAMATO {
44874756360SColomban Wendling vStringPut (token->string, '\\');
4493ae02089SMasatake YAMATO parseIdentifier (token->string, c);
45074756360SColomban Wendling token->keyword = lookupKeyword (vStringValue (token->string) + 1, Lang_tex);
4513ae02089SMasatake YAMATO if (isKeyword (token, KEYWORD_NONE))
4523ae02089SMasatake YAMATO token->type = TOKEN_IDENTIFIER;
4533ae02089SMasatake YAMATO else
4543ae02089SMasatake YAMATO token->type = TOKEN_KEYWORD;
4553ae02089SMasatake YAMATO }
4563ae02089SMasatake YAMATO break;
4573ae02089SMasatake YAMATO
4583ae02089SMasatake YAMATO case '%':
4594fffc5afSMasatake YAMATO skipToCharacterInInputFile ('\n'); /* % are single line comments */
4603ae02089SMasatake YAMATO goto getNextChar;
4613ae02089SMasatake YAMATO break;
4623ae02089SMasatake YAMATO
4633ae02089SMasatake YAMATO default:
46474756360SColomban Wendling if (isIdentChar (c))
4653ae02089SMasatake YAMATO {
4663ae02089SMasatake YAMATO parseIdentifier (token->string, c);
4673ae02089SMasatake YAMATO token->type = TOKEN_IDENTIFIER;
4683ae02089SMasatake YAMATO }
4693ae02089SMasatake YAMATO break;
4703ae02089SMasatake YAMATO }
471969a87f4SMasatake YAMATO return true;
4723ae02089SMasatake YAMATO }
4733ae02089SMasatake YAMATO
readToken(tokenInfo * const token)47474756360SColomban Wendling static bool readToken (tokenInfo *const token)
47574756360SColomban Wendling {
47674756360SColomban Wendling return readTokenFull (token, false);
47774756360SColomban Wendling }
47874756360SColomban Wendling
copyToken(tokenInfo * const dest,tokenInfo * const src)4793ae02089SMasatake YAMATO static void copyToken (tokenInfo *const dest, tokenInfo *const src)
4803ae02089SMasatake YAMATO {
4813ae02089SMasatake YAMATO dest->lineNumber = src->lineNumber;
4823ae02089SMasatake YAMATO dest->filePosition = src->filePosition;
4833ae02089SMasatake YAMATO dest->type = src->type;
4843ae02089SMasatake YAMATO dest->keyword = src->keyword;
4853ae02089SMasatake YAMATO vStringCopy (dest->string, src->string);
4863ae02089SMasatake YAMATO vStringCopy (dest->scope, src->scope);
4873ae02089SMasatake YAMATO }
4883ae02089SMasatake YAMATO
updateScopeInfo(texKind kind,vString * fullname)4893566b8ecSMasatake YAMATO static void updateScopeInfo (texKind kind, vString *fullname)
4903566b8ecSMasatake YAMATO {
4913566b8ecSMasatake YAMATO switch (kind)
4923566b8ecSMasatake YAMATO {
4933566b8ecSMasatake YAMATO case TEXTAG_PART:
4943566b8ecSMasatake YAMATO vStringCopy(lastPart, fullname);
4953566b8ecSMasatake YAMATO vStringClear(lastChapter);
4963566b8ecSMasatake YAMATO vStringClear(lastSection);
4973566b8ecSMasatake YAMATO vStringClear(lastSubS);
4983566b8ecSMasatake YAMATO vStringClear(lastSubSubS);
4993566b8ecSMasatake YAMATO break;
5003566b8ecSMasatake YAMATO case TEXTAG_CHAPTER:
5013566b8ecSMasatake YAMATO vStringCopy(lastChapter, fullname);
5023566b8ecSMasatake YAMATO vStringClear(lastSection);
5033566b8ecSMasatake YAMATO vStringClear(lastSubS);
5043566b8ecSMasatake YAMATO vStringClear(lastSubSubS);
5053566b8ecSMasatake YAMATO break;
5063566b8ecSMasatake YAMATO case TEXTAG_SECTION:
5073566b8ecSMasatake YAMATO vStringCopy(lastSection, fullname);
5083566b8ecSMasatake YAMATO vStringClear(lastSubS);
5093566b8ecSMasatake YAMATO vStringClear(lastSubSubS);
5103566b8ecSMasatake YAMATO break;
5113566b8ecSMasatake YAMATO case TEXTAG_SUBSECTION:
5123566b8ecSMasatake YAMATO vStringCopy(lastSubS, fullname);
5133566b8ecSMasatake YAMATO vStringClear(lastSubSubS);
5143566b8ecSMasatake YAMATO break;
5153566b8ecSMasatake YAMATO case TEXTAG_SUBSUBSECTION:
5163566b8ecSMasatake YAMATO vStringCopy(lastSubSubS, fullname);
5173566b8ecSMasatake YAMATO break;
5183566b8ecSMasatake YAMATO default:
5193566b8ecSMasatake YAMATO break;
5203566b8ecSMasatake YAMATO }
5213566b8ecSMasatake YAMATO }
5223566b8ecSMasatake YAMATO
5233ae02089SMasatake YAMATO /*
5243ae02089SMasatake YAMATO * Scanning functions
5253ae02089SMasatake YAMATO */
5263ae02089SMasatake YAMATO
527d0937875SMasatake YAMATO /* STRATEGY array represents the sequence of * expected tokens. If an
528d0937875SMasatake YAMATO * input token matches the current * expectation (the current strategy),
529d0937875SMasatake YAMATO * parseWithStrategy() runs * the actions attached to the strategy.
530d0937875SMasatake YAMATO *
531d0937875SMasatake YAMATO * The actions are making a tag with the kind specified with kindIndex
532d0937875SMasatake YAMATO * field of the current strategy and/or storing a name to NAME field
533d0937875SMasatake YAMATO * of the current strategy.
534d0937875SMasatake YAMATO *
535d0937875SMasatake YAMATO * If the input token doesn't much the current strategy, above actions
536d0937875SMasatake YAMATO * are not run. If TEX_NAME_FLAG_OPTIONAL is specified in FLAGS field
537d0937875SMasatake YAMATO * of the current specified, parseWithStrategy() tries the next
538d0937875SMasatake YAMATO * strategy of STRATEGY array without reading a new token. If
539d0937875SMasatake YAMATO * TEX_NAME_FLAG_OPTIONAL is not in FLAGS field, parseWithStrategy()
540d0937875SMasatake YAMATO * returns the control to its caller immediately.
541d0937875SMasatake YAMATO *
542d0937875SMasatake YAMATO * TOKENUNPROCESSED is used for both input and output. As input,
543d0937875SMasatake YAMATO * TOKENUNPROCESSED tells whether parseWithStrategy() should read a
544d0937875SMasatake YAMATO * new token before matching the STRATEGY array or not. If
545d0937875SMasatake YAMATO * TOKENUNPROCESSED is true, parseWithStrategy function reads a new
546d0937875SMasatake YAMATO * token before matching. As output, TOKENUNPROCESSED tells the
547d0937875SMasatake YAMATO * caller of parseWithStrategy() that a new token is already stored to
548d0937875SMasatake YAMATO * TOKEN but parseWithStrategy() has not processed yet.
549d0937875SMasatake YAMATO */
parseWithStrategy(tokenInfo * token,struct TexParseStrategy * strategy,bool * tokenUnprocessed)550d0937875SMasatake YAMATO static bool parseWithStrategy (tokenInfo *token,
551d0937875SMasatake YAMATO struct TexParseStrategy *strategy,
552d0937875SMasatake YAMATO bool *tokenUnprocessed)
5533ae02089SMasatake YAMATO {
554d0937875SMasatake YAMATO bool next_token = !*tokenUnprocessed;
555d0937875SMasatake YAMATO tokenInfo * name = NULL;
556969a87f4SMasatake YAMATO bool eof = false;
557d0937875SMasatake YAMATO bool exclusive = false;
5583ae02089SMasatake YAMATO
559d0937875SMasatake YAMATO for (struct TexParseStrategy *s = strategy; s->type != 0; ++s)
560d0937875SMasatake YAMATO s->corkIndex = CORK_NIL;
561d0937875SMasatake YAMATO
562d0937875SMasatake YAMATO for (struct TexParseStrategy *s = strategy; !eof && s->type != 0; ++s)
563d0937875SMasatake YAMATO {
564d0937875SMasatake YAMATO if (s->kindIndex != KIND_GHOST_INDEX || s->name)
565d0937875SMasatake YAMATO {
566d0937875SMasatake YAMATO name = newToken ();
567d0937875SMasatake YAMATO break;
568d0937875SMasatake YAMATO }
569d0937875SMasatake YAMATO }
570d0937875SMasatake YAMATO
571d0937875SMasatake YAMATO for (struct TexParseStrategy *s = strategy; !eof && s->type != 0; ++s)
572d0937875SMasatake YAMATO {
573d0937875SMasatake YAMATO bool capture_name = s->kindIndex != KIND_GHOST_INDEX || s->name;
574d0937875SMasatake YAMATO
575d0937875SMasatake YAMATO if (next_token)
576d0937875SMasatake YAMATO {
577d0937875SMasatake YAMATO if (!readToken (token))
578d0937875SMasatake YAMATO {
579d0937875SMasatake YAMATO eof = true;
580d0937875SMasatake YAMATO break;
581d0937875SMasatake YAMATO }
582d0937875SMasatake YAMATO }
583d0937875SMasatake YAMATO
584d0937875SMasatake YAMATO if ((s->type == '<' && isType (token, '<'))
585d0937875SMasatake YAMATO || (s->type == '[' && isType (token, '[')))
586d0937875SMasatake YAMATO {
587d0937875SMasatake YAMATO tokenType terminator = (s->type == '<') ? '>' : ']';
588d0937875SMasatake YAMATO
589d0937875SMasatake YAMATO next_token = true;
590d0937875SMasatake YAMATO
591d0937875SMasatake YAMATO
592d0937875SMasatake YAMATO if (!readToken (token))
593d0937875SMasatake YAMATO {
594d0937875SMasatake YAMATO eof = true;
595d0937875SMasatake YAMATO break;
596d0937875SMasatake YAMATO }
597d0937875SMasatake YAMATO if (capture_name)
598d0937875SMasatake YAMATO {
599d0937875SMasatake YAMATO copyToken (name, token);
600d0937875SMasatake YAMATO vStringClear (name->string);
601d0937875SMasatake YAMATO }
602d0937875SMasatake YAMATO
603d0937875SMasatake YAMATO while (! isType (token, terminator))
604d0937875SMasatake YAMATO {
605d0937875SMasatake YAMATO if (capture_name && isType (token, TOKEN_IDENTIFIER))
606d0937875SMasatake YAMATO {
607d0937875SMasatake YAMATO if (vStringLength (name->string) > 0)
608d0937875SMasatake YAMATO vStringPut (name->string, ' ');
609d0937875SMasatake YAMATO vStringCat (name->string, token->string);
610d0937875SMasatake YAMATO }
611d0937875SMasatake YAMATO
612d0937875SMasatake YAMATO if (!readTokenFull (token,
613d0937875SMasatake YAMATO s->flags & TEX_NAME_FLAG_INCLUDING_WHITESPACE))
614d0937875SMasatake YAMATO {
615d0937875SMasatake YAMATO eof = true;
616d0937875SMasatake YAMATO break;
617d0937875SMasatake YAMATO }
618d0937875SMasatake YAMATO }
619d0937875SMasatake YAMATO if (!exclusive && capture_name && vStringLength (name->string) > 0)
620d0937875SMasatake YAMATO {
621d0937875SMasatake YAMATO if (s->kindIndex != KIND_GHOST_INDEX)
622f67e271cSMasatake YAMATO s->corkIndex = makeTexTag (name, s->kindIndex, s->roleIndex,
623f67e271cSMasatake YAMATO s->unique, s->scopeIndex);
624d0937875SMasatake YAMATO
625d0937875SMasatake YAMATO if (s->name)
626d0937875SMasatake YAMATO vStringCopy(s->name, name->string);
627d0937875SMasatake YAMATO
628d0937875SMasatake YAMATO if (s->flags & TEX_NAME_FLAG_EXCLUSIVE)
629d0937875SMasatake YAMATO exclusive = true;
630d0937875SMasatake YAMATO }
631d0937875SMasatake YAMATO }
632d0937875SMasatake YAMATO else if (s->type == '*' && isType (token, '*'))
633d0937875SMasatake YAMATO next_token = true;
634c6cbaf9cSJiří Techet else if (((s->type == '{' || s->type == '\\') && isType (token, '{')) ||
635c6cbaf9cSJiří Techet (s->type == '\\' && isType (token, TOKEN_IDENTIFIER)))
636d0937875SMasatake YAMATO {
637d0937875SMasatake YAMATO int depth = 1;
638c6cbaf9cSJiří Techet bool missing_parens = isType (token, TOKEN_IDENTIFIER);
639d0937875SMasatake YAMATO
640d0937875SMasatake YAMATO next_token = true;
641d0937875SMasatake YAMATO
642c6cbaf9cSJiří Techet if (!missing_parens && !readToken (token))
643d0937875SMasatake YAMATO {
644d0937875SMasatake YAMATO eof = true;
645d0937875SMasatake YAMATO break;
646d0937875SMasatake YAMATO }
647d0937875SMasatake YAMATO if (capture_name)
648d0937875SMasatake YAMATO {
649d0937875SMasatake YAMATO copyToken (name, token);
650d0937875SMasatake YAMATO vStringClear (name->string);
651d0937875SMasatake YAMATO }
652c6cbaf9cSJiří Techet if (missing_parens)
65304d5c984SJiří Techet {
65404d5c984SJiří Techet vStringCat (name->string, token->string);
65504d5c984SJiří Techet depth = 0;
65604d5c984SJiří Techet }
657d0937875SMasatake YAMATO
658d0937875SMasatake YAMATO /* Handle the case the code like \section{} */
659d0937875SMasatake YAMATO if (isType (token, '}'))
660d0937875SMasatake YAMATO break;
661d0937875SMasatake YAMATO while (depth > 0)
662d0937875SMasatake YAMATO {
663d0937875SMasatake YAMATO if (capture_name)
664d0937875SMasatake YAMATO {
665d0937875SMasatake YAMATO if (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))
666d0937875SMasatake YAMATO vStringCat (name->string, token->string);
667d0937875SMasatake YAMATO else
668d0937875SMasatake YAMATO vStringPut (name->string, token->type);
669d0937875SMasatake YAMATO }
670d0937875SMasatake YAMATO if (!readTokenFull (token,
671d0937875SMasatake YAMATO s->flags & TEX_NAME_FLAG_INCLUDING_WHITESPACE))
672d0937875SMasatake YAMATO {
673d0937875SMasatake YAMATO eof = true;
674d0937875SMasatake YAMATO break;
675d0937875SMasatake YAMATO }
676d0937875SMasatake YAMATO else if (isType (token, TOKEN_OPEN_CURLY))
677d0937875SMasatake YAMATO depth++;
678d0937875SMasatake YAMATO else if (isType (token, TOKEN_CLOSE_CURLY))
679d0937875SMasatake YAMATO depth--;
680d0937875SMasatake YAMATO }
681d0937875SMasatake YAMATO if (!exclusive && depth == 0 && capture_name && vStringLength (name->string) > 0)
682d0937875SMasatake YAMATO {
683d0937875SMasatake YAMATO vStringStripTrailing (name->string);
684d0937875SMasatake YAMATO
685d0937875SMasatake YAMATO if (s->kindIndex != KIND_GHOST_INDEX)
686f67e271cSMasatake YAMATO s->corkIndex = makeTexTag (name, s->kindIndex, s->roleIndex,
687f67e271cSMasatake YAMATO s->unique, s->scopeIndex);
688d0937875SMasatake YAMATO
689d0937875SMasatake YAMATO if (s->name)
690d0937875SMasatake YAMATO vStringCopy(s->name, name->string);
691d0937875SMasatake YAMATO
692d0937875SMasatake YAMATO if (s->flags & TEX_NAME_FLAG_EXCLUSIVE)
693d0937875SMasatake YAMATO exclusive = true;
694d0937875SMasatake YAMATO
695d0937875SMasatake YAMATO }
696d0937875SMasatake YAMATO }
697d0937875SMasatake YAMATO else if (s->flags & TEX_NAME_FLAG_OPTIONAL)
698d0937875SMasatake YAMATO /* Apply next strategy to the same token */
699d0937875SMasatake YAMATO next_token = false;
700d0937875SMasatake YAMATO else
701d0937875SMasatake YAMATO {
702d0937875SMasatake YAMATO *tokenUnprocessed = true;
703d0937875SMasatake YAMATO break;
704d0937875SMasatake YAMATO }
705d0937875SMasatake YAMATO }
706d0937875SMasatake YAMATO
707af6af4ddSJiří Techet /* The last token is optional and not present - let the caller know */
708af6af4ddSJiří Techet if (!next_token)
709af6af4ddSJiří Techet *tokenUnprocessed = true;
710af6af4ddSJiří Techet
711d0937875SMasatake YAMATO if (name)
712d0937875SMasatake YAMATO deleteToken (name);
713d0937875SMasatake YAMATO
714d0937875SMasatake YAMATO return eof;
715d0937875SMasatake YAMATO }
716d0937875SMasatake YAMATO
parseTagFull(tokenInfo * const token,texKind kind,int roleIndex,bool enterSquare,bool * tokenUnprocessed)717f7be3a35SMasatake YAMATO static bool parseTagFull (tokenInfo *const token, texKind kind, int roleIndex, bool enterSquare, bool *tokenUnprocessed)
718d0937875SMasatake YAMATO {
719d0937875SMasatake YAMATO bool eof = false;
720d0937875SMasatake YAMATO vString *taggedName = vStringNew();
7213ae02089SMasatake YAMATO
7223ae02089SMasatake YAMATO /*
7233ae02089SMasatake YAMATO * Tex tags are of these formats:
7243ae02089SMasatake YAMATO * \keyword{any number of words}
7253ae02089SMasatake YAMATO * \keyword[short desc]{any number of words}
7263ae02089SMasatake YAMATO * \keyword*[short desc]{any number of words}
7273ae02089SMasatake YAMATO *
7283ae02089SMasatake YAMATO * When a keyword is found, loop through all words within
7293ae02089SMasatake YAMATO * the curly braces for the tag name.
7305100d567SMasatake YAMATO *
7315100d567SMasatake YAMATO * If the keyword is label like \label, words in the square
7329173df85SMasatake YAMATO * brackets should be skipped. This can be controlled
7339173df85SMasatake YAMATO * with `enterSquare' parameter; true is for tagging, and
7349173df85SMasatake YAMATO * false is for skipping.
7353ae02089SMasatake YAMATO */
7363ae02089SMasatake YAMATO
737d0937875SMasatake YAMATO struct TexParseStrategy strategy [] = {
7383ae02089SMasatake YAMATO {
739d0937875SMasatake YAMATO .type = '[',
740d0937875SMasatake YAMATO .flags = TEX_NAME_FLAG_OPTIONAL,
741d0937875SMasatake YAMATO /* .kindIndex is initialized dynamically. */
742d0937875SMasatake YAMATO },
743969a87f4SMasatake YAMATO {
744d0937875SMasatake YAMATO .type = '*',
745d0937875SMasatake YAMATO .flags = TEX_NAME_FLAG_OPTIONAL,
746d0937875SMasatake YAMATO .kindIndex = KIND_GHOST_INDEX,
747d0937875SMasatake YAMATO .name = NULL,
748d0937875SMasatake YAMATO },
749d0937875SMasatake YAMATO {
750d0937875SMasatake YAMATO .type = '{',
751d0937875SMasatake YAMATO .flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,
752d0937875SMasatake YAMATO .kindIndex = kind,
753f7be3a35SMasatake YAMATO .roleIndex = roleIndex,
754d0937875SMasatake YAMATO .name = taggedName,
755f67e271cSMasatake YAMATO .unique = false,
756d0937875SMasatake YAMATO },
757d0937875SMasatake YAMATO {
758d0937875SMasatake YAMATO .type = 0
759969a87f4SMasatake YAMATO }
760d0937875SMasatake YAMATO };
7613ae02089SMasatake YAMATO
7623ae02089SMasatake YAMATO
7635100d567SMasatake YAMATO if (enterSquare)
7645100d567SMasatake YAMATO {
765d0937875SMasatake YAMATO strategy [0].kindIndex = kind;
766f7be3a35SMasatake YAMATO strategy [0].roleIndex = roleIndex;
767d0937875SMasatake YAMATO strategy [0].flags |= TEX_NAME_FLAG_EXCLUSIVE;
768d0937875SMasatake YAMATO strategy [0].name = taggedName;
769f67e271cSMasatake YAMATO strategy [0].unique = false;
7703ae02089SMasatake YAMATO }
77174756360SColomban Wendling else
772d0937875SMasatake YAMATO {
773d0937875SMasatake YAMATO strategy [0].kindIndex = KIND_GHOST_INDEX;
774d0937875SMasatake YAMATO strategy [0].name = NULL;
7753ae02089SMasatake YAMATO }
776d0937875SMasatake YAMATO
777d0937875SMasatake YAMATO if (parseWithStrategy (token, strategy, tokenUnprocessed))
778969a87f4SMasatake YAMATO {
779969a87f4SMasatake YAMATO eof = true;
780969a87f4SMasatake YAMATO goto out;
781969a87f4SMasatake YAMATO }
7823ae02089SMasatake YAMATO
7833ae02089SMasatake YAMATO /*
7843ae02089SMasatake YAMATO * save the name of the last section definitions for scope-resolution
7853ae02089SMasatake YAMATO * later
7863ae02089SMasatake YAMATO */
787d0937875SMasatake YAMATO if (vStringLength (taggedName) > 0)
788d0937875SMasatake YAMATO updateScopeInfo (kind, taggedName);
7893ae02089SMasatake YAMATO
790969a87f4SMasatake YAMATO out:
791d0937875SMasatake YAMATO vStringDelete (taggedName);
792d0937875SMasatake YAMATO
793969a87f4SMasatake YAMATO return eof;
7943ae02089SMasatake YAMATO }
7953ae02089SMasatake YAMATO
parseTag(tokenInfo * const token,texKind kind,bool enterSquare,bool * tokenUnprocessed)796f7be3a35SMasatake YAMATO static bool parseTag (tokenInfo *const token, texKind kind,
797f7be3a35SMasatake YAMATO bool enterSquare, bool *tokenUnprocessed)
798f7be3a35SMasatake YAMATO {
799f7be3a35SMasatake YAMATO return parseTagFull (token, kind, ROLE_DEFINITION_INDEX,
800f7be3a35SMasatake YAMATO enterSquare, tokenUnprocessed);
801f7be3a35SMasatake YAMATO }
802f7be3a35SMasatake YAMATO
parseEnv(tokenInfo * const token,bool begin,bool * tokenUnprocessed)8031cfa869bSMasatake YAMATO static bool parseEnv (tokenInfo *const token, bool begin, bool *tokenUnprocessed)
8041cfa869bSMasatake YAMATO {
8051cfa869bSMasatake YAMATO bool eof = false;
8061cfa869bSMasatake YAMATO vString *envName = vStringNew ();
8071cfa869bSMasatake YAMATO struct TexParseStrategy strategy [] = {
8081cfa869bSMasatake YAMATO {
8091cfa869bSMasatake YAMATO .type = '{',
8101cfa869bSMasatake YAMATO .flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,
8116e18762eSJiří Techet .kindIndex = begin ? TEXTAG_ENVIRONMENT : KIND_GHOST_INDEX,
8126e18762eSJiří Techet .roleIndex = TEX_ENVIRONMENT_USED,
8131cfa869bSMasatake YAMATO .name = envName,
8141cfa869bSMasatake YAMATO },
8151cfa869bSMasatake YAMATO {
8161cfa869bSMasatake YAMATO .type = 0
8171cfa869bSMasatake YAMATO }
8181cfa869bSMasatake YAMATO };
8191cfa869bSMasatake YAMATO
8201cfa869bSMasatake YAMATO if (parseWithStrategy (token, strategy, tokenUnprocessed))
8211cfa869bSMasatake YAMATO {
8221cfa869bSMasatake YAMATO eof = true;
8231cfa869bSMasatake YAMATO goto out;
8241cfa869bSMasatake YAMATO }
8251cfa869bSMasatake YAMATO
8261cfa869bSMasatake YAMATO
8271cfa869bSMasatake YAMATO if (vStringLength (envName) > 0)
8281cfa869bSMasatake YAMATO {
8291cfa869bSMasatake YAMATO if (begin)
8301cfa869bSMasatake YAMATO eof = notifyReadingBeginEnvironment (token, envName, tokenUnprocessed);
8311cfa869bSMasatake YAMATO else
8321cfa869bSMasatake YAMATO eof = notifyReadingEndEnvironment (envName);
8331cfa869bSMasatake YAMATO }
8341cfa869bSMasatake YAMATO
8351cfa869bSMasatake YAMATO out:
8361cfa869bSMasatake YAMATO vStringDelete (envName);
8371cfa869bSMasatake YAMATO
8381cfa869bSMasatake YAMATO return eof;
8391cfa869bSMasatake YAMATO
8401cfa869bSMasatake YAMATO }
8411cfa869bSMasatake YAMATO
parseNewcommandFull(tokenInfo * const token,bool * tokenUnprocessed,texKind kind)842952983dbSJiří Techet static bool parseNewcommandFull (tokenInfo *const token, bool *tokenUnprocessed, texKind kind)
8433e2c7ce9SMasatake YAMATO {
8443e2c7ce9SMasatake YAMATO bool eof = false;
8453e2c7ce9SMasatake YAMATO
8463e2c7ce9SMasatake YAMATO /* \newcommand{cmd}[args][opt]{def} */
847c6cbaf9cSJiří Techet /* \newcommand\cmd[args][opt]{def} */
848c6cbaf9cSJiří Techet /* \def\cmd{replacement} */
8493e2c7ce9SMasatake YAMATO struct TexParseStrategy strategy [] = {
8503e2c7ce9SMasatake YAMATO {
851c6cbaf9cSJiří Techet .type = '\\',
8523e2c7ce9SMasatake YAMATO .flags = 0,
853952983dbSJiří Techet .kindIndex = kind,
8543e2c7ce9SMasatake YAMATO .roleIndex = ROLE_DEFINITION_INDEX,
8553e2c7ce9SMasatake YAMATO .name = NULL,
856f67e271cSMasatake YAMATO .unique = false,
8573e2c7ce9SMasatake YAMATO },
8583e2c7ce9SMasatake YAMATO {
8593e2c7ce9SMasatake YAMATO .type = '[',
8603e2c7ce9SMasatake YAMATO .flags = TEX_NAME_FLAG_OPTIONAL,
8613e2c7ce9SMasatake YAMATO .kindIndex = KIND_GHOST_INDEX,
8623e2c7ce9SMasatake YAMATO .name = NULL,
8633e2c7ce9SMasatake YAMATO },
8643e2c7ce9SMasatake YAMATO {
8653e2c7ce9SMasatake YAMATO .type = '[',
8663e2c7ce9SMasatake YAMATO .flags = TEX_NAME_FLAG_OPTIONAL,
8673e2c7ce9SMasatake YAMATO .kindIndex = KIND_GHOST_INDEX,
8683e2c7ce9SMasatake YAMATO .name = NULL,
8693e2c7ce9SMasatake YAMATO },
8703e2c7ce9SMasatake YAMATO {
8713e2c7ce9SMasatake YAMATO .type = '{',
8723e2c7ce9SMasatake YAMATO .flags = 0,
8733e2c7ce9SMasatake YAMATO .kindIndex = KIND_GHOST_INDEX,
8743e2c7ce9SMasatake YAMATO .name = NULL,
8753e2c7ce9SMasatake YAMATO },
8763e2c7ce9SMasatake YAMATO {
8773e2c7ce9SMasatake YAMATO .type = 0
8783e2c7ce9SMasatake YAMATO }
8793e2c7ce9SMasatake YAMATO };
8803e2c7ce9SMasatake YAMATO
8813e2c7ce9SMasatake YAMATO if (parseWithStrategy (token, strategy, tokenUnprocessed))
8823e2c7ce9SMasatake YAMATO eof = true;
8833e2c7ce9SMasatake YAMATO
8843e2c7ce9SMasatake YAMATO return eof;
8853e2c7ce9SMasatake YAMATO }
8863e2c7ce9SMasatake YAMATO
parseNewcommand(tokenInfo * const token,bool * tokenUnprocessed)887952983dbSJiří Techet static bool parseNewcommand (tokenInfo *const token, bool *tokenUnprocessed)
888952983dbSJiří Techet {
889952983dbSJiří Techet return parseNewcommandFull (token, tokenUnprocessed, TEXTAG_COMMAND);
890952983dbSJiří Techet }
891952983dbSJiří Techet
parseNewEnvironment(tokenInfo * const token,bool * tokenUnprocessed)892bcf90eddSJiří Techet static bool parseNewEnvironment (tokenInfo *const token, bool *tokenUnprocessed)
893bcf90eddSJiří Techet {
894bcf90eddSJiří Techet bool eof = false;
895bcf90eddSJiří Techet /* \newenvironment{nam}[args]{begdef}{enddef} */
896bcf90eddSJiří Techet struct TexParseStrategy strategy [] = {
897bcf90eddSJiří Techet {
898bcf90eddSJiří Techet .type = '{',
899bcf90eddSJiří Techet .flags = 0,
900bcf90eddSJiří Techet .kindIndex = TEXTAG_ENVIRONMENT,
901bcf90eddSJiří Techet .roleIndex = ROLE_DEFINITION_INDEX,
902bcf90eddSJiří Techet .name = NULL,
903bcf90eddSJiří Techet .unique = false,
904bcf90eddSJiří Techet },
905bcf90eddSJiří Techet {
906bcf90eddSJiří Techet .type = '[',
907bcf90eddSJiří Techet .flags = TEX_NAME_FLAG_OPTIONAL,
908bcf90eddSJiří Techet .kindIndex = KIND_GHOST_INDEX,
909bcf90eddSJiří Techet .name = NULL,
910bcf90eddSJiří Techet },
911bcf90eddSJiří Techet {
912bcf90eddSJiří Techet .type = '{',
913bcf90eddSJiří Techet .flags = 0,
914bcf90eddSJiří Techet .kindIndex = KIND_GHOST_INDEX,
915bcf90eddSJiří Techet .name = NULL,
916bcf90eddSJiří Techet },
917bcf90eddSJiří Techet {
918bcf90eddSJiří Techet .type = '{',
919bcf90eddSJiří Techet .flags = 0,
920bcf90eddSJiří Techet .kindIndex = KIND_GHOST_INDEX,
921bcf90eddSJiří Techet .name = NULL,
922bcf90eddSJiří Techet },
923bcf90eddSJiří Techet {
924bcf90eddSJiří Techet .type = 0
925bcf90eddSJiří Techet }
926bcf90eddSJiří Techet };
927bcf90eddSJiří Techet
928bcf90eddSJiří Techet if (parseWithStrategy (token, strategy, tokenUnprocessed))
929bcf90eddSJiří Techet eof = true;
930bcf90eddSJiří Techet
931bcf90eddSJiří Techet return eof;
932bcf90eddSJiří Techet }
933bcf90eddSJiří Techet
parseNewTheorem(tokenInfo * const token,bool * tokenUnprocessed)934aa63a3eaSJiří Techet static bool parseNewTheorem (tokenInfo *const token, bool *tokenUnprocessed)
935aa63a3eaSJiří Techet {
936aa63a3eaSJiří Techet bool eof = false;
937aa63a3eaSJiří Techet /* \newtheorem{name}{title}
938aa63a3eaSJiří Techet \newtheorem{name}{title}[numbered_within]
939aa63a3eaSJiří Techet \newtheorem{name}[numbered_like]{title} */
940aa63a3eaSJiří Techet struct TexParseStrategy strategy [] = {
941aa63a3eaSJiří Techet {
942aa63a3eaSJiří Techet .type = '{',
943aa63a3eaSJiří Techet .flags = 0,
944aa63a3eaSJiří Techet .kindIndex = TEXTAG_THEOREM,
945aa63a3eaSJiří Techet .roleIndex = ROLE_DEFINITION_INDEX,
946aa63a3eaSJiří Techet .name = NULL,
947aa63a3eaSJiří Techet .unique = false,
948aa63a3eaSJiří Techet },
949aa63a3eaSJiří Techet {
950aa63a3eaSJiří Techet .type = '[',
951aa63a3eaSJiří Techet .flags = TEX_NAME_FLAG_OPTIONAL,
952aa63a3eaSJiří Techet .kindIndex = KIND_GHOST_INDEX,
953aa63a3eaSJiří Techet .name = NULL,
954aa63a3eaSJiří Techet },
955aa63a3eaSJiří Techet {
956aa63a3eaSJiří Techet .type = '{',
957aa63a3eaSJiří Techet .flags = 0,
958aa63a3eaSJiří Techet .kindIndex = KIND_GHOST_INDEX,
959aa63a3eaSJiří Techet .name = NULL,
960aa63a3eaSJiří Techet },
961aa63a3eaSJiří Techet {
962aa63a3eaSJiří Techet .type = '[',
963aa63a3eaSJiří Techet .flags = TEX_NAME_FLAG_OPTIONAL,
964aa63a3eaSJiří Techet .kindIndex = KIND_GHOST_INDEX,
965aa63a3eaSJiří Techet .name = NULL,
966aa63a3eaSJiří Techet },
967aa63a3eaSJiří Techet {
968aa63a3eaSJiří Techet .type = 0
969aa63a3eaSJiří Techet }
970aa63a3eaSJiří Techet };
971aa63a3eaSJiří Techet
972aa63a3eaSJiří Techet if (parseWithStrategy (token, strategy, tokenUnprocessed))
973aa63a3eaSJiří Techet eof = true;
974aa63a3eaSJiří Techet
975aa63a3eaSJiří Techet return eof;
976aa63a3eaSJiří Techet }
977aa63a3eaSJiří Techet
parseNewcounter(tokenInfo * const token,bool * tokenUnprocessed)9783859e610SMasatake YAMATO static bool parseNewcounter (tokenInfo *const token, bool *tokenUnprocessed)
9793859e610SMasatake YAMATO {
9803859e610SMasatake YAMATO bool eof = false;
981af6af4ddSJiří Techet /* \newcounter {counter}[parentCounter] */
9823859e610SMasatake YAMATO struct TexParseStrategy strategy [] = {
9833859e610SMasatake YAMATO {
9843859e610SMasatake YAMATO .type = '{',
9853859e610SMasatake YAMATO .flags = 0,
9863859e610SMasatake YAMATO .kindIndex = TEXTAG_COUNTER,
9873859e610SMasatake YAMATO .roleIndex = ROLE_DEFINITION_INDEX,
9883859e610SMasatake YAMATO .name = NULL,
989f67e271cSMasatake YAMATO .unique = false,
9903859e610SMasatake YAMATO },
9913859e610SMasatake YAMATO {
9923859e610SMasatake YAMATO .type = '[',
993af6af4ddSJiří Techet .flags = TEX_NAME_FLAG_OPTIONAL,
9943859e610SMasatake YAMATO .kindIndex = KIND_GHOST_INDEX,
9953859e610SMasatake YAMATO .name = NULL,
9963859e610SMasatake YAMATO },
9973859e610SMasatake YAMATO {
9983859e610SMasatake YAMATO .type = 0
9993859e610SMasatake YAMATO }
10003859e610SMasatake YAMATO };
10013859e610SMasatake YAMATO
10023859e610SMasatake YAMATO if (parseWithStrategy (token, strategy, tokenUnprocessed))
10033859e610SMasatake YAMATO eof = true;
10043859e610SMasatake YAMATO
10053859e610SMasatake YAMATO return eof;
10063859e610SMasatake YAMATO }
1007bcf90eddSJiří Techet
parseTexFile(tokenInfo * const token)10083ae02089SMasatake YAMATO static void parseTexFile (tokenInfo *const token)
10093ae02089SMasatake YAMATO {
1010969a87f4SMasatake YAMATO bool eof = false;
1011d0937875SMasatake YAMATO bool tokenUnprocessed = false;
1012969a87f4SMasatake YAMATO
10133ae02089SMasatake YAMATO do
10143ae02089SMasatake YAMATO {
1015d0937875SMasatake YAMATO if (!tokenUnprocessed)
1016d0937875SMasatake YAMATO {
1017969a87f4SMasatake YAMATO if (!readToken (token))
1018969a87f4SMasatake YAMATO break;
1019d0937875SMasatake YAMATO }
1020d0937875SMasatake YAMATO tokenUnprocessed = false;
10213ae02089SMasatake YAMATO
10223ae02089SMasatake YAMATO if (isType (token, TOKEN_KEYWORD))
10233ae02089SMasatake YAMATO {
10243ae02089SMasatake YAMATO switch (token->keyword)
10253ae02089SMasatake YAMATO {
10263ae02089SMasatake YAMATO case KEYWORD_part:
1027d0937875SMasatake YAMATO eof = parseTag (token, TEXTAG_PART, true, &tokenUnprocessed);
10283ae02089SMasatake YAMATO break;
10293ae02089SMasatake YAMATO case KEYWORD_chapter:
1030d0937875SMasatake YAMATO eof = parseTag (token, TEXTAG_CHAPTER, true, &tokenUnprocessed);
10313ae02089SMasatake YAMATO break;
10323ae02089SMasatake YAMATO case KEYWORD_section:
1033d0937875SMasatake YAMATO eof = parseTag (token, TEXTAG_SECTION, true, &tokenUnprocessed);
10343ae02089SMasatake YAMATO break;
10353ae02089SMasatake YAMATO case KEYWORD_subsection:
1036d0937875SMasatake YAMATO eof = parseTag (token, TEXTAG_SUBSECTION, true, &tokenUnprocessed);
10373ae02089SMasatake YAMATO break;
10383ae02089SMasatake YAMATO case KEYWORD_subsubsection:
1039d0937875SMasatake YAMATO eof = parseTag (token, TEXTAG_SUBSUBSECTION, true, &tokenUnprocessed);
10403ae02089SMasatake YAMATO break;
10413ae02089SMasatake YAMATO case KEYWORD_paragraph:
1042d0937875SMasatake YAMATO eof = parseTag (token, TEXTAG_PARAGRAPH, true, &tokenUnprocessed);
10433ae02089SMasatake YAMATO break;
10443ae02089SMasatake YAMATO case KEYWORD_subparagraph:
1045d0937875SMasatake YAMATO eof = parseTag (token, TEXTAG_SUBPARAGRAPH, true, &tokenUnprocessed);
10463ae02089SMasatake YAMATO break;
10473ae02089SMasatake YAMATO case KEYWORD_label:
1048d0937875SMasatake YAMATO eof = parseTag (token, TEXTAG_LABEL, false, &tokenUnprocessed);
10493ae02089SMasatake YAMATO break;
10503ae02089SMasatake YAMATO case KEYWORD_include:
1051f7be3a35SMasatake YAMATO eof = parseTagFull (token, TEXTAG_XINPUT, TEX_XINPUT_INCLUDED,
1052f7be3a35SMasatake YAMATO false, &tokenUnprocessed);
1053f7be3a35SMasatake YAMATO break;
1054f7be3a35SMasatake YAMATO case KEYWORD_input:
1055f7be3a35SMasatake YAMATO eof = parseTagFull (token, TEXTAG_XINPUT, TEX_XINPUT_INPUT,
1056f7be3a35SMasatake YAMATO false, &tokenUnprocessed);
10573ae02089SMasatake YAMATO break;
10581cfa869bSMasatake YAMATO case KEYWORD_begin:
10591cfa869bSMasatake YAMATO eof = parseEnv (token, true, &tokenUnprocessed);
10601cfa869bSMasatake YAMATO break;
10611cfa869bSMasatake YAMATO case KEYWORD_end:
10621cfa869bSMasatake YAMATO eof = parseEnv (token, false, &tokenUnprocessed);
10631cfa869bSMasatake YAMATO break;
1064b3ac7a43SMasatake YAMATO case KEYWORD_bibitem:
1065b3ac7a43SMasatake YAMATO eof = parseTag (token, TEXTAG_BIBITEM, false, &tokenUnprocessed);
1066b3ac7a43SMasatake YAMATO break;
106747b7253cSMasatake YAMATO case KEYWORD_bibliography:
106847b7253cSMasatake YAMATO eof = parseTagFull (token, TEXTAG_XINPUT, TEX_XINPUT_BIBLIOGRAPHY,
106947b7253cSMasatake YAMATO false, &tokenUnprocessed);
1070be0f06e7SAvinash Sonawane break;
10713e2c7ce9SMasatake YAMATO case KEYWORD_newcommand:
1072c359e13dSJiří Techet case KEYWORD_renewcommand:
1073c359e13dSJiří Techet case KEYWORD_providecommand:
107404d5c984SJiří Techet case KEYWORD_def:
1075c6cbaf9cSJiří Techet eof = parseNewcommand (token, &tokenUnprocessed);
107604d5c984SJiří Techet break;
1077952983dbSJiří Techet case KEYWORD_declaremathoperator:
1078952983dbSJiří Techet eof = parseNewcommandFull (token, &tokenUnprocessed, TEXTAG_OPERATOR);
1079952983dbSJiří Techet break;
1080bcf90eddSJiří Techet case KEYWORD_newenvironment:
1081bcf90eddSJiří Techet case KEYWORD_renewenvironment:
1082bcf90eddSJiří Techet eof = parseNewEnvironment (token, &tokenUnprocessed);
1083bcf90eddSJiří Techet break;
1084aa63a3eaSJiří Techet case KEYWORD_newtheorem:
1085aa63a3eaSJiří Techet eof = parseNewTheorem (token, &tokenUnprocessed);
1086aa63a3eaSJiří Techet break;
10873859e610SMasatake YAMATO case KEYWORD_newcounter:
10883859e610SMasatake YAMATO eof = parseNewcounter (token, &tokenUnprocessed);
10893859e610SMasatake YAMATO break;
10903ae02089SMasatake YAMATO default:
10913ae02089SMasatake YAMATO break;
10923ae02089SMasatake YAMATO }
10933ae02089SMasatake YAMATO }
10943b13813cSMasatake YAMATO else if (isType (token, TOKEN_IDENTIFIER))
10953b13813cSMasatake YAMATO eof = notifyReadingIdentifier (token, &tokenUnprocessed);
1096969a87f4SMasatake YAMATO if (eof)
1097969a87f4SMasatake YAMATO break;
1098ce990805SThomas Braun } while (true);
10993ae02089SMasatake YAMATO }
11003ae02089SMasatake YAMATO
initialize(const langType language)11013ae02089SMasatake YAMATO static void initialize (const langType language)
11023ae02089SMasatake YAMATO {
1103158a3387SMasatake YAMATO Assert (ARRAY_SIZE (TexKinds) == TEXTAG_COUNT);
1104970f6116SJiří Techet Lang_tex = language;
11053ae02089SMasatake YAMATO
11063ae02089SMasatake YAMATO lastPart = vStringNew();
11073ae02089SMasatake YAMATO lastChapter = vStringNew();
11083ae02089SMasatake YAMATO lastSection = vStringNew();
11093ae02089SMasatake YAMATO lastSubS = vStringNew();
11103ae02089SMasatake YAMATO lastSubSubS = vStringNew();
11113ae02089SMasatake YAMATO }
11123ae02089SMasatake YAMATO
finalize(const langType language CTAGS_ATTR_UNUSED,bool initialized)11138ccb7ee9SJiří Techet static void finalize (const langType language CTAGS_ATTR_UNUSED,
1114ce990805SThomas Braun bool initialized)
111519e4de57SMasatake YAMATO {
111619e4de57SMasatake YAMATO if (initialized)
11173ae02089SMasatake YAMATO {
11183ae02089SMasatake YAMATO vStringDelete(lastPart);
11193ae02089SMasatake YAMATO lastPart = NULL;
11203ae02089SMasatake YAMATO vStringDelete(lastChapter);
11213ae02089SMasatake YAMATO lastChapter = NULL;
11223ae02089SMasatake YAMATO vStringDelete(lastSection);
11233ae02089SMasatake YAMATO lastSection = NULL;
11243ae02089SMasatake YAMATO vStringDelete(lastSubS);
11253ae02089SMasatake YAMATO lastSubS = NULL;
11263ae02089SMasatake YAMATO vStringDelete(lastSubSubS);
11273ae02089SMasatake YAMATO lastSubSubS = NULL;
11283ae02089SMasatake YAMATO }
112919e4de57SMasatake YAMATO }
11303ae02089SMasatake YAMATO
findTexTags(void)11313ae02089SMasatake YAMATO static void findTexTags (void)
11323ae02089SMasatake YAMATO {
11333ae02089SMasatake YAMATO tokenInfo *const token = newToken ();
11343ae02089SMasatake YAMATO
1135*add23eb1SJiří Techet vStringClear(lastPart);
1136*add23eb1SJiří Techet vStringClear(lastChapter);
1137*add23eb1SJiří Techet vStringClear(lastSection);
1138*add23eb1SJiří Techet vStringClear(lastSubS);
1139*add23eb1SJiří Techet vStringClear(lastSubSubS);
1140*add23eb1SJiří Techet
11413ae02089SMasatake YAMATO parseTexFile (token);
11423ae02089SMasatake YAMATO
11433ae02089SMasatake YAMATO deleteToken (token);
11443ae02089SMasatake YAMATO }
11453ae02089SMasatake YAMATO
notifyReadingIdentifier(tokenInfo * id_token,bool * tokenUnprocessed)11463b13813cSMasatake YAMATO static bool notifyReadingIdentifier (tokenInfo *id_token, bool *tokenUnprocessed)
11473b13813cSMasatake YAMATO {
11483b13813cSMasatake YAMATO subparser *sub;
11493b13813cSMasatake YAMATO bool eof = false;
11503b13813cSMasatake YAMATO
11513b13813cSMasatake YAMATO foreachSubparser (sub, false)
11523b13813cSMasatake YAMATO {
11533b13813cSMasatake YAMATO texSubparser *texsub = (texSubparser *)sub;
11543b13813cSMasatake YAMATO
11553b13813cSMasatake YAMATO if (texsub->readIdentifierNotify)
11563b13813cSMasatake YAMATO {
11573b13813cSMasatake YAMATO struct TexParseStrategy *strategy;
11583b13813cSMasatake YAMATO
11593b13813cSMasatake YAMATO enterSubparser(sub);
11603b13813cSMasatake YAMATO
11613b13813cSMasatake YAMATO strategy = texsub->readIdentifierNotify (texsub, id_token->string);
11623b13813cSMasatake YAMATO
11633b13813cSMasatake YAMATO if (strategy)
1164f03d2abaSMasatake YAMATO {
11653b13813cSMasatake YAMATO eof = parseWithStrategy (id_token, strategy, tokenUnprocessed);
1166f03d2abaSMasatake YAMATO if (texsub->reportStrategicParsing)
1167f03d2abaSMasatake YAMATO texsub->reportStrategicParsing (texsub, strategy);
1168f03d2abaSMasatake YAMATO }
11693b13813cSMasatake YAMATO
11703b13813cSMasatake YAMATO leaveSubparser();
11713b13813cSMasatake YAMATO
11723b13813cSMasatake YAMATO if (strategy)
11733b13813cSMasatake YAMATO break;
11743b13813cSMasatake YAMATO }
11753b13813cSMasatake YAMATO }
11763b13813cSMasatake YAMATO
11773b13813cSMasatake YAMATO return eof;
11783b13813cSMasatake YAMATO }
11793b13813cSMasatake YAMATO
notifyReadingBeginEnvironment(tokenInfo * token,vString * envName,bool * tokenUnprocessed)11801cfa869bSMasatake YAMATO static bool notifyReadingBeginEnvironment (tokenInfo *token,
11811cfa869bSMasatake YAMATO vString *envName,
11821cfa869bSMasatake YAMATO bool *tokenUnprocessed)
11831cfa869bSMasatake YAMATO {
11841cfa869bSMasatake YAMATO subparser *sub;
11851cfa869bSMasatake YAMATO bool eof = false;
11861cfa869bSMasatake YAMATO
11871cfa869bSMasatake YAMATO foreachSubparser (sub, false)
11881cfa869bSMasatake YAMATO {
11891cfa869bSMasatake YAMATO texSubparser *texsub = (texSubparser *)sub;
11901cfa869bSMasatake YAMATO
11911cfa869bSMasatake YAMATO if (texsub->readEnviromentBeginNotify)
11921cfa869bSMasatake YAMATO {
11931cfa869bSMasatake YAMATO struct TexParseStrategy *strategy;
11941cfa869bSMasatake YAMATO
11951cfa869bSMasatake YAMATO enterSubparser (sub);
11961cfa869bSMasatake YAMATO strategy = texsub->readEnviromentBeginNotify (texsub, envName);
11971cfa869bSMasatake YAMATO if (strategy)
1198f03d2abaSMasatake YAMATO {
11991cfa869bSMasatake YAMATO eof = parseWithStrategy (token, strategy, tokenUnprocessed);
1200f03d2abaSMasatake YAMATO if (texsub->reportStrategicParsing)
1201f03d2abaSMasatake YAMATO texsub->reportStrategicParsing (texsub, strategy);
1202f03d2abaSMasatake YAMATO }
12031cfa869bSMasatake YAMATO leaveSubparser ();
12041cfa869bSMasatake YAMATO if (strategy)
12051cfa869bSMasatake YAMATO break;
12061cfa869bSMasatake YAMATO }
12071cfa869bSMasatake YAMATO }
12081cfa869bSMasatake YAMATO
12091cfa869bSMasatake YAMATO return eof;
12101cfa869bSMasatake YAMATO }
12111cfa869bSMasatake YAMATO
notifyReadingEndEnvironment(vString * envName)12121cfa869bSMasatake YAMATO static bool notifyReadingEndEnvironment (vString *envName)
12131cfa869bSMasatake YAMATO {
12141cfa869bSMasatake YAMATO subparser *sub;
12151cfa869bSMasatake YAMATO
12161cfa869bSMasatake YAMATO foreachSubparser (sub, false)
12171cfa869bSMasatake YAMATO {
12181cfa869bSMasatake YAMATO texSubparser *texsub = (texSubparser *)sub;
12191cfa869bSMasatake YAMATO
12201cfa869bSMasatake YAMATO if (texsub->readEnviromentEndNotify)
12211cfa869bSMasatake YAMATO {
12221cfa869bSMasatake YAMATO bool consuming;
12231cfa869bSMasatake YAMATO
12241cfa869bSMasatake YAMATO enterSubparser (sub);
12251cfa869bSMasatake YAMATO consuming = texsub->readEnviromentEndNotify (texsub, envName);
12261cfa869bSMasatake YAMATO leaveSubparser ();
12271cfa869bSMasatake YAMATO if (consuming)
12281cfa869bSMasatake YAMATO break;
12291cfa869bSMasatake YAMATO }
12301cfa869bSMasatake YAMATO }
12311cfa869bSMasatake YAMATO
12321cfa869bSMasatake YAMATO return false;
12331cfa869bSMasatake YAMATO }
12341cfa869bSMasatake YAMATO
1235137eb990SK.Takata /* Create parser definition structure */
TexParser(void)12363ae02089SMasatake YAMATO extern parserDefinition* TexParser (void)
12373ae02089SMasatake YAMATO {
12383ae02089SMasatake YAMATO static const char *const extensions [] = { "tex", NULL };
12393ae02089SMasatake YAMATO parserDefinition *const def = parserNew ("Tex");
12403ae02089SMasatake YAMATO def->extensions = extensions;
12413ae02089SMasatake YAMATO /*
12423ae02089SMasatake YAMATO * New definitions for parsing instead of regex
12433ae02089SMasatake YAMATO */
124409ae690fSMasatake YAMATO def->kindTable = TexKinds;
12453db72c21SMasatake YAMATO def->kindCount = ARRAY_SIZE (TexKinds);
12463ae02089SMasatake YAMATO def->parser = findTexTags;
12473ae02089SMasatake YAMATO def->initialize = initialize;
12483ae02089SMasatake YAMATO def->finalize = finalize;
1249c379c5d2SMasatake YAMATO def->keywordTable = TexKeywordTable;
12503db72c21SMasatake YAMATO def->keywordCount = ARRAY_SIZE (TexKeywordTable);
1251f67e271cSMasatake YAMATO def->useCork = CORK_QUEUE | CORK_SYMTAB;
12523ae02089SMasatake YAMATO return def;
12533ae02089SMasatake YAMATO }
1254