diff --git a/ctags/Makefile.am b/ctags/Makefile.am index 3b4e191b..c941aa1e 100644 --- a/ctags/Makefile.am +++ b/ctags/Makefile.am @@ -14,6 +14,7 @@ parsers = \ parsers/asciidoc.c \ parsers/asm.c \ parsers/basic.c \ + parsers/bibtex.c \ parsers/c.c \ parsers/cobol.c \ parsers/iniconf.c \ diff --git a/ctags/main/parsers.h b/ctags/main/parsers.h index b261f80e..c90ebf70 100644 --- a/ctags/main/parsers.h +++ b/ctags/main/parsers.h @@ -24,6 +24,7 @@ PhpParser, \ PythonParser, \ TexParser, \ + BibParser, \ AsmParser, \ ConfParser, \ SqlParser, \ diff --git a/ctags/parsers/bibtex.c b/ctags/parsers/bibtex.c new file mode 100644 index 00000000..bb669788 --- /dev/null +++ b/ctags/parsers/bibtex.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2000-2001, Jérôme Plût + * Copyright (c) 2006, Enrico Tröger + * Copyright (c) 2019, Mirco Schönfeld + * + * 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 BibTex formatting system. + * https://en.wikipedia.org/wiki/BibTeX + */ + +/* +* INCLUDE FILES +*/ +#include "general.h" /* must always come first */ + +#include +#include + +#include "parse.h" +#include "read.h" +#include "vstring.h" +#include "routines.h" + +/* +* DATA DEFINITIONS +*/ +typedef enum { + K_ARTICLE, + K_BOOK, + K_PAPER, + K_THESIS, + K_OTHER +} BibKind; + +static kindDefinition BibKinds[] = { + { true, 'f', "function", "@article @inbook @incollection" }, + { true, 'c', "class", "@book @booklet @proceedings" }, + { true, 'm', "member", "@inproceedings @conference" }, + { true, 'v', "variable", "@phdthesis @mastersthesis" }, + { true, 's', "struct", "@manual @misc @techreport" } +}; + +/* +* FUNCTION DEFINITIONS +*/ +#define BIB_LABEL (1<<2) + +static int getBibWord(const char * ref, const char **ptr) +{ + const char *p = *ptr; + + while ((*ref != '\0') && (*p != '\0') && (*ref == *p)) + ref++, p++; + + + if (*ref) + return false; + + *ptr = p; + return true; +} + +static void createBibTag(int flags, BibKind kind, const char * l) +{ + vString *name = vStringNew (); + + while ((*l == ' ')) + l++; + if (flags & (BIB_LABEL)) + { + if (*l != '{') + goto no_tag; + l++; + + do + { + vStringPut(name, (int) *l); + ++l; + } while ((*l != '\0') && (*l != ',')); + if (name->buffer[0] != ',') + makeSimpleTag(name, kind); + } + else + { + vStringPut(name, (int) *l); + makeSimpleTag(name, kind); + } + +no_tag: + vStringDelete(name); +} + +static void findBibTags(void) +{ + const char *line; + + while ((line = (const char*)readLineFromInputFile()) != NULL) + { + const char *cp = line; + /*int escaped = 0;*/ + + for (; *cp != '\0'; cp++) + { + if (*cp == '%') + break; + if (*cp == '@') + { + cp++; + + if (getBibWord("article", &cp)) + { + createBibTag(BIB_LABEL, K_ARTICLE, cp); + continue; + }else if (getBibWord("inbook", &cp)) + { + createBibTag(BIB_LABEL, K_ARTICLE, cp); + continue; + }else if (getBibWord("incollection", &cp)) + { + createBibTag(BIB_LABEL, K_ARTICLE, cp); + continue; + }else if (getBibWord("book", &cp)) + { + createBibTag(BIB_LABEL, K_BOOK, cp); + continue; + }else if (getBibWord("booklet", &cp)) + { + createBibTag(BIB_LABEL, K_BOOK, cp); + continue; + }else if (getBibWord("proceedings", &cp)) + { + createBibTag(BIB_LABEL, K_BOOK, cp); + continue; + }else if (getBibWord("inproceedings", &cp)) + { + createBibTag(BIB_LABEL, K_PAPER, cp); + continue; + }else if (getBibWord("conference", &cp)) + { + createBibTag(BIB_LABEL, K_PAPER, cp); + continue; + }else if (getBibWord("phdthesis", &cp)) + { + createBibTag(BIB_LABEL, K_THESIS, cp); + continue; + }else if (getBibWord("mastersthesis", &cp)) + { + createBibTag(BIB_LABEL, K_THESIS, cp); + continue; + }else if (getBibWord("manual", &cp)) + { + createBibTag(BIB_LABEL, K_OTHER, cp); + continue; + }else if (getBibWord("misc", &cp)) + { + createBibTag(BIB_LABEL, K_OTHER, cp); + continue; + }else if (getBibWord("techreport", &cp)) + { + createBibTag(BIB_LABEL, K_OTHER, cp); + continue; + } + } + } + } +} + +extern parserDefinition* BibParser (void) +{ + static const char *const extensions [] = { "bib", NULL }; + parserDefinition * def = parserNew ("Bib"); + def->kindTable = BibKinds; + def->kindCount = ARRAY_SIZE (BibKinds); + def->extensions = extensions; + def->parser = findBibTags; + return def; +} diff --git a/data/filedefs/filetypes.bibtex b/data/filedefs/filetypes.bibtex new file mode 100644 index 00000000..def2ccc1 --- /dev/null +++ b/data/filedefs/filetypes.bibtex @@ -0,0 +1,51 @@ +# For complete documentation of this file, please see Geany's main documentation +[styling] +# Edit these in the colorscheme .conf file instead +default=default +command=keyword_1 +tag=tag +math=number_1 +comment=comment +# mappings below may need checking +tag2=tag +math2=number_1 +comment2=comment +verbatim=default +shortcmd=keyword_1 +special=keyword_2 +cmdopt=keyword_1 +error=error + +[keywords] +# all items must be in one line +primary=article + +[settings] +# default extension used when saving files +extension=bib + +# MIME type +mime_type=text/x-bibtex + +# single comments, like # in this file +comment_single=% +# multiline comments +#comment_open= +#comment_close= + +# set to false if a comment character/string should start at column 0 of a line, true uses any +# indentation of the line, e.g. setting to true causes the following on pressing CTRL+d + #command_example(); +# setting to false would generate this +# command_example(); +# This setting works only for single line comments +comment_use_indent=true + +# context action command (please see Geany's main documentation for details) +context_action_cmd= + +[indentation] +#width=4 +# 0 is spaces, 1 is tabs, 2 is tab & spaces +#type=1 + diff --git a/data/filetype_extensions.conf b/data/filetype_extensions.conf index 98150c94..b0bfef45 100644 --- a/data/filetype_extensions.conf +++ b/data/filetype_extensions.conf @@ -10,6 +10,7 @@ Arduino=*.ino;*.pde; Asciidoc=*.asciidoc;*.adoc; ASM=*.asm;*.asm51;*.a51;*.s;*.S;*.sx; Batch=*.bat;*.cmd;*.nt; +BibTeX=*.bib; CAML=*.ml;*.mli; C=*.c;*.xpm; C++=*.cpp;*.cxx;*.c++;*.cc;*.h;*.hpp;*.hxx;*.h++;*.hh;*.C;*.H; @@ -41,7 +42,7 @@ HTML=*.htm;*.html;*.shtml;*.hta;*.htd;*.htt;*.cfm;*.tpl; Java=*.java;*.jsp; Javascript=*.js; JSON=*.json; -LaTeX=*.tex;*.sty;*.idx;*.ltx;*.latex;*.aux;*.bib; +LaTeX=*.tex;*.sty;*.idx;*.ltx;*.latex;*.aux; Lisp=*.lisp; Lua=*.lua; Make=*.mak;*.mk;GNUmakefile;makefile;Makefile;makefile.*;Makefile.*; diff --git a/src/filetypes.c b/src/filetypes.c index dfcdc2b6..cdf1d269 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -160,6 +160,7 @@ static void init_builtin_filetypes(void) FT_INIT( SQL, SQL, "SQL", NULL, FILE, MISC ); FT_INIT( COBOL, COBOL, "COBOL", NULL, SOURCE_FILE, COMPILED ); FT_INIT( LATEX, LATEX, "LaTeX", NULL, SOURCE_FILE, MARKUP ); + FT_INIT( BIBTEX, BIBTEX, "BibTeX", NULL, SOURCE_FILE, MARKUP ); FT_INIT( VHDL, VHDL, "VHDL", NULL, SOURCE_FILE, COMPILED ); FT_INIT( VERILOG, VERILOG, "Verilog", NULL, SOURCE_FILE, COMPILED ); FT_INIT( DIFF, DIFF, "Diff", NULL, FILE, MISC ); diff --git a/src/filetypes.h b/src/filetypes.h index debd618d..1014697f 100644 --- a/src/filetypes.h +++ b/src/filetypes.h @@ -74,6 +74,7 @@ typedef enum GEANY_FILETYPES_VALA, GEANY_FILETYPES_PASCAL, GEANY_FILETYPES_LATEX, + GEANY_FILETYPES_BIBTEX, GEANY_FILETYPES_ASM, GEANY_FILETYPES_CONF, GEANY_FILETYPES_HAXE, diff --git a/src/symbols.c b/src/symbols.c index c4d017f1..4fcd2362 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -525,6 +525,17 @@ static void add_top_level_items(GeanyDocument *doc) NULL); break; } + case GEANY_FILETYPES_BIBTEX: + { + tag_list_add_groups(tag_store, + &(tv_iters.tag_function), _("Journal Articles"), ICON_NONE, + &(tv_iters.tag_class), _("Books & Conference Proceedings"), ICON_NONE, + &(tv_iters.tag_member), _("Conference Papers"), ICON_NONE, + &(tv_iters.tag_variable), _("Theses"), ICON_NONE, + &(tv_iters.tag_struct), _("Other"), ICON_NONE, + NULL); + break; + } case GEANY_FILETYPES_MATLAB: { tag_list_add_groups(tag_store, diff --git a/src/tagmanager/tm_parser.c b/src/tagmanager/tm_parser.c index c3fda335..174bc963 100644 --- a/src/tagmanager/tm_parser.c +++ b/src/tagmanager/tm_parser.c @@ -124,6 +124,13 @@ static TMParserMapEntry map_LATEX[] = { {'n', tm_tag_namespace_t}, {'s', tm_tag_struct_t}, }; +static TMParserMapEntry map_BIBTEX[] = { + {'f', tm_tag_function_t}, + {'c', tm_tag_class_t}, + {'m', tm_tag_member_t}, + {'v', tm_tag_variable_t}, + {'s', tm_tag_struct_t}, +}; static TMParserMapEntry map_ASM[] = { {'d', tm_tag_macro_t}, @@ -531,6 +538,7 @@ static TMParserMap parser_map[] = { MAP_ENTRY(PHP), MAP_ENTRY(PYTHON), MAP_ENTRY(LATEX), + MAP_ENTRY(BIBTEX), MAP_ENTRY(ASM), MAP_ENTRY(CONF), MAP_ENTRY(SQL), diff --git a/src/tagmanager/tm_parser.h b/src/tagmanager/tm_parser.h index db64a61f..8ff99c10 100644 --- a/src/tagmanager/tm_parser.h +++ b/src/tagmanager/tm_parser.h @@ -67,6 +67,7 @@ enum TM_PARSER_PHP, TM_PARSER_PYTHON, TM_PARSER_LATEX, + TM_PARSER_BIBTEX, TM_PARSER_ASM, TM_PARSER_CONF, TM_PARSER_SQL,