Highlight function names correctly.
[ibg.git] / tools / inform.py
1 """
2 Inform 6 syntax highlighting.
3
4 This is an ultra-minimal version compared to the standard Pygments Inform6
5 lexer, but is much more forgiving of syntax errors.  And it handles the
6 exclamation-inside-string case properly.
7 """
8
9 from pygments.lexer import RegexLexer
10 from pygments.token import (Text, Comment, Operator, Keyword, Name,
11                             String, Number, Punctuation, Token)
12
13 objects = ["Class", "Nearby", "Object"]
14
15 directives = ["Abbreviate", "Array", "Attribute", "Btrace", "Class",
16               "Constant", "Default", "Dictionary", "End", "Endif", "Etrace",
17               "Extend", "Fake_action", "Global", "Ifdef", "Iffalse",
18               "Ifndef", "Ifnot", "Iftrue", "Ifv3", "Ifv5", "Import",
19               "Include", "Link", "Listsymbols", "Listdict", "Listverbs",
20               "Lowstring", "Ltrace", "Message", "Nearby", "Nobtrace",
21               "Noetrace", "Noltrace", "Notrace", "Object", "Property",
22               "Release", "Replace", "Serial", "Statusline", "Stub",
23               "Switches", "System_file", "Trace", "Verb", "Version",
24               "Zcharacter"]
25
26 defining = ["[", "array", "attribute", "class", "constant", "fake_action",
27             "global", "lowstring", "nearby", "object", "property"]
28
29 attributes = ["absent", "animate", "clothing", "concealed", "container",
30               "door", "edible", "enterable", "female", "general", "light",
31               "lockable", "locked", "male", "moved", "neuter", "on", "open",
32               "openable", "pluralname", "proper", "scenery", "scored",
33               "static", "supporter", "switchable", "talkable", "transparent",
34               "visited", "workflag", "worn"]
35
36 properties = ["n_to", "s_to", "e_to", "w_to", "ne_to", "se_to", "nw_to",
37               "sw_to", "u_to", "d_to", "in_to", "out_to", "add_to_scope",
38               "after", "article", "articles", "before", "cant_go", "capacity",
39               "daemon", "describe", "description", "door_dir", "door_to",
40               "each_turn", "found_in", "grammar", "initial",
41               "inside_description", "invent", "life", "list_together",
42               "name", "number", "orders", "parse_name", "plural",
43               "react_after", "react_before", "short_name", "short_name_indef",
44               "time_left", "time_out", "when_closed", "when_open", "when_on",
45               "when_off", "with_key"]
46
47 extension_properties = ["pname"]
48
49 keywords = ["box", "break", "continue", "do", "else", "font",
50             "for", "give", "has", "hasnt", "if", "in", "inversion", "jump",
51             "move", "new_line", "notin", "objectloop", "ofclass", "or",
52             "print", "print_ret", "provides", "quit", "read", "remove",
53             "restore", "return", "rfalse", "rtrue", "save", "spaces",
54             "string", "style bold", "style fixed", "style reverse",
55             "style roman", "style underline", "switch", "to", "until",
56             "while", "with"]
57
58 constants = ["false", "true"]
59
60 def wordlist(list):
61     return "(" + "|".join(list) + r")\b"
62
63 class InformLexer(RegexLexer):
64     """
65     Inform code lexer.
66     """
67
68     name = 'Inform 6'
69     aliases = ['inform', 'inform6', 'i6']
70     filenames = ['*.inf']
71     mimetypes = ['text/x-inform', 'application/x-inform']
72
73     tokens = {
74         'root': [
75             (r'"', String.Double, 'string-double'),
76             (r"'", String.Single, 'string-single'),
77             (r"\[ *", Text, 'function-name'),
78
79             (r'\n', Text),
80             (r'[^\S\n]+', Text),
81             (r'!.*$', Comment.Single),
82             (r'\\\n', Text),
83             (r'\\', Text),
84             (r'=', Operator),
85             (r"[A-Za-z_,]+:", Name.Label),
86             (r"<.+?>", Name.Label),
87
88             (wordlist(objects), Name.Class),
89             (wordlist(keywords), Token.Keyword.Reserved),
90             (wordlist(properties), Name.Builtin),
91             (wordlist(directives), Name.Entity),
92             (wordlist(attributes), Name.Attribute),
93             (wordlist(constants), Name.Constant),
94
95             (wordlist(extension_properties), Name.Builtin),
96
97             (r'[a-zA-Z_][a-zA-Z0-9_.]*', Name),
98             (r'(\d+\.?\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
99             (r'\d+', Number.Integer),
100
101             (r'.', Punctuation),
102         ],
103
104         'function-name': [
105             (r"[ ;]", Text, '#pop'),
106             (r".", Name.Function),
107         ],
108
109         'string-double': [
110             (r'"', String.Double, '#pop'),
111             (r'.', String.Double),
112             (r'\n', String.Double),
113         ],
114
115         'string-single': [
116             (r"'", String.Single, '#pop'),
117             (r'.', String.Single),
118         ],
119     }