2007-08-14 11:50:03 +00:00
|
|
|
/*
|
|
|
|
*
|
2009-01-04 18:30:42 +00:00
|
|
|
* Copyright (c) 2007-2009, Nick Treleaven
|
2007-08-14 11:50:03 +00:00
|
|
|
*
|
|
|
|
* This source code is released for free distribution under the terms of the
|
|
|
|
* GNU General Public License.
|
|
|
|
*
|
|
|
|
* This module contains functions for generating tags for reStructuredText (reST) files.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* INCLUDE FILES
|
|
|
|
*/
|
|
|
|
#include "general.h" /* must always come first */
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "parse.h"
|
|
|
|
#include "read.h"
|
|
|
|
#include "vstring.h"
|
2009-05-11 15:36:46 +00:00
|
|
|
#include "nestlevel.h"
|
2007-08-14 11:50:03 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* DATA DEFINITIONS
|
|
|
|
*/
|
|
|
|
typedef enum {
|
2008-12-21 12:32:25 +00:00
|
|
|
K_CHAPTER = 0,
|
2008-12-19 18:11:54 +00:00
|
|
|
K_SECTION,
|
2007-08-14 11:50:03 +00:00
|
|
|
K_SUBSECTION,
|
2008-12-21 12:32:25 +00:00
|
|
|
K_SUBSUBSECTION,
|
|
|
|
SECTION_COUNT
|
2007-08-14 11:50:03 +00:00
|
|
|
} restKind;
|
|
|
|
|
|
|
|
static kindOption RestKinds[] = {
|
|
|
|
{ TRUE, 'n', "namespace", "chapters"},
|
|
|
|
{ TRUE, 'm', "member", "sections" },
|
|
|
|
{ TRUE, 'd', "macro", "subsections" },
|
|
|
|
{ TRUE, 'v', "variable", "subsubsections" }
|
|
|
|
};
|
|
|
|
|
2008-12-21 12:32:25 +00:00
|
|
|
static char kindchars[SECTION_COUNT];
|
|
|
|
|
2009-05-11 15:36:46 +00:00
|
|
|
static NestingLevels *nestingLevels = NULL;
|
|
|
|
|
2007-08-14 11:50:03 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION DEFINITIONS
|
|
|
|
*/
|
|
|
|
|
2009-05-11 15:36:46 +00:00
|
|
|
static NestingLevel *getNestingLevel(const int kind)
|
|
|
|
{
|
|
|
|
NestingLevel *nl;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
nl = nestingLevelsGetCurrent(nestingLevels);
|
|
|
|
if (nl && nl->type >= kind)
|
|
|
|
nestingLevelsPop(nestingLevels);
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return nl;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void makeRestTag (const vString* const name, const int kind)
|
2007-08-14 11:50:03 +00:00
|
|
|
{
|
2009-05-11 15:36:46 +00:00
|
|
|
const NestingLevel *const nl = getNestingLevel(kind);
|
|
|
|
|
|
|
|
if (vStringLength (name) > 0)
|
2008-12-19 18:11:54 +00:00
|
|
|
{
|
|
|
|
tagEntryInfo e;
|
|
|
|
initTagEntry (&e, vStringValue (name));
|
2007-08-14 11:50:03 +00:00
|
|
|
|
2008-12-19 18:11:54 +00:00
|
|
|
e.lineNumber--; /* we want the line before the '---' underline chars */
|
2009-05-11 15:36:46 +00:00
|
|
|
e.kindName = RestKinds [kind].name;
|
|
|
|
e.kind = RestKinds [kind].letter;
|
2007-08-14 11:50:03 +00:00
|
|
|
|
2009-05-11 15:36:46 +00:00
|
|
|
if (nl && nl->type < kind)
|
|
|
|
{
|
|
|
|
e.extensionFields.scope [0] = RestKinds [nl->type].name;
|
|
|
|
e.extensionFields.scope [1] = vStringValue (nl->name);
|
|
|
|
}
|
2008-12-19 18:11:54 +00:00
|
|
|
makeTagEntry (&e);
|
|
|
|
}
|
2009-05-11 15:36:46 +00:00
|
|
|
nestingLevelsPush(nestingLevels, name, kind);
|
2007-08-14 11:50:03 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 12:32:25 +00:00
|
|
|
|
|
|
|
/* checks if str is all the same character */
|
|
|
|
static boolean issame(const char *str)
|
|
|
|
{
|
|
|
|
char first = *str;
|
|
|
|
|
|
|
|
while (*str)
|
|
|
|
{
|
|
|
|
char c;
|
|
|
|
|
|
|
|
str++;
|
|
|
|
c = *str;
|
|
|
|
if (c && c != first)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int get_kind(char c)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < SECTION_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (kindchars[i] == c)
|
|
|
|
return i;
|
|
|
|
|
|
|
|
if (kindchars[i] == 0)
|
|
|
|
{
|
|
|
|
kindchars[i] = c;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* TODO: parse overlining & underlining as distinct sections. */
|
2007-08-14 11:50:03 +00:00
|
|
|
static void findRestTags (void)
|
|
|
|
{
|
2008-12-19 18:11:54 +00:00
|
|
|
vString *name = vStringNew ();
|
|
|
|
const unsigned char *line;
|
2007-08-14 11:50:03 +00:00
|
|
|
|
2008-12-21 12:32:25 +00:00
|
|
|
memset(kindchars, 0, sizeof kindchars);
|
2009-05-12 15:16:23 +00:00
|
|
|
nestingLevels = nestingLevelsNew();
|
2008-12-21 12:32:25 +00:00
|
|
|
|
2008-12-19 18:11:54 +00:00
|
|
|
while ((line = fileReadLine ()) != NULL)
|
|
|
|
{
|
2008-12-19 17:31:59 +00:00
|
|
|
int line_len = strlen((const char*) line);
|
2008-12-21 12:32:25 +00:00
|
|
|
int name_len = vStringLength(name);
|
2008-12-19 17:31:59 +00:00
|
|
|
|
2008-12-21 12:32:25 +00:00
|
|
|
/* underlines must be the same length or more */
|
|
|
|
if (line_len >= name_len && name_len > 0 &&
|
|
|
|
ispunct(line[0]) && issame((const char*) line))
|
2007-08-14 11:50:03 +00:00
|
|
|
{
|
2008-12-21 12:32:25 +00:00
|
|
|
char c = line[0];
|
|
|
|
int kind = get_kind(c);
|
|
|
|
|
|
|
|
if (kind >= 0)
|
2007-08-14 11:50:03 +00:00
|
|
|
{
|
2009-05-11 15:36:46 +00:00
|
|
|
makeRestTag(name, kind);
|
2007-08-14 11:50:03 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vStringClear (name);
|
|
|
|
if (! isspace(*line))
|
|
|
|
vStringCatS(name, (const char*) line);
|
|
|
|
vStringTerminate(name);
|
2008-12-19 18:11:54 +00:00
|
|
|
}
|
|
|
|
vStringDelete (name);
|
2009-05-12 15:16:23 +00:00
|
|
|
nestingLevelsFree(nestingLevels);
|
2007-08-14 11:50:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
extern parserDefinition* RestParser (void)
|
|
|
|
{
|
2008-12-19 18:11:54 +00:00
|
|
|
static const char *const patterns [] = { "*.rest", "*.reST", NULL };
|
|
|
|
static const char *const extensions [] = { "rest", NULL };
|
|
|
|
parserDefinition* const def = parserNew ("reStructuredText");
|
|
|
|
|
|
|
|
def->kinds = RestKinds;
|
|
|
|
def->kindCount = KIND_COUNT (RestKinds);
|
|
|
|
def->patterns = patterns;
|
|
|
|
def->extensions = extensions;
|
|
|
|
def->parser = findRestTags;
|
|
|
|
return def;
|
2007-08-14 11:50:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* vi:set tabstop=8 shiftwidth=4: */
|