Coverage for src/lcdoc/mkdocs/find_pages/__init__.py: 86.00%

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

127 statements  

1""" 

2## Find Pages 

3 

4Adds pages to nav 

5""" 

6 

7import string lp

8import time lp

9from ast import literal_eval lp

10from functools import partial lp

11 

12from lcdoc.mkdocs.tools import MDPlugin, app, config_options, find_md_files lp

13from lcdoc.tools import dirname, exists, OD, unflatten, flatten, os, project, read_file lp

14from lcdoc.mkdocs.find_pages.autodocs import autodocs, find_pages lp

15 

16 

17def repl_src_refs(s): lp

18 if not s.startswith(':srcref:'): lp

19 return s lp

20 s = s.split(',t=', 1) lp

21 if len(s) == 1: 21 ↛ 22line 21 didn't jump to line 22, because the condition on line 21 was never truelp

22 return '' 

23 return s[-1].split(',', 1)[0] lp

24 

25 

26def uppercase_words(s): lp

27 """titles in nav should only contain the strings, not e.g. links 

28 

29 s: "Local LP Blocks :srcref:fn=src/lcdoc/mkdocs/lp/plugs/python/pyplugs/lprunner/__init__.py,t=Runner" 

30 

31 """ 

32 L = [repl_src_refs(i) for i in s.split(' ')] lp

33 r = [] lp

34 for l in L: lp

35 if l and l[0] == l[0].upper() and l[0] in string.ascii_letters: lp

36 r.append(l) lp

37 return ' '.join(r) lp

38 

39 

40def is_after(fn, hfn): lp

41 

42 breakpoint() # FIXME BREAKPOINT 

43 

44 

45def get_insert_pos(fn, have): lp

46 """when "after" is not given we have to find out ourselves""" 

47 while fn: 47 ↛ exitline 47 didn't return from function 'get_insert_pos', because the condition on line 47 was never falselp

48 fn, post = fn.rsplit('/', 1) lp

49 for i in range(len(have)): lp

50 if not have[i].startswith(fn): lp

51 continue lp

52 while ( lp

53 (i < len(have) - 1) 

54 and have[i] < (fn + '/' + post) 

55 and have[i].startswith(fn) 

56 ): 

57 i += 1 lp

58 return have[i - 1], have[i] lp

59 

60 

61# get_insert_pos( './features', ['index.md', 'install.md', 'features/index.md', 'features/blacklist/index.md'],) 

62now = time.time lp

63 

64 

65def clear_digits(t): lp

66 return '.'.join([k for k in t.split('.') if not k.isdigit()]) lp

67 

68 

69def get_title(fn_page, dd): lp

70 # TODO: find the mkdocs way of deriving the title from the header within content 

71 s = read_file(dd + '/' + fn_page, dflt='') lp

72 h = '\n' + s + '\n# Found\n' # so that we find *something* when there is no head lp

73 tit = '' lp

74 # find the highest header, could be also "### My Title" 

75 for k in range(5, 0, -1): lp

76 head = '\n' + k * '#' + ' ' # "\n#### " for k = 3 lp

77 _ = h.split(head) lp

78 if len(_) == 1: lp

79 continue lp

80 h = _[0] # the content above, is there a higher header? lp

81 tit = _[1].split('\n', 1)[0] lp

82 if not tit: 82 ↛ 83line 82 didn't jump to line 83, because the condition on line 82 was never truelp

83 tit = fn_page 

84 h = uppercase_words(tit) lp

85 if not h: lp

86 # e.g. # `bash` alone has no uppercase word. then take the filename: 

87 l = fn_page.rsplit('/', 2) lp

88 if l[-1] == 'index.md': 88 ↛ 91line 88 didn't jump to line 91, because the condition on line 88 was never falselp

89 h = l[-2] lp

90 else: 

91 h = fn_page.rsplit('/', 1)[-1].split('.', 1)[0] 

92 return h lp

93 

94 

95def find_pages_and_add_to_nav(find, config, stats): lp

96 found = find_pages(find, config, stats) lp

97 if not found: 97 ↛ 98line 97 didn't jump to line 98, because the condition on line 97 was never truelp

