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:
parent
9266f022d2
commit
46690c0b8f
@ -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
190
tagmanager/docbook.c
Normal 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: */
|
@ -25,6 +25,7 @@
|
||||
PythonParser, \
|
||||
TexParser, \
|
||||
ConfParser, \
|
||||
DocBookParser, \
|
||||
ShParser
|
||||
|
||||
#endif /* _PARSERS_H */
|
||||
|
222
tagmanager/tex.c
222
tagmanager/tex.c
@ -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: */
|
||||
|
Loading…
x
Reference in New Issue
Block a user