OTWO-1213 Works around lost encoding in Ruby/C binding layer
[ohcount] / src / parsers / tex.rl
1 // tex.rl written by Mitchell Foral. mitchell<att>caladbolg<dott>net.
2
3 /************************* Required for every parser *************************/
4 #ifndef OHCOUNT_TEX_PARSER_H
5 #define OHCOUNT_TEX_PARSER_H
6
7 #include "../parser_macros.h"
8
9 // the name of the language
10 const char *TEX_LANG = LANG_TEX;
11
12 // the languages entities
13 const char *tex_entities[] = {
14   "space", "comment", "string", "any"
15 };
16
17 // constants associated with the entities
18 enum {
19   TEX_SPACE = 0, TEX_COMMENT, TEX_STRING, TEX_ANY
20 };
21
22 /*****************************************************************************/
23
24 %%{
25   machine tex;
26   write data;
27   include common "common.rl";
28
29   # Line counting machine
30
31   action tex_ccallback {
32     switch(entity) {
33     case TEX_SPACE:
34       ls
35       break;
36     case TEX_ANY:
37       code
38       break;
39     case INTERNAL_NL:
40       std_internal_newline(TEX_LANG)
41       break;
42     case NEWLINE:
43       std_newline(TEX_LANG)
44     }
45   }
46
47   tex_comment = '%' @comment nonnewline*;
48
49   tex_line := |*
50     spaces       ${ entity = TEX_SPACE; } => tex_ccallback;
51     tex_comment;
52     newline      ${ entity = NEWLINE;   } => tex_ccallback;
53     ^space       ${ entity = TEX_ANY;   } => tex_ccallback;
54   *|;
55
56   # Entity machine
57
58   action tex_ecallback {
59     callback(TEX_LANG, tex_entities[entity], cint(ts), cint(te), userdata);
60   }
61
62   tex_comment_entity = '%' nonnewline*;
63
64   tex_entity := |*
65     space+             ${ entity = TEX_SPACE;   } => tex_ecallback;
66     tex_comment_entity ${ entity = TEX_COMMENT; } => tex_ecallback;
67     # TODO:
68     ^space;
69   *|;
70 }%%
71
72 /************************* Required for every parser *************************/
73
74 /* Parses a string buffer with Tex markup.
75  *
76  * @param *buffer The string to parse.
77  * @param length The length of the string to parse.
78  * @param count Integer flag specifying whether or not to count lines. If yes,
79  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
80  *   machine optimized for returning entity positions.
81  * @param *callback Callback function. If count is set, callback is called for
82  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
83  *   'lblank' respectively. Otherwise callback is called for each entity found.
84  */
85 void parse_tex(char *buffer, int length, int count,
86                void (*callback) (const char *lang, const char *entity, int s,
87                                  int e, void *udata),
88                void *userdata
89   ) {
90   init
91
92   %% write init;
93   cs = (count) ? tex_en_tex_line : tex_en_tex_entity;
94   %% write exec;
95
96   // if no newline at EOF; callback contents of last line
97   if (count) { process_last_line(TEX_LANG) }
98 }
99
100 #endif
101
102 /*****************************************************************************/