Coverage for src/lcdoc/call_flows/markdown.py: 21.38%

Shortcuts on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

89 statements  

1from inspect import getsource lp|features/lp/python/call_flow_logging/index.mdpytest

2 

3 

4class Mkdocs: lp|features/lp/python/call_flow_logging/index.mdpytest

5 details = ''' 

6 

7<details> 

8 <summary>%s</summary> 

9 

10%s 

11 

12</details> 

13 

14''' 

15 code_ = ''' 

16 

17```_code_ 

18%s 

19``` 

20 

21 ''' 

22 admon_ = ''' 

23 

24!!! %s "%s" 

25 

26%s  

27 

28 ''' 

29 admon_closed_ = admon_.replace('!!!', '???') lp|features/lp/python/call_flow_logging/index.mdpytest

30 admon_clsabl_ = admon_.replace('!!!', '???+') lp|features/lp/python/call_flow_logging/index.mdpytest

31 tab_ = ''' 

32=== "%s" 

33 

34%s 

35 

36 ''' 

37 js = code_.replace('_code_', 'js') lp|features/lp/python/call_flow_logging/index.mdpytest

38 py = code_.replace('_code_', 'python') lp|features/lp/python/call_flow_logging/index.mdpytest

39 

40 code = lambda which, body: Mkdocs.code_.replace('_code_', which) % body 40 ↛ exitline 40 didn't run the lambda on line 40lp|features/lp/python/call_flow_logging/index.mdpytest

41 tab = lambda title, cont, t=tab_: t % (title, indent(cont)) 41 ↛ exitline 41 didn't run the lambda on line 41lp|features/lp/python/call_flow_logging/index.mdpytest

42 admon = lambda title, cont, mode='note', widg=admon_: widg % ( 42 ↛ exitline 42 didn't run the lambda on line 42lp|features/lp/python/call_flow_logging/index.mdpytest

43 mode, 

44 title.replace('\n', ''), 

45 indent(cont), 

46 ) 

47 closed_admon = lambda *a, _=admon, __=admon_closed_, **kw: _(*a, widg=__, **kw) 47 ↛ exitline 47 didn't run the lambda on line 47lp|features/lp/python/call_flow_logging/index.mdpytest

48 clsabl_admon = lambda *a, _=admon, __=admon_clsabl_, **kw: _(*a, widg=__, **kw) 48 ↛ exitline 48 didn't run the lambda on line 48lp|features/lp/python/call_flow_logging/index.mdpytest

49 

50 

51def to_min_header_level(l, s): lp|features/lp/python/call_flow_logging/index.mdpytest

52 h = '\n' 

53 s = '\n' + s 

54 for k in range(1, l): 

55 h += '#' 

56 s = s.replace(h + ' ', ('\n' + '#' * l) + ' ') 

57 return s 

58 

59 

60indent = lambda s: ('\n' + s).replace('\n', '\n ')[1:] 60 ↛ exitline 60 didn't run the lambda on line 60lp|features/lp/python/call_flow_logging/index.mdpytest

61 

62 

63def header(s, level): lp|features/lp/python/call_flow_logging/index.mdpytest

64 return level * '#' + ' ' + s.strip() 

65 

66 

67def deindent( 67 ↛ exitline 67 didn't jump to the function exit

68 s, add_code_line_seps=False, dl=lambda l, ws: l[ws:] if l[:ws] == ' ' * ws else l 

69): 

70 # can handle first line not indentend as in docstrings starting after """ w/o line sep 

71 s = s or '' 

72 if not s.strip(): 

73 return s 

74 ls = s.splitlines() 

75 # first line might be special after like '''def foo''' 

76 # if indented though we use it: 

77 if len(ls) == 1: 

78 return ls[0].strip() 

79 if ls[0].startswith(' ') or ls[0][:4] in ('def ', 'clas'): 

80 i = 0 

81 else: 

82 for i in 1, 2, 3, 4: 

83 if i > len(ls) - 1: 

84 i = i - 1 

85 break 

86 if ls[i].lstrip(): 

87 break 

88 # len of indent to remove: 

89 ws = len(ls[i]) - len(ls[i].lstrip()) 

90 ls = [dl(l, ws) for l in ls] 

91 if add_code_line_seps: 

92 ls = line_sep_before_code(ls) 

93 return '\n'.join(ls).strip() 

94 

95 

96def line_sep_before_code(ls): lp|features/lp/python/call_flow_logging/index.mdpytest

97 """for markdown""" 

98 r, is_code = [], False 

99 for ln in ls: 

100 if not is_code: 

101 if ln.startswith(' '): 

102 r.append('') 

103 is_code = True 

104 else: 

105 if not ln.startswith(' '): 

106 is_code = False 

107 r.append(ln) 

108 return r 

109 

110 

111# ----------------------------------------------------- Create markdown from whole tree 

112def extract_docstr_head(docstr): lp|features/lp/python/call_flow_logging/index.mdpytest

113 """ 

114 Finding Docstrings 

115 

116 Example: The one of this func would be 'Finding Docstrings'  

117 """ 

118 s, rest = docstr.strip(), '' 

119 if not s: 

120 return '', '' 

121 l = s.splitlines() 

122 h = len(l[0]) < 80 and (len(l) < 2 or not l[1].strip()) 

123 if len(l[0]) < 80 and (len(l) < 2 or not l[1].strip()): 

124 rest = '\n'.join(l[1:]).strip() 

125 l0 = l[0] 

126 if l0.startswith('#'): 

127 # remove markdown: 

128 return l0.split(' ', 1)[1], rest 

129 return l0, rest 

130 # no docstring with header: 

131 return '', docstr 

132 

133 

134def obj_tree_to_markdown(obj, hir=1): lp|features/lp/python/call_flow_logging/index.mdpytest

135 """obj as created by auto_docs recurse_into""" 

136 T = Mkdocs 

137 r = [] 

138 add = r.append 

139 if 1: 

140 n = obj['name'] 

141 head, rest = extract_docstr_head(obj['doc']) 

142 add(header('`%s` %s' % (n, head), hir)) 

143 add(rest) 

144 src = obj['source'] 

145 src = T.code('python', src) 

146 add(Mkdocs.closed_admon('source', src)) 

147 cs, fs = obj.get('classes', ()), obj.get('funcs', ()) 

148 if cs: 

149 add(header('Classes', hir + 1)) 

150 obj_tree_to_markdown(cs[0], hir + 2) 

151 [add(obj_tree_to_markdown(c, hir + 2)) for c in cs] 

152 if fs: 

153 add(header('Functions', hir + 1)) 

154 [add(obj_tree_to_markdown(f, hir + 2)) for f in fs] 

155 

156 return '\n'.join(r)