Caffe2 - Python API
A deep learning, cross platform ML framework
parser.py
1 ## @package parser
2 # Module caffe2.python.docs.parser
3 from __future__ import absolute_import
4 from __future__ import division
5 from __future__ import print_function
6 from __future__ import unicode_literals
7 import re
8 
9 
10 class Parser(object):
11  # List of tuples (regex_str, lambda(regex_match, formatter))
12  # If a lambda returns True it will be called repeatedly with replacement
13  # otherwise it will only be called on text that hasn't been parsed yet.
14  regexes = [
15  # Code blocks of various formats
16  ('````(.+?)````',
17  lambda m, f: f.addCode(m.group(1))
18  ),
19  ('```(.+?)```',
20  lambda m, f: f.addCode(m.group(1))
21  ),
22  (r'((( {2})+)(\S.*)(\n\s*\n|\n))+',
23  lambda m, f: f.addCode(m.group(0))
24  ),
25  (r'([^\.])\n',
26  lambda m, f: f.addRaw('{c} '.format(c=m.group(1))) or True
27  ),
28  ('`(.+?)`',
29  lambda m, f: f.addCode(m.group(1), True)
30  ),
31  # Make links clickable
32  ('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'
33  r'|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+',
34  lambda m, f: f.addLink(m.group(0), m.group(0))
35  ),
36  (r'\*\*(.+?)\*\*',
37  lambda m, f: f.addEmphasis(m.group(1), 2)
38  ),
39  (r'\*(.+?)\*',
40  lambda m, f: f.addEmphasis(m.group(1), 1)
41  ),
42  ]
43 
44  def __init__(self, text, formatter):
45  self.text = text
46  self.lines = []
47  self.formatter = formatter
48 
49  def parseText(self):
50  UNPARSED = 0
51  PARSED = 1
52  parsed_block = [(UNPARSED, self.text)]
53  for regex, func in self.regexes:
54  index = 0
55  while index < len(parsed_block):
56  label, text = parsed_block[index]
57 
58  # Already been parsed
59  if (label == PARSED):
60  index += 1
61  continue
62 
63  match = re.search(regex, text)
64  if match:
65  parsed_block.pop(index)
66  start = match.start(0)
67  end = match.end(0)
68 
69  f = self.formatter.clone()
70  merge = func(match, f)
71 
72  if merge:
73  merged = text[:start] + f.dump() + text[end:]
74  parsed_block.insert(index, (UNPARSED, merged))
75  else:
76  if text[:start]:
77  parsed_block.insert(index,
78  (UNPARSED, text[:start]))
79 
80  index += 1
81  parsed_block.insert(index, (PARSED, f.dump()))
82 
83  index += 1
84  if text[end:]:
85  parsed_block.insert(index,
86  (UNPARSED, text[end:]))
87 
88  else:
89  index += 1
90 
91  self.lines += [i for _, i in parsed_block]
92  self.text = ' '.join(self.lines)
93 
94  def parse(self):
95  self.parseText()
96  return self.text