manual: added documentation about replacement of 'untitled.ext' with filename (#1804)
[geany-mirror.git] / ctags / parsers / latex.c
blobb25317c4763038065ff8711a96c81fe57809eabe
1 /*
2 * Copyright (c) 2000-2001, Jérôme Plût
3 * Copyright (c) 2006, Enrico Tröger
5 * This source code is released for free distribution under the terms of the
6 * GNU General Public License.
8 * This module contains functions for generating tags for source files
9 * for the TeX formatting system.
13 * INCLUDE FILES
15 #include "general.h" /* must always come first */
17 #include <ctype.h>
18 #include <string.h>
20 #include "parse.h"
21 #include "read.h"
22 #include "vstring.h"
23 #include "routines.h"
26 * DATA DEFINITIONS
28 typedef enum {
29 K_COMMAND,
30 K_ENVIRONMENT,
31 K_SECTION,
32 K_SUBSECTION,
33 K_SUBSUBSECTION,
34 K_CHAPTER,
35 K_LABEL
36 } TeXKind;
38 static kindOption TeXKinds[] = {
39 { true, 'f', "function", "command definitions" },
40 { true, 'c', "class", "environment definitions" },
41 { true, 'm', "member", "labels, sections and bibliography" },
42 { true, 'd', "macro", "subsections" },
43 { true, 'v', "variable", "subsubsections" },
44 { true, 'n', "namespace", "chapters"},
45 { true, 's', "struct", "labels and bibliography" }
48 #define TEX_BRACES (1<<0)
49 #define TEX_BSLASH (1<<1)
50 #define TEX_LABEL (1<<2)
53 * FUNCTION DEFINITIONS
56 static int getWord(const char * ref, const char **ptr)
58 const char *p = *ptr;
60 while ((*ref != '\0') && (*p != '\0') && (*ref == *p))
61 ref++, p++;
64 if (*ref)
65 return false;
67 if (*p == '*') /* to allow something like \section*{foobar} */
68 p++;
70 *ptr = p;
71 return true;
74 static void createTag(int flags, TeXKind kind, const char * l)
76 vString *name = vStringNew ();
78 while ((*l == ' '))
79 l++;
80 if (flags & (TEX_BRACES | TEX_LABEL))
82 if (*l == '[')
84 while (*l != ']')
86 if (*l == '\0')
87 goto no_tag;
88 l++;
90 l++; /* skip the closing square bracket */
92 if (*l != '{')
93 goto no_tag;
94 l++;
96 if (flags & TEX_BSLASH)
98 if ((*(l++)) != '\\')
99 goto no_tag;
101 if (flags & TEX_LABEL)
105 vStringPut(name, (int) *l);
106 ++l;
107 } while ((*l != '\0') && (*l != '}'));
108 if (name->buffer[0] != '}')
109 makeSimpleTag(name, TeXKinds, kind);
111 else if (isalpha((int) *l) || *l == '@')
115 vStringPut (name, (int) *l);
116 ++l;
117 } while (isalpha((int) *l) || *l == '@');
118 makeSimpleTag(name, TeXKinds, kind);
120 else
122 vStringPut(name, (int) *l);
123 makeSimpleTag(name, TeXKinds, kind);
126 no_tag:
127 vStringDelete(name);
130 static void findTeXTags(void)
132 const char *line;
134 while ((line = (const char*)readLineFromInputFile()) != NULL)
136 const char *cp = line;
137 /*int escaped = 0;*/
139 for (; *cp != '\0'; cp++)
141 if (*cp == '%')
142 break;
143 if (*cp == '\\')
145 cp++;
147 /* \newcommand{\command} */
148 if (getWord("newcommand", &cp)
149 || getWord("providecommand", &cp)
150 || getWord("renewcommand", &cp)
153 createTag (TEX_BRACES|TEX_BSLASH, K_COMMAND, cp);
154 continue;
157 /* \DeclareMathOperator{\command} */
158 else if (getWord("DeclareMathOperator", &cp))
160 if (*cp == '*')
161 cp++;
162 createTag(TEX_BRACES|TEX_BSLASH, K_COMMAND, cp);
163 continue;
166 /* \def\command */
167 else if (getWord("def", &cp))
169 createTag(TEX_BSLASH, K_COMMAND, cp);
170 continue;
173 /* \newenvironment{name} */
174 else if ( getWord("newenvironment", &cp)
175 || getWord("newtheorem", &cp)
176 || getWord("begin", &cp)
179 createTag(TEX_BRACES, K_ENVIRONMENT, cp);
180 continue;
183 /* \bibitem[label]{key} */
184 else if (getWord("bibitem", &cp))
186 while (*cp == ' ')
187 cp++;
188 if (*(cp++) != '[')
189 break;
190 while ((*cp != '\0') && (*cp != ']'))
191 cp++;
192 if (*(cp++) != ']')
193 break;
194 createTag(TEX_LABEL, K_LABEL, cp);
195 continue;
198 /* \label{key} */
199 else if (getWord("label", &cp))
201 createTag(TEX_LABEL, K_LABEL, cp);
202 continue;
204 /* \section{key} */
205 else if (getWord("section", &cp))
207 createTag(TEX_LABEL, K_SECTION, cp);
208 continue;
210 /* \subsection{key} */
211 else if (getWord("subsection", &cp))
213 createTag(TEX_LABEL, K_SUBSECTION, cp);
214 continue;
216 /* \subsubsection{key} */
217 else if (getWord("subsubsection", &cp))
219 createTag(TEX_LABEL, K_SUBSUBSECTION, cp);
220 continue;
222 /* \chapter{key} */
223 else if (getWord("chapter", &cp))
225 createTag(TEX_LABEL, K_CHAPTER, cp);
226 continue;
233 extern parserDefinition* LaTeXParser (void)
235 static const char *const extensions [] = { "tex", "sty", "idx", NULL };
236 parserDefinition * def = parserNew ("LaTeX");
237 def->kinds = TeXKinds;
238 def->kindCount = ARRAY_SIZE (TeXKinds);
239 def->extensions = extensions;
240 def->parser = findTeXTags;
241 return def;