|
1 # -*- coding: utf-8 -*- |
|
2 """ |
|
3 pygments.lexers.bibtex |
|
4 ~~~~~~~~~~~~~~~~~~~~~~ |
|
5 |
|
6 Lexers for BibTeX bibliography data and styles |
|
7 |
|
8 :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS. |
|
9 :license: BSD, see LICENSE for details. |
|
10 """ |
|
11 |
|
12 import re |
|
13 |
|
14 from pygments.lexer import RegexLexer, ExtendedRegexLexer, include, default, \ |
|
15 words |
|
16 from pygments.token import Name, Comment, String, Error, Number, Text, \ |
|
17 Keyword, Punctuation |
|
18 |
|
19 __all__ = ['BibTeXLexer', 'BSTLexer'] |
|
20 |
|
21 |
|
22 class BibTeXLexer(ExtendedRegexLexer): |
|
23 """ |
|
24 A lexer for BibTeX bibliography data format. |
|
25 |
|
26 .. versionadded:: 2.2 |
|
27 """ |
|
28 |
|
29 name = 'BibTeX' |
|
30 aliases = ['bib', 'bibtex'] |
|
31 filenames = ['*.bib'] |
|
32 mimetypes = ["text/x-bibtex"] |
|
33 flags = re.IGNORECASE |
|
34 |
|
35 ALLOWED_CHARS = r'@!$&*+\-./:;<>?\[\\\]^`|~' |
|
36 IDENTIFIER = '[{0}][{1}]*'.format('a-z_' + ALLOWED_CHARS, r'\w' + ALLOWED_CHARS) |
|
37 |
|
38 def open_brace_callback(self, match, ctx): |
|
39 opening_brace = match.group() |
|
40 ctx.opening_brace = opening_brace |
|
41 yield match.start(), Punctuation, opening_brace |
|
42 ctx.pos = match.end() |
|
43 |
|
44 def close_brace_callback(self, match, ctx): |
|
45 closing_brace = match.group() |
|
46 if ( |
|
47 ctx.opening_brace == '{' and closing_brace != '}' or |
|
48 ctx.opening_brace == '(' and closing_brace != ')' |
|
49 ): |
|
50 yield match.start(), Error, closing_brace |
|
51 else: |
|
52 yield match.start(), Punctuation, closing_brace |
|
53 del ctx.opening_brace |
|
54 ctx.pos = match.end() |
|
55 |
|
56 tokens = { |
|
57 'root': [ |
|
58 include('whitespace'), |
|
59 ('@comment', Comment), |
|
60 ('@preamble', Name.Class, ('closing-brace', 'value', 'opening-brace')), |
|
61 ('@string', Name.Class, ('closing-brace', 'field', 'opening-brace')), |
|
62 ('@' + IDENTIFIER, Name.Class, |
|
63 ('closing-brace', 'command-body', 'opening-brace')), |
|
64 ('.+', Comment), |
|
65 ], |
|
66 'opening-brace': [ |
|
67 include('whitespace'), |
|
68 (r'[{(]', open_brace_callback, '#pop'), |
|
69 ], |
|
70 'closing-brace': [ |
|
71 include('whitespace'), |
|
72 (r'[})]', close_brace_callback, '#pop'), |
|
73 ], |
|
74 'command-body': [ |
|
75 include('whitespace'), |
|
76 (r'[^\s\,\}]+', Name.Label, ('#pop', 'fields')), |
|
77 ], |
|
78 'fields': [ |
|
79 include('whitespace'), |
|
80 (',', Punctuation, 'field'), |
|
81 default('#pop'), |
|
82 ], |
|
83 'field': [ |
|
84 include('whitespace'), |
|
85 (IDENTIFIER, Name.Attribute, ('value', '=')), |
|
86 default('#pop'), |
|
87 ], |
|
88 '=': [ |
|
89 include('whitespace'), |
|
90 ('=', Punctuation, '#pop'), |
|
91 ], |
|
92 'value': [ |
|
93 include('whitespace'), |
|
94 (IDENTIFIER, Name.Variable), |
|
95 ('"', String, 'quoted-string'), |
|
96 (r'\{', String, 'braced-string'), |
|
97 (r'[\d]+', Number), |
|
98 ('#', Punctuation), |
|
99 default('#pop'), |
|
100 ], |
|
101 'quoted-string': [ |
|
102 (r'\{', String, 'braced-string'), |
|
103 ('"', String, '#pop'), |
|
104 ('[^\{\"]+', String), |
|
105 ], |
|
106 'braced-string': [ |
|
107 (r'\{', String, '#push'), |
|
108 (r'\}', String, '#pop'), |
|
109 ('[^\{\}]+', String), |
|
110 ], |
|
111 'whitespace': [ |
|
112 (r'\s+', Text), |
|
113 ], |
|
114 } |
|
115 |
|
116 |
|
117 class BSTLexer(RegexLexer): |
|
118 """ |
|
119 A lexer for BibTeX bibliography styles. |
|
120 |
|
121 .. versionadded:: 2.2 |
|
122 """ |
|
123 |
|
124 name = 'BST' |
|
125 aliases = ['bst', 'bst-pybtex'] |
|
126 filenames = ['*.bst'] |
|
127 flags = re.IGNORECASE | re.MULTILINE |
|
128 |
|
129 tokens = { |
|
130 'root': [ |
|
131 include('whitespace'), |
|
132 (words(['read', 'sort']), Keyword), |
|
133 (words(['execute', 'integers', 'iterate', 'reverse', 'strings']), |
|
134 Keyword, ('group')), |
|
135 (words(['function', 'macro']), Keyword, ('group', 'group')), |
|
136 (words(['entry']), Keyword, ('group', 'group', 'group')), |
|
137 ], |
|
138 'group': [ |
|
139 include('whitespace'), |
|
140 (r'\{', Punctuation, ('#pop', 'group-end', 'body')), |
|
141 ], |
|
142 'group-end': [ |
|
143 include('whitespace'), |
|
144 (r'\}', Punctuation, '#pop'), |
|
145 ], |
|
146 'body': [ |
|
147 include('whitespace'), |
|
148 (r"\'[^#\"\{\}\s]+", Name.Function), |
|
149 (r'[^#\"\{\}\s]+\$', Name.Builtin), |
|
150 (r'[^#\"\{\}\s]+', Name.Variable), |
|
151 (r'"[^\"]*"', String), |
|
152 (r'#-?\d+', Number), |
|
153 (r'\{', Punctuation, ('group-end', 'body')), |
|
154 default('#pop'), |
|
155 ], |
|
156 'whitespace': [ |
|
157 ('\s+', Text), |
|
158 ('%.*?$', Comment.SingleLine), |
|
159 ], |
|
160 } |