27 |
|
|
28 |
__docformat__ = 'reStructuredText' |
__docformat__ = 'reStructuredText' |
29 |
|
|
|
#from __future__ import nested_scopes |
|
|
import re, random, string |
|
|
|
|
|
import navidoc.mp, navidoc.link |
|
|
|
|
30 |
import config |
import config |
31 |
|
|
32 |
dbg = config.dbg.shorthand('parser') |
import mp, link |
33 |
|
from utils.parser import * |
|
element_types = {} |
|
|
link_types = {} |
|
|
|
|
|
def __init__(): |
|
|
""" |
|
|
Gather available elements and linktypes from modules. |
|
|
""" |
|
|
#XXX: Fix key-name conflicts |
|
|
element_types.update(keys4classes(navidoc.mp)) |
|
|
for module in dir(navidoc.mp): |
|
|
module = getattr(navidoc.mp, module) |
|
|
element_types.update(keys4classes(module)) |
|
|
|
|
|
link_types.update(keys4classes(navidoc.link)) |
|
|
for module in dir(navidoc.link): |
|
|
module = getattr(navidoc.link, module) |
|
|
link_types.update(keys4classes(module)) |
|
|
|
|
|
def keys4classes(module): |
|
|
""" |
|
|
Gather a key -> class dictionary for all classes containing |
|
|
'key' in sub modules under root module. |
|
|
""" |
|
|
d = {} |
|
|
for elements in dir(module): |
|
|
for element in elements: |
|
|
element = getattr(module, element) |
|
|
if hasattr(element, "key") \ |
|
|
and type(element.key) == type(''): |
|
|
d[element.key] = element |
|
|
return d |
|
|
|
|
|
class ParserException(Exception): |
|
|
def __init__(self, value): |
|
|
Exception.__init__() |
|
|
self.value = value |
|
|
def __str__(self): |
|
|
return self.value |
|
|
|
|
|
def match_remove(p, s): |
|
|
""" |
|
|
Match pattern p in s and remove the match, return (match, ns) |
|
|
""" |
|
|
m = re.match(p,s) |
|
|
if m: s = re.sub(p, "", s) |
|
|
return (m, s) |
|
|
|
|
|
def resolve_tabs(s): |
|
|
""" |
|
|
Transform tabs into spaces. Return the transformed string. |
|
|
""" |
|
|
return re.sub("\t", " ", s); |
|
34 |
|
|
35 |
def init_spaces(s): |
dbg = config.dbg.shorthand('parser') |
|
""" |
|
|
Strip whitespaces and calculates the amount of them in the |
|
|
beginning of the string. Return the amount and stripped |
|
|
string. |
|
|
""" |
|
|
n = len(re.match("^\s*", s).group()) |
|
|
return (n, s.strip()) |
|
36 |
|
|
37 |
def random_var(): |
class ElementFactor: |
|
""" |
|
|
Return a 20 random character string. |
|
|
""" |
|
|
l = len(string.letters) |
|
|
return "".join([ |
|
|
string.letters[random.randint(0, l-1)] |
|
|
for k in range(20)]) |
|
38 |
|
|
39 |
def parse_indented(s): |
element_types = {} |
40 |
""" |
link_types = {} |
|
Split the string into lines after "\n"s. Parse the string |
|
|
array into array tree after indentions in consecutive strings. |
|
|
Return the parsed array. |
|
|
""" |
|
|
stack = [(-1, [])] |
|
|
for r in s.split("\n") : |
|
|
if re.match("^\s*$", r): continue |
|
|
r = resolve_tabs(r) |
|
|
(n,x) = init_spaces(r) |
|
|
while n < stack[-1][0]: |
|
|
stack.pop() |
|
|
if n > stack[-1][0]: |
|
|
new = (n, [x]) |
|
|
stack[-1][1].append(new[1]) |
|
|
stack.append(new) |
|
|
else: # x == stack[-1][0]: |
|
|
new = (n, [x]) |
|
|
stack[-2][1].append(new[1]) |
|
|
stack.pop() |
|
|
stack.append(new) |
|
|
return stack[0][1] |
|
|
|
|
|
class Element: |
|
|
""" |
|
|
The general element for all subelements. |
|
|
""" |
|
|
def __init__(self, list): |
|
|
self.list = list |
|
41 |
|
|
42 |
class NamedElement (Element): |
def __init__(self): |
43 |
""" |
""" |
44 |
Element with name and linking features. |
Gather available elements and linktypes from modules. |
45 |
""" |
""" |
46 |
def do_contents(self, list): |
#XXX: Fix key-name conflicts |
47 |
for el in list: |
element_types.update(keys4classes(navidoc.mp)) |
48 |
self.handle_contained(el) |
for module in dir(navidoc.mp): |
49 |
dbg("Link: "+self.link) |
module = getattr(navidoc.mp, module) |
50 |
def handle_contained(self, el): |
if type(module) == type(navidoc.parser): |
51 |
if link_types.has_key(el[0]): |
print module |
52 |
link = el[1:] |
element_types.update(keys4classes(module)) |
53 |
if len(link): |
|
54 |
self.link = link_types[el[0]](link[0][0]) |
# link_types.update(keys4classes(navidoc.link)) |
55 |
else: |
# for module in dir(navidoc.link): |
56 |
self.link = self.defaultlink(link[0][0]) |
# module = getattr(navidoc.link, module) |
57 |
else: |
# link_types.update(keys4classes(module)) |
58 |
self.list.add_sub_element(self.name, el) |
|
59 |
def defaultlink(self, link): |
def keys4classes(self.module): |
60 |
return navidoc.link.Link(link) |
""" |
61 |
|
Gather a key -> class dictionary for all classes containing |
62 |
|
'key' in sub modules under root module. |
63 |
|
""" |
64 |
|
d = {} |
65 |
|
for element in dir(module): |
66 |
|
element = getattr(module, element) |
67 |
|
if type(element) == type(Element) \ |
68 |
|
and issubclass(element, Element): |
69 |
|
print element |
70 |
|
if hasattr(element, "key") \ |
71 |
|
and type(element.key) == type(''): |
72 |
|
d[element.key] = element |
73 |
|
return d |
74 |
|
|
75 |
class ElementList: |
class ElementList: |
76 |
""" |
""" |
134 |
code = "\n".join([element.draw_code() for element in self.list]) + "\n" |
code = "\n".join([element.draw_code() for element in self.list]) + "\n" |
135 |
return code |
return code |
136 |
|
|
137 |
|
class ParserException(Exception): |
138 |
|
def __init__(self, value): |
139 |
|
Exception.__init__() |
140 |
|
self.value = value |
141 |
|
def __str__(self): |
142 |
|
return self.value |
143 |
|
|