Hot-keys 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"""
6import string lp
7import time lp
8from ast import literal_eval lp
9from collections import OrderedDict as OD 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, flatten, os, project, read_file lp
16def uppercase_words(s): lp
17 """titles in nav should only contain the strings, not e.g. links"""
18 l = s.split(' ') lp
19 r = [] lp
20 while l[0] == l[0].upper() and l[0] in string.ascii_letters: 20 ↛ 21line 20 didn't jump to line 21, because the condition on line 20 was never truelp
21 r.append(l)
22 return ' '.join(r) lp
25def find_pages(find, config, stats): lp
27 ev = [i.strip() for i in os.environ.get('find_pages', '').split(',')] lp
28 ev = [i for i in ev if i] lp
29 find.extend(ev) lp
30 find = list(set(find)) lp
31 stats['find_terms'] = len(find) lp
32 if not find: 32 ↛ 33line 32 didn't jump to line 33, because the condition on line 32 was never truelp
33 return
34 fnd = [] lp
35 for m in find: lp
36 found = find_md_files(match=m, config=config) lp
37 if not found: 37 ↛ 38line 37 didn't jump to line 38, because the condition on line 37 was never truelp
38 app.warning('No pages found', match=m)
39 else:
40 fnd.extend(found) lp
41 stats['matching'] = len(fnd) lp
42 return fnd lp
45def is_after(fn, hfn): lp
47 breakpoint() # FIXME BREAKPOINT
50def get_insert_pos(fn, have): lp
51 while fn: 51 ↛ exitline 51 didn't return from function 'get_insert_pos', because the condition on line 51 was never falselp
52 fn, post = fn.rsplit('/', 1) lp
53 for i in range(len(have)): lp
54 if not have[i].startswith(fn): lp
55 continue lp
56 while have[i] < (fn + '/' + post) and have[i].startswith(fn): lp
57 i += 1 lp
58 return have[i - 1], have[i] lp
61now = time.time lp
64def clear_digits(t): lp
65 return '.'.join([k for k in t.split('.') if not k.isdigit()]) lp
68def find_pages_and_add_to_nav(find, config, stats): lp
69 found = find_pages(find, config, stats) lp
70 if not found: 70 ↛ 71line 70 didn't jump to line 71, because the condition on line 70 was never truelp
71 return
73 # m = OD({p: None for p in found})
74 nav = config['nav'] lp
75 navl = flatten(nav, '.') lp
76 navll = [[fn, k] for k, fn in navl.items()] lp
77 have = [fn[0] for fn in navll] lp
78 ins = {} lp
79 while found: lp
80 fn = found.pop(0) lp
81 if fn in have: lp
82 continue lp
83 bef, aft = get_insert_pos(fn, have) lp
84 ins.setdefault(have.index(bef), []).insert(0, fn) lp
85 l = {} lp
86 for k in reversed(sorted([i for i in ins])): lp
87 fns = ins[k] lp
88 [have.insert(k + 1, fn) for fn in fns] lp
89 l[have[k]] = fns lp
90 app.info('Inserting %s pages into nav' % sum([len(i) for i in ins.values()]), json=l) lp
91 # have now the complete list with found ones inserted at right places
92 # 'features/lp/python/_tech.md',
93 # 'features/lp/python/data_table/index.md',
94 navl_rev = {v: k for k, v in navl.items()} lp
95 r = OD() lp
97 dd = config['docs_dir'] lp
99 def get_title(fn_page): lp
100 h = '\n' + read_file(dd + '/' + fn_page, dflt='') + '\n# Found\n' lp
101 h = uppercase_words(h.split('\n# ', 1)[1].split('\n', 1)[0]) lp
102 if not h: 102 ↛ 109line 102 didn't jump to line 109, because the condition on line 102 was never falselp
103 # e.g. # bash alone has no uppercase word. then take the filename:
104 l = fn_page.rsplit('/', 2) lp
105 if l[-1] == 'index.md': 105 ↛ 108line 105 didn't jump to line 108, because the condition on line 105 was never falselp
106 h = l[-2] lp
107 else:
108 h = fn_page.rsplit('/', 1)[-1].split('.', 1)[0]
109 return h lp
111 to = None lp
112 for h in have: lp
113 tit = navl_rev.get(h) lp
114 if not tit: lp
115 t = to.rsplit('.', 2) lp
116 tit = '.'.join((t[0], str(int(t[-2]) + 1), get_title(h))) lp
117 r[tit] = h lp
118 to = tit lp
120 n = OD() lp
121 for k, v in r.items(): lp
122 n[clear_digits(k)] = v lp
124 r = unflatten(n) lp
125 r = to_list(r) lp
126 config['nav'].clear() lp
127 config['nav'].extend(r) lp
130def to_list(d): lp
131 l = [] lp
132 for k, v in d.items(): lp
133 v = v if not isinstance(v, dict) else to_list(v) lp
134 l.append({k: v}) lp
135 return l lp
138def unflatten(dictionary): lp
139 resultDict = OD() lp
140 for key, value in dictionary.items(): lp
141 parts = key.split('.') lp
142 d = resultDict lp
143 for part in parts[:-1]: lp
144 if part not in d: lp
145 d[part] = OD() lp
146 d = d[part] lp
147 d[parts[-1]] = value lp
148 return resultDict lp
151def into_path(item, after, last_title): lp
152 """
153 (Pdb) pp item, after, last_title
154 ('features/termcasts/zab/baz.md', 'features/termcasts/index.md', '3.Features.3.TermCasts.0.Overview')
156 Then we return '3.Features.3.TermCasts.0'
157 """
158 while not item.startswith(after):
159 after = after.rsplit('/', 1)[0]
160 parts = after.split('/')
161 return '.'.join(last_title.split('.', 2 * len(parts) + 1)[:-1])
164class MDFindPagesPlugin(MDPlugin): lp
165 config_scheme = (('find-pages', config_options.Type(list, default=[])),) lp
167 def on_config(self, config): lp
168 # t0 = now()
169 find_pages_and_add_to_nav(self.config['find-pages'], config, self.stats) lp
170 # print(now() - t0) # = 0.02 for docutools. Could be improved