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
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
1"""
2## Find Pages
4Adds pages to nav
5"""
7import string lp
8import time lp
9from ast import literal_eval lp
10from functools import partial lp
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
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
26def uppercase_words(s): lp
27 """titles in nav should only contain the strings, not e.g. links
29 s: "Local LP Blocks :srcref:fn=src/lcdoc/mkdocs/lp/plugs/python/pyplugs/lprunner/__init__.py,t=Runner"
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
40def is_after(fn, hfn): lp
42 breakpoint() # FIXME BREAKPOINT
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
61# get_insert_pos( './features', ['index.md', 'install.md', 'features/index.md', 'features/blacklist/index.md'],)
62now = time.time lp
65def clear_digits(t): lp
66 return '.'.join([k for k in t.split('.') if not k.isdigit()]) lp
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
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
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
127 dd = config['docs_dir'] lp
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
148 n = OD() lp
149 for k, v in r.items(): lp
150 n[clear_digits(k)] = v lp
152 r = unflatten(n, '.') lp
153 r = to_list(r) lp
154 config['nav'].clear() lp
155 config['nav'].extend(r) lp
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
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')
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])
182class MDFindPagesPlugin(MDPlugin): lp
183 config_scheme = (
184 ('find-pages', config_options.Type(list, default=[])),
185 ('autodocs', config_options.Type(dict, default={}),),
186 )
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