98 return 

99 

100 # m = OD({p: None for p in found}) 

101 nav = config['nav'] lp

102 navl = flatten(nav, '.') lp

103 navll = [[fn, k] for k, fn in navl.items()] lp

104 have = [fn[0] for fn in navll] lp

105 ins = {} lp

106 for spec in found: lp

107 while spec['found']: lp

108 fn = spec['found'].pop(0) lp

109 if fn in have: lp

110 continue lp

111 aft = spec.get('after') lp

112 if not aft: 112 ↛ 114line 112 didn't jump to line 114, because the condition on line 112 was never falselp

113 aft, _ = get_insert_pos(fn, have) lp

114 ins.setdefault(have.index(aft), []).insert(0, fn) lp

115 l = {} lp

116 for k in reversed(sorted([i for i in ins])): lp

117 fns = ins[k] lp

118 [have.insert(k + 1, fn) for fn in fns] lp

119 l[have[k]] = fns lp

120 app.info('Inserting %s pages into nav' % sum([len(i) for i in ins.values()]), json=l) lp

121 # have now the complete list with found ones inserted at right places 

122 # 'features/lp/python/_tech.md', 

123 # 'features/lp/python/data_table/index.md', 

124 navl_rev = {v: k for k, v in navl.items()} lp

125 r = OD() lp

126 

127 dd = config['docs_dir'] lp

128 

129 to = None lp

130 for h in have: lp

131 tit = navl_rev.get(h) lp

132 if not tit: lp

133 t = to.rsplit('.', 2) lp

134 try: lp

135 T = get_title(h, dd) lp

136 if t[-1].isdigit(): 136 ↛ 137line 136 didn't jump to line 137, because the condition on line 136 was never truelp

137 tit = '.'.join((t[0], t[1], str(int(t[2]) + 1), T)) 

138 else: 

139 tit = '.'.join((t[0], str(int(t[-2]) + 1), T)) lp

140 except Exception as ex: 

141 hint = 'Your filenames in that folder must match mkdocs config' 

142 msg = 'Cannot find position or title for page' 

143 app.error(msg, page=h, to=to, hint=hint) 

144 raise 

145 r[tit] = h lp

146 to = tit lp

147 

148 n = OD() lp

149 for k, v in r.items(): lp

150 n[clear_digits(k)] = v lp

151 

152 r = unflatten(n, '.') lp

153 r = to_list(r) lp

154 config['nav'].clear() lp

155 config['nav'].extend(r) lp

156 

157 

158def to_list(d): lp

159 l = [] lp

160 for k, v in d.items(): lp

161 if k == None: # inserted by unflatten, when there was no title lp

162 l.append(v) lp

163 continue lp

164 v = v if not isinstance(v, dict) else to_list(v) lp

165 l.append({k: v}) lp

166 return l lp

167 

168 

169def into_path(item, after, last_title): lp

170 """ 

171 (Pdb) pp item, after, last_title 

172 ('features/termcasts/zab/baz.md', 'features/termcasts/index.md', '3.Features.3.TermCasts.0.Overview') 

173 

174 Then we return '3.Features.3.TermCasts.0' 

175 """ 

176 while not item.startswith(after): 

177 after = after.rsplit('/', 1)[0] 

178 parts = after.split('/') 

179 return '.'.join(last_title.split('.', 2 * len(parts) + 1)[:-1]) 

180 

181 

182class MDFindPagesPlugin(MDPlugin): lp

183 config_scheme = ( 

184 ('find-pages', config_options.Type(list, default=[])), 

185 ('autodocs', config_options.Type(dict, default={}),), 

186 ) 

187 

188 def on_config(self, config): lp

189 # t0 = now() 

190 ad = self.config['autodocs'] lp

191 if ad: 191 ↛ 192line 191 didn't jump to line 192, because the condition on line 191 was never truelp

192 [autodocs.do_spec(ad, k, v, config, self.stats) for k, v in ad.items()] 

193 find_pages_and_add_to_nav(self.config['find-pages'], config, self.stats) lp

194 # print(now() - t0) # = 0.02 for docutools. Could be improved