added tagmanager support for filetype DocBook and LaTeX

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@123 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2006-01-11 18:50:44 +00:00
parent 9266f022d2
commit 46690c0b8f
4 changed files with 356 additions and 62 deletions

View File

@ -1,4 +1,6 @@
## Process this file with automake to produce Makefile.in
# $Id$
SUBDIRS = include
INCLUDES = -Iinclude $(PACKAGE_CFLAGS)
# -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED \
@ -15,7 +17,6 @@ libtagmanager_a_SOURCES =\
sort.h\
vstring.h\
args.h\
conf.c\
ctags.h\
entry.h\
get.h\
@ -26,6 +27,8 @@ libtagmanager_a_SOURCES =\
args.c\
args.h\
c.c\
conf.c\
docbook.c\
make.c\
tex.c\
pascal.c\

190
tagmanager/docbook.c Normal file
View File

@ -0,0 +1,190 @@
/*
* $Id$
*
* Copyright (c) 2001-2002, Darren Hiebert
* Copyright (c) 2006, Enrico Tröger
*
* 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 the DocBook language,
* to extract the id attribute from section and chapter tags.
* The code is based on pascal.c from tagmanager.
*
* TODO: skip commented blocks like <!-- <section id="comment">...</section> -->
*
*/
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include <string.h>
#include "entry.h"
#include "parse.h"
#include "read.h"
#include "vstring.h"
/*
* DATA DEFINITIONS
*/
typedef enum {
K_SECTION,
K_CHAPTER
} docbookKind;
static kindOption DocBookKinds [] = {
{ TRUE, 'c', "class", "sections"},
{ TRUE, 'n', "namespace", "chapters"},
};
/*
* FUNCTION DEFINITIONS
*/
static void createDocBookTag (tagEntryInfo* const tag,
const vString* const name, const int kind)
{
if (DocBookKinds[kind].enabled && name != NULL && vStringLength (name) > 0)
{
initTagEntry (tag, vStringValue (name));
tag->kindName = DocBookKinds [kind].name;
tag->kind = DocBookKinds [kind].letter;
}
else
initTagEntry (tag, NULL);
}
static void makeDocBookTag (const tagEntryInfo* const tag)
{
if (tag->name != NULL) makeTagEntry(tag);
}
static const unsigned char* dbp;
#define starttoken(c) ((int) c == '"')
//#define intoken(c) ((isalnum ((int) c) || isspace((int) c)) && (int) c != '"')
#define intoken(c) ((isalnum ((int) c) || (int) c == '_') && (int) c != '"')
#define endtoken(c) (! intoken (c))
static boolean tail (const char *cp)
{
boolean result = FALSE;
register int len = 0;
while (*cp != '\0' && tolower ((int) *cp) == tolower ((int) dbp [len]))
cp++, len++;
if (*cp == '\0' && !intoken (dbp [len]))
{
dbp += len;
result = TRUE;
}
return result;
}
/* Algorithm adapted from from GNU etags. */
static void findDocBookTags (void)
{
vString *name = vStringNew ();
tagEntryInfo tag;
docbookKind kind = K_SECTION;
/* each of these flags is TRUE iff: */
boolean get_tagname = FALSE;/* point is after tag, so next item = potential tag */
boolean found_tag = FALSE; /* point is after a potential tag */
boolean verify_tag = FALSE;
dbp = fileReadLine ();
while (dbp != NULL)
{
int c = *dbp++;
if (c == '\0') /* if end of line */
{
dbp = fileReadLine ();
if (dbp == NULL || *dbp == '\0')
continue;
if (!((found_tag && verify_tag) || get_tagname))
c = *dbp++; /* only if don't need *dbp pointing
to the beginning of the name of the tag */
}
if ((c == '"' || c == '>') && found_tag) // end of proc or fn stmt
{
verify_tag = TRUE;
continue;
}
if (found_tag && verify_tag && *dbp != ' ')
{
if (*dbp == '\0')
continue;
if (found_tag && verify_tag) // not external proc, so make tag
{
found_tag = FALSE;
verify_tag = FALSE;
makeDocBookTag(&tag);
continue;
}
}
if (get_tagname) /* grab name of proc or fn */
{
const unsigned char *cp;
if (*dbp == '\0') continue;
/* grab block name */
while (isspace((int) *dbp)) ++dbp;
while ((int) *dbp != 'i') ++dbp;
while ((int) *dbp != 'd') ++dbp;
while ((int) *dbp != '"') ++dbp;
++dbp;
for (cp = dbp ; *cp != '\0' && !endtoken(*cp); cp++) continue;
vStringNCopyS(name, (const char*) dbp, cp - dbp);
createDocBookTag(&tag, name, kind);
//printf("%s\n", name);
dbp = cp; /* set dbp to e-o-token */
get_tagname = FALSE;
found_tag = TRUE;
}
else if (!found_tag)
{
switch (tolower ((int) c))
{
case 's':
{
if (tail ("ection"))
{
get_tagname = TRUE;
kind = K_SECTION;
}
break;
}
case 'c':
{
if (tail ("hapter"))
{
get_tagname = TRUE;
kind = K_CHAPTER;
}
break;
}
} /* while not eof */
}
}
}
extern parserDefinition* DocBookParser (void)
{
static const char *const extensions [] = { "d", "docbook", NULL };
parserDefinition* def = parserNew ("Docbook");
def->extensions = extensions;
def->kinds = DocBookKinds;
def->kindCount = KIND_COUNT (DocBookKinds);
def->parser = findDocBookTags;
return def;
}
/* vi:set tabstop=8 shiftwidth=4: */

