diff options
Diffstat (limited to 'Build/source/utils/xindy-new/xindy/tex2xindy/tex2xindy.l')
-rw-r--r-- | Build/source/utils/xindy-new/xindy/tex2xindy/tex2xindy.l | 511 |
1 files changed, 511 insertions, 0 deletions
diff --git a/Build/source/utils/xindy-new/xindy/tex2xindy/tex2xindy.l b/Build/source/utils/xindy-new/xindy/tex2xindy/tex2xindy.l new file mode 100644 index 00000000000..dc507aade62 --- /dev/null +++ b/Build/source/utils/xindy-new/xindy/tex2xindy/tex2xindy.l @@ -0,0 +1,511 @@ +%{ + /* $Id: tex2xindy.l,v 1.21 2006/07/30 09:44:04 jschrod Exp $ + ============================================================ + (history at end) + +=head1 NAME + +tex2xindy - a preprocessor of the xindy index processor + +=head1 SYNOPSIS + + tex2xindy [-o] [attr_file] + +=head1 DESCRIPTION + +B<tex2xindy> transforms a LaTeX index file C<.idx> (or an C<.aux> +file) into a B<xindy> raw index file. + +It is a filter that reads from F<stdin> a file in the input format of +LaTeX's raw index file, i.e., with C<\indexentry> tags. It outputs on +F<stdout> a B<xindy> raw index file, i.e., with C<indexentry> clauses. + +If the option B<-o> is not specified, B<tex2xindy> handles ^^-notation +of TeX and outputs the octet that is represented: C<^^ab> in the input +gets output as the octet 0xab. If C<^^^^abcd> or C<^^^^^^^^abcdefab> +are detected, they are output as is. + +If the option B<-o> is specified, B<tex2xindy> operates in I<Omega +mode> and handles its ^^-notation: Then C<^^ab>, C<^^^^abcd>, and +C<^^^^^^^^abcdefab> represent Unicode characters with code points +0xab, 0xabcd, and 0xabcdefab respectively. They are output in UTF-8 +encoding. + +If the optional argument F<attr_file> is specified, B<tex2xindy> +writes all index key attributes into this file. + + +=head1 DEFICITS + +This program was written since it was not easily possible to extract +the parser from the old makeindex system. Therefore it does not find +all errors in the input as the makeindex(1) version. + +Additionally it uses only the default input specifiers of +makeindex(1). If other input specifiers (cf. manual page of +makeindex(1)) are needed, the input specifiers (starting from the +pattern C<KEYWORD>, see below) must be changed and the program must be +recompiled. + +The particular missing feature is configuration of the quote and the +actual characters, maybe also the escape, subitem (level), and encap +characters. Argument and range delimiters seem to be less of a problem. + +In fact, input markup handling (and thus B<tex2xindy>) should be +incorporated into the B<xindy> kernel, to be able to specify +configuration in xindy style files. + +=head1 SEE ALSO + +texindy(1), +xindy(1), +makeindex(1) + +=head1 AUTHOR + +Roger Kehr, Institut fuer Theoretische Informatik, TU Darmstadt + +=head1 COPYRIGHT AND LICENSE + +Copyright (c) 1996,1997 Roger Kehr. +Copyright (c) 2006 Joachim Schrod. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +=cut + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#define QUOTE_ECHO qs(yytext) + +FILE* attrfd = NULL; + +static int lineno = 1; +static int braces = 0; +static int xref_mode = 0; +static int glos_mode = 0; +static int errors = 0; +static int omega_mode = 0; + +#define multiple_err \ + { \ + fprintf(stderr, "line %d: multiple %s's\n", lineno, yytext); \ + errors++; \ + } + +#define NO_RANGE 0 +#define OPEN_RANGE 1 +#define CLOSE_RANGE 2 + +int range = NO_RANGE; + +/* This function quotes a character, if necessary. */ + +static void qc( char ch ) { + switch (ch) { + case '\\' : + case '"' : + putchar( '\\' ); + break; + } + putchar(ch); +} + +/* Quote an entire string. */ + +static void qs( const char* str ) { + while ( *str ) { + qc( *str++ ); + } +} + +/* + Output an Omega character, ^^-notation in yytext, in UTF-8 encoding. + The parameter gets passed the amount of hex digits in the ^^-notation. + In front of the hex digits are the same amount of ^ chars. +*/ +static void omega_output_utf8 ( int width ) +{ + unsigned long int c = strtoul (yytext+width, NULL, 16); + if (c < 0x80) { + putchar (c); + } + else if (c < 0x800) { + putchar (0xC0 | (c>>6)); + putchar (0x80 | (c & 0x3F)); + } + else if (c < 0x10000) { + putchar (0xE0 | (c>>12)); + putchar (0x80 | (c>>6 & 0x3F)); + putchar (0x80 | (c & 0x3F)); + } + else if (c < 0x200000) { + putchar (0xF0 | (c>>18)); + putchar (0x80 | (c>>12 & 0x3F)); + putchar (0x80 | (c>>6 & 0x3F)); + putchar (0x80 | (c & 0x3F)); + } + else if (c < 0x4000000) { + putchar (0xF8 | (c>>24)); + putchar (0x80 | (c>>18 & 0x3F)); + putchar (0x80 | (c>>12 & 0x3F)); + putchar (0x80 | (c>>6 & 0x3F)); + putchar (0x80 | (c & 0x3F)); + } + else if (c < 0x80000000) { + putchar (0xFC | (c>>30)); + putchar (0x80 | (c>>24 & 0x3F)); + putchar (0x80 | (c>>18 & 0x3F)); + putchar (0x80 | (c>>12 & 0x3F)); + putchar (0x80 | (c>>6 & 0x3F)); + putchar (0x80 | (c & 0x3F)); + } + else { /* out of range, output U+FFFD REPLACEMENT CHARACTER */ + fputs("\xef\xbf\xbd",stdout); + fprintf (stderr, "line %d: character %#lx not in UTF-8 range\n", + lineno, c); + } +} + +%} + +KEYWORD \\indexentry +KEYWORDG \\glossaryentry +ENCAP \| +ACTUAL @ +ESCAPE \\ +LEVEL ! +IS : +QUOTE \" +ROPEN \( +RCLOSE \) +ARGOPEN \{ +ARGCLOSE \} + +HATHAT8BIT \^{2}[0-9a-fA-F]{2} +HATHAT16BIT \^{4}[0-9a-fA-F]{4} +HATHAT32BIT \^{8}[0-9a-fA-F]{8} + +%s key print skip2location location encap xref is skiplocation + +%% + +<INITIAL>{KEYWORD}[ \t]*{ARGOPEN} { + printf("(indexentry :tkey ((\""); + xref_mode = 0; + glos_mode = 0; + BEGIN(key); + } + +<INITIAL>{KEYWORDG}[ \t]*{ARGOPEN} { + printf("(indexentry :tkey ((\""); + xref_mode = 0; + glos_mode = 1; + BEGIN(key); + } + +{ESCAPE}{QUOTE} { QUOTE_ECHO; } +{QUOTE}\n { qc(yytext[1]); lineno++; } +{QUOTE}. { qc(yytext[1]); } +<key,print>{ENCAP} { + printf("\")) :attr \""); + range = NO_RANGE; + BEGIN(encap); + } +<key,print>{IS} { + if ( glos_mode ) { + printf("\")) :attr \"is\" :xref (\""); + range = NO_RANGE; + if (attrfd) fprintf(attrfd, "\txref\n"); + BEGIN(is); + } else { + ECHO; + } + } +<key>{LEVEL} { printf("\") (\""); } +<print>{LEVEL} { printf("\") (\""); BEGIN(key); } +<key,print>{ARGOPEN} { ECHO; braces++; } +<key,print>{ARGCLOSE} { + if ( braces > 0 ) { + ECHO; + braces--; + } else { + printf("\"))"); + BEGIN(skip2location); + } + } + +<key>{ACTUAL} { printf("\" \""); BEGIN(print); } +<print>{ACTUAL} { multiple_err; } + +<encap>{ENCAP} { multiple_err; } +<encap>{ROPEN} { range = OPEN_RANGE; } +<encap>{RCLOSE} { range = CLOSE_RANGE; } +<encap>{ARGOPEN} { /* close :attr "... */ + printf("\" :xref (\""); + if (attrfd) fprintf(attrfd, "\txref\n"); + braces++; + BEGIN(xref); + } +<encap>{ARGCLOSE} { + if ( braces > 0 ) { + ECHO; + braces--; + } else { + putchar('"'); + if (attrfd) fprintf(attrfd, "\tlocref\n"); + switch (range) { + case OPEN_RANGE: + printf(" :open-range"); + break; + case CLOSE_RANGE: + printf(" :close-range"); + break; + } + BEGIN(skip2location); + } + } +<encap>.|\n { + QUOTE_ECHO; + if (attrfd) fwrite(yytext, sizeof(char), 1, attrfd); + if (*yytext == '\n') lineno++; + } + + + +<xref>{LEVEL} { printf("\" \""); } +<xref,is>{ARGOPEN} { ECHO; braces++; } +<xref>{ARGCLOSE} { + if ( braces > 1 ) { + ECHO; + braces--; + } else if ( braces == 1 ) { + braces--; + } else { + printf("\")"); + xref_mode = 1; + BEGIN(skip2location); + } + } +<is>{ARGCLOSE} { + if ( braces > 0 ) { + ECHO; + braces--; + } else { + printf("\")"); + xref_mode = 1; + BEGIN(skip2location); + } + } + +<skip2location>[ \t]*{ARGOPEN} { + if (xref_mode) { + BEGIN(skiplocation); + } else { + printf(" :locref \""); + BEGIN(location); + } + } +<location>{ARGCLOSE} { printf("\")\n"); BEGIN(0); } + +<skiplocation>{ARGCLOSE} { printf(")\n"); BEGIN(0); } +<skiplocation>. { ; } + +<key,print,xref,is,location>{HATHAT8BIT} { + if ( omega_mode ) { + omega_output_utf8(2); + } else { + unput( strtol(yytext+2, NULL, 16) ); + } + } +<key,print,xref,is,location>{HATHAT16BIT} { + if ( omega_mode ) { + omega_output_utf8(4); + } else { + ECHO; + } + } +<key,print,xref,is,location>{HATHAT32BIT} { + if ( omega_mode ) { + omega_output_utf8(8); + } else { + ECHO; + } + } + +<key,print,xref,is,location>\n { ECHO; lineno++; } +<key,print,xref,is,location>. { QUOTE_ECHO; } + +\n { lineno++; } +[ \t] { ; } +. { + fprintf(stderr, + "Encountered unexpected char '%c' on line %d\n", + yytext[0], lineno); + } + +%% + +/* + * Define dummy yywrap so we no longer depend on `libfl.a'. + */ +int yywrap (void) +{ + return 1; +} + +static void usage (void) +{ + fputs("This is tex2xindy, $Revision: 1.21 $.\n", stderr); + fputs("usage: tex2xindy [-o] [attr_file]\n", stderr); + exit (1); +} + +int +main(int argc, char* argv[]) +{ + int option; + extern char *optarg; + extern int optind, optopt; + + while ( (option=getopt(argc, argv, ":o")) != -1 ) { + switch (option) { + case 'o': + omega_mode = 1; + break; + case '?': + default: + fprintf(stderr, "Unrecognized option: -%c\n", optopt); + usage(); + /* NOTREACHED */ + } + } + + /* More than one argument left? */ + if ( optind < argc - 1 ) usage(); + + /* attr_file specified? */ + if ( optind == argc - 1 ) { + fprintf(stderr, "Writing attribute names to file \"%s\".\n", + argv[optind]); + if ( (attrfd = fopen(argv[optind], "w")) == NULL ) { + perror (argv[optind]); + exit (1); + } + } + + yylex(); + if (attrfd) fclose(attrfd); + return (errors > 0); /* 1 or 0 */ +} + + +/* ============================================================ + + $Log: tex2xindy.l,v $ + Revision 1.21 2006/07/30 09:44:04 jschrod + While quote is not output, escape+quote *is* output. + + Revision 1.20 2006/07/18 21:40:45 jschrod + Add parenthesis as recommended by gcc -Wall. + Use ECHO instead of QUOTE_ECHO where quoting will not be needed. + Code cleanup: sanitize braces and indentation. + + Revision 1.19 2006/07/18 21:26:34 jschrod + Add man page as POD to tex2xindy source. + Add support for ^^-notation, both in TeX and in new Omega mode. + Add usage message and proper option parsing. + + Revision 1.18 2006/02/21 12:12:05 jschrod + Don't output escape or quote characters. + + Revision 1.17 2006/02/21 02:05:00 jschrod + Quote really quotes the next char, now. + + Revision 1.16 2005/06/27 20:49:06 jschrod + Keywords may be inmidst a line, as Jörg Sommer showed. + "." rule merging did not work for attributes, and for skiplocation. + Output error message if we come across chars outside our FSA. + + Revision 1.15 2005/06/14 16:22:08 jschrod + Fold in changes from Thomas Henlich, as of 2000-02-14: + Paranoia fix: recognize KEYWORD only in INITIAL start condition. + Recognize \n and count lines (multiline entries do exist!). + Merged "." rules. + Fixed error messages (multiple ...). + + Revision 1.14 2004/10/05 21:10:48 jschrod + Handles quote character correctly (bug ticket 1006128). + Test case: german-sty. + + Revision 1.13 2002/01/29 13:32:58 thenlich + Fixed bug in crossref-to-subitem bugfix. The original one proposed by Roger Kehr + was right, only I copied it wrongly (shame on me). Thanks to Torsten Bronger + for pointing it out to me. + + Revision 1.12 1999/10/13 08:06:44 kehr + Changed revision number message back to RCS-tag. No functional changes. + + Revision 1.11 1999/10/13 08:05:10 kehr + Merged bugfix from Thomas Henlich with my own modifications. + + 1.8 Fixed minor quoting bugs (for increased makeindex compatibility). + 1999-07-28 Thomas Henlich <henlich@mmers1.mw.tu-dresden.de> + Fixed crossref to subitem. + 1999-09-23 Thomas Henlich <henlich@mmers1.mw.tu-dresden.de> + + 1.7 Fixed a bug concerning writing to and closing non-existing file (stat) + Fixed a bug concerning quoting the " character. + Enhancement for processing glossary files. + 1999-06-14 Thomas Henlich <henlich@mmers1.mw.tu-dresden.de> + + Revision 1.10 1999/09/23 06:53:32 kehr + Fixed wrong raw index generation for cross-ref keywords. + + Revision 1.9 1999/04/27 09:01:17 kehr + Defined a clean exit code as suggested by Klaus Guntermann + <guntermann@iti.informatik.tu-darmstadt.de>. + + Revision 1.8 1999/04/27 08:57:48 kehr + Added quoting patch sent by Thomas Henlich <thenlich@Rcs1.urz.tu-dresden.de> + + Revision 1.7 1999/04/27 08:56:59 kehr + Another checkin. + + Revision 1.6 1997/02/13 14:42:50 kehr + Minor changes. + + Revision 1.5 1997/01/21 16:44:36 kehr + Bugfix: State <print> was not changed back to <key> if {LEVEL} was found. + + Revision 1.4 1997/01/17 16:30:37 kehr + Rewrote makeindex4 and heavily modified tex2xindy. + + Revision 1.3 1996/07/19 17:15:18 kehr + Made this program comaptible with lex by correctly enclosing all + actions--stupid bug, 'cause lex didn't complain and flex did some + wonderful matching of all the actions such that no error was + discovered. + + Revision 1.2 1996/07/11 14:16:55 kehr + Complete Major checkin before changing the letter-groups. + + Revision 1.1 1996/06/24 08:53:57 kehr + Initial checkin of the Makefile, README and tex2xindy. +*/ |