Version bump.
[geany-mirror.git] / tagmanager / rest.c
blob3b065dba2ccd5616eb12802babaf33eb0ba015ea
1 /*
3 * Copyright (c) 2007-2010, Nick Treleaven
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 reStructuredText (reST) files.
9 */
12 * INCLUDE FILES
14 #include "general.h" /* must always come first */
16 #include <ctype.h>
17 #include <string.h>
19 #include "parse.h"
20 #include "read.h"
21 #include "vstring.h"
22 #include "nestlevel.h"
25 * DATA DEFINITIONS
27 typedef enum {
28 K_CHAPTER = 0,
29 K_SECTION,
30 K_SUBSECTION,
31 K_SUBSUBSECTION,
32 SECTION_COUNT
33 } restKind;
35 static kindOption RestKinds[] = {
36 { TRUE, 'n', "namespace", "chapters"},
37 { TRUE, 'm', "member", "sections" },
38 { TRUE, 'd', "macro", "subsections" },
39 { TRUE, 'v', "variable", "subsubsections" }
42 static char kindchars[SECTION_COUNT];
44 static NestingLevels *nestingLevels = NULL;
47 * FUNCTION DEFINITIONS
50 static NestingLevel *getNestingLevel(const int kind)
52 NestingLevel *nl;
54 while (1)
56 nl = nestingLevelsGetCurrent(nestingLevels);
57 if (nl && nl->type >= kind)
58 nestingLevelsPop(nestingLevels);
59 else
60 break;
62 return nl;
65 static void makeRestTag (const vString* const name, const int kind)
67 const NestingLevel *const nl = getNestingLevel(kind);
69 if (vStringLength (name) > 0)
71 tagEntryInfo e;
72 initTagEntry (&e, vStringValue (name));
74 e.lineNumber--; /* we want the line before the '---' underline chars */
75 e.kindName = RestKinds [kind].name;
76 e.kind = RestKinds [kind].letter;
78 if (nl && nl->type < kind)
80 e.extensionFields.scope [0] = RestKinds [nl->type].name;
81 e.extensionFields.scope [1] = vStringValue (nl->name);
83 makeTagEntry (&e);
85 nestingLevelsPush(nestingLevels, name, kind);
89 /* checks if str is all the same character */
90 static boolean issame(const char *str)
92 char first = *str;
94 while (*str)
96 char c;
98 str++;
99 c = *str;
100 if (c && c != first)
101 return FALSE;
103 return TRUE;
107 static int get_kind(char c)
109 int i;
111 for (i = 0; i < SECTION_COUNT; i++)
113 if (kindchars[i] == c)
114 return i;
116 if (kindchars[i] == 0)
118 kindchars[i] = c;
119 return i;
122 return -1;
126 /* TODO: parse overlining & underlining as distinct sections. */
127 static void findRestTags (void)
129 vString *name = vStringNew ();
130 const unsigned char *line;
132 memset(kindchars, 0, sizeof kindchars);
133 nestingLevels = nestingLevelsNew();
135 while ((line = fileReadLine ()) != NULL)
137 int line_len = strlen((const char*) line);
138 int name_len = vStringLength(name);
140 /* underlines must be the same length or more */
141 if (line_len >= name_len && name_len > 0 &&
142 ispunct(line[0]) && issame((const char*) line))
144 char c = line[0];
145 int kind = get_kind(c);
147 if (kind >= 0)
149 makeRestTag(name, kind);
150 continue;
153 vStringClear (name);
154 if (! isspace(*line))
155 vStringCatS(name, (const char*) line);
156 vStringTerminate(name);
158 vStringDelete (name);
159 nestingLevelsFree(nestingLevels);
162 extern parserDefinition* RestParser (void)
164 static const char *const patterns [] = { "*.rest", "*.reST", NULL };
165 static const char *const extensions [] = { "rest", NULL };
166 parserDefinition* const def = parserNew ("reStructuredText");
168 def->kinds = RestKinds;
169 def->kindCount = KIND_COUNT (RestKinds);
170 def->patterns = patterns;
171 def->extensions = extensions;
172 def->parser = findRestTags;
173 return def;
176 /* vi:set tabstop=8 shiftwidth=4: */