View File

@ -25,6 +25,7 @@
PythonParser, \
TexParser, \
ConfParser, \
DocBookParser, \
ShParser
#endif /* _PARSERS_H */

View File

@ -1,12 +1,15 @@
/*
*
* Copyright (c) 2005, Enrico Troeger
*
* 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 (la)tex files.
*/
* $Id$
*
* Copyright (c) 2000-2001, Jérôme Plût
* Copyright (c) 2006, Enrico Tröger
*
* 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 source files
* for the TeX formatting system.
*/
/*
* INCLUDE FILES
@ -14,6 +17,7 @@
#include "general.h" /* must always come first */
#include <ctype.h>
#include <string.h>
#include "parse.h"
#include "read.h"
@ -23,80 +27,176 @@
* DATA DEFINITIONS
*/
typedef enum {
K_KEYWORD
} texKind;
K_COMMAND,
K_ENVIRONMENT,
K_LABEL
} TeXKind;
static kindOption TexKinds [] = {
{ TRUE, 's', "symbol", "symbols"}
static kindOption TeXKinds[] = {
/* Commands - including \newcommand, \providecommand, \renewcommand,
* \def, \DeclareMathOperator. */
{ TRUE, 'c', "class", "command definitions" },
/* Environment - \newenvironment, \newtheorem */
{ TRUE, 'n', "namespace", "environment definitions" },
/* Labels - \label, \bibitem. */
{ TRUE, 't', "typedef", "labels and bibliography" }
};
#define TEX_BRACES (1<<0)
#define TEX_BSLASH (1<<1)
#define TEX_LABEL (1<<2)
/*
* FUNCTION DEFINITIONS
*/
static boolean isIdentifier (int c)
static int getWord (const char * ref, const unsigned char ** pointer)
{
return (boolean)(isalnum (c) || c == '\\');
const char * p = *pointer;
while ((*ref != '\0') && (*p != '\0') && (*ref == *p))
ref++, p++;
if (*ref)
return FALSE;
*pointer = p;
return TRUE;
}
static void findTexTags (void)
static void createTag (int flags, TeXKind kind, const char * l)
{
vString *name = vStringNew ();
while ((*l == ' '))
l++;
if (flags & (TEX_BRACES | TEX_LABEL))
{
if ((*(l++)) != '{')
goto no_tag;
}
if (flags & TEX_BSLASH)
{
if ((*(l++)) != '\\')
goto no_tag;
}
if (flags & TEX_LABEL)
{
do
{
vStringPut (name, (int) *l);
++l;
} while ((*l != '\0') && (*l != '}'));
vStringTerminate (name);
makeSimpleTag (name, TeXKinds, kind);
}
else if (isalpha ((int) *l) || *l == '@')
{
do
{
vStringPut (name, (int) *l);
++l;
} while (isalpha ((int) *l) || *l == '@');
vStringTerminate (name);
makeSimpleTag (name, TeXKinds, kind);
}
else
{
vStringPut (name, (int) *l);
vStringTerminate (name);
makeSimpleTag (name, TeXKinds, kind);
}
no_tag:
vStringDelete (name);
}
static void findTeXTags (void)
{
vString *name = vStringNew ();
const unsigned char *line;
while ((line = fileReadLine ()) != NULL)
{
const unsigned char* cp = line;
boolean possible = TRUE;
const unsigned char *cp = line;
//int escaped = 0;
while (isspace ((int) *cp))
++cp;
if (*cp == '#')
continue;
for (; *cp != '\0'; cp++)
{
if (*cp == '%')
break;
if (*cp == '\\')
{
cp++;
while (*cp != '\0')
{
/* We look for any sequence of identifier characters following
* either a white space or a colon and followed by either = or :=
*/
if (possible && isIdentifier ((int) *cp))
{
while (isIdentifier ((int) *cp))
{
vStringPut (name, (int) *cp);
++cp;
}
vStringTerminate (name);
while (isspace ((int) *cp))
++cp;
if ( *cp == ':')
++cp;
if ( *cp == '=')
makeSimpleTag (name, TexKinds, K_KEYWORD);
vStringClear (name);
}
else if (isspace ((int) *cp) || *cp == ':')
possible = TRUE;
else
possible = FALSE;
if (*cp != '\0')
++cp;
}
/* \newcommand{\command} */
if (getWord ("newcommand", &cp)
|| getWord ("providecommand", &cp)
|| getWord ("renewcommand", &cp)
)
{
createTag (TEX_BRACES|TEX_BSLASH, K_COMMAND, cp);
continue;
}
/* \DeclareMathOperator{\command} */
if (getWord ("DeclareMathOperator", &cp))
{
if (*cp == '*')
cp++;
createTag (TEX_BRACES|TEX_BSLASH, K_COMMAND, cp);
continue;
}
/* \def\command */
if (getWord ("def", &cp))
{
createTag (TEX_BSLASH, K_COMMAND, cp);
continue;
}
/* \newenvironment{name} */
if ( getWord ("newenvironment", &cp)
|| getWord ("newtheorem", &cp)
)
{
createTag (TEX_BRACES, K_ENVIRONMENT, cp);
continue;
}
/* \bibitem[label]{key} */
if (getWord ("bibitem", &cp))
{
while (*cp == ' ')
cp++;
if (*(cp++) != '[')
break;
while ((*cp != '\0') && (*cp != ']'))
cp++;
if (*(cp++) != ']')
break;
createTag (TEX_LABEL, K_LABEL, cp);
continue;
}
/* \label{key} */
if (getWord ("label", &cp))
{
createTag (TEX_LABEL, K_LABEL, cp);
continue;
}
}
}
}
vStringDelete (name);
}
extern parserDefinition* TexParser (void)
{
//static const char *const patterns [] = { "[Mm]akefile", NULL };
static const char *const extensions [] = { "tex", NULL };
parserDefinition* const def = parserNew ("Tex");
def->kinds = TexKinds;
def->kindCount = KIND_COUNT (TexKinds);
//def->patterns = patterns;
def->extensions = extensions;
def->parser = findTexTags;
return def;
static const char *const extensions [] = { "tex", "sty", "cls", NULL };
parserDefinition * def = parserNew ("Tex");
def->kinds = TeXKinds;
def->kindCount = KIND_COUNT (TeXKinds);
def->extensions = extensions;
def->parser = findTeXTags;
return def;
}
/* vi:set tabstop=8 shiftwidth=4: */