wiki
This commit is contained in:
parent
7aaa5663c2
commit
a25d3df0f2
@ -1,6 +1,12 @@
|
|||||||
import glob
|
import glob
|
||||||
|
import re
|
||||||
|
from typing import TypeVar, Iterator
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
class WikiArticle:
|
class WikiArticle:
|
||||||
|
'''Abstract class that defines an article in the wiki'''
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
def tags(content):
|
def tags(content):
|
||||||
for line in content:
|
for line in content:
|
||||||
@ -24,12 +30,19 @@ class WikiArticle:
|
|||||||
self.title = title(content)
|
self.title = title(content)
|
||||||
self.tags = tags(content)
|
self.tags = tags(content)
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
|
||||||
|
def enrich(self, articles: Iterator):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'{type(self).__name__}({self.title}, {self.filename}, {self.tags})'
|
return f'{type(self).__name__}({self.title}, {self.filename}, {self.tags})'
|
||||||
|
|
||||||
class ContentArticle(WikiArticle): pass
|
class ContentArticle(WikiArticle):
|
||||||
|
'''The articles we wrote'''
|
||||||
|
pass
|
||||||
|
|
||||||
class MetaPage(WikiArticle):
|
class MetaPage(WikiArticle):
|
||||||
|
'''Wiki article containing code that must be generated by this program'''
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
self.header = '** Pages in this category'
|
self.header = '** Pages in this category'
|
||||||
super().__init__(filename)
|
super().__init__(filename)
|
||||||
@ -41,14 +54,15 @@ class MetaPage(WikiArticle):
|
|||||||
if len(correct_section) != 1:
|
if len(correct_section) != 1:
|
||||||
raise Exception(f'Invalid meta section in {filename}')
|
raise Exception(f'Invalid meta section in {filename}')
|
||||||
|
|
||||||
def replace_content(self, wikiarticles):
|
def enrich(self, linked_articles: Iterator[WikiArticle]):
|
||||||
|
'''Generator that returns content that will end up in the document before html conversion'''
|
||||||
content = map(identity, self.content)
|
content = map(identity, self.content)
|
||||||
def rep():
|
def rep():
|
||||||
for line in content:
|
for line in content:
|
||||||
if line == self.header: break
|
if line == self.header: break
|
||||||
else: yield line
|
else: yield line
|
||||||
yield self.header
|
yield self.header
|
||||||
for w in wikiarticles:
|
for w in linked_articles:
|
||||||
yield f'- [[../{w.filename}][{w.title}]]'
|
yield f'- [[../{w.filename}][{w.title}]]'
|
||||||
return rep()
|
return rep()
|
||||||
|
|
||||||
@ -64,26 +78,47 @@ def files():
|
|||||||
def metafiles():
|
def metafiles():
|
||||||
return glob.glob('meta/*.org')
|
return glob.glob('meta/*.org')
|
||||||
|
|
||||||
|
def invert_map(map_: list[ContentArticle]):
|
||||||
def invert_map(map_: list[WikiArticle]):
|
|
||||||
'''from {a: [1, 2], b: [2, 3]} to {1: [a], 2: [a, b], 3: [b]}'''
|
'''from {a: [1, 2], b: [2, 3]} to {1: [a], 2: [a, b], 3: [b]}'''
|
||||||
keys = set(i for e in map_ for i in e.tags)
|
keys = set(i for e in map_ for i in e.tags)
|
||||||
res = dict()
|
res: dict[str, list[WikiArticle]] = dict()
|
||||||
for k in keys:
|
for k in keys:
|
||||||
res[k] = res.get(k, []) + [w for w in map_ if k in w.tags]
|
res[k] = res.get(k, []) + [w for w in map_ if k in w.tags]
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def write_meta_page(m: MetaPage, content: list[str]):
|
def links(article: ContentArticle):
|
||||||
|
def haslink(line):
|
||||||
|
return re.findall(r'\[\[(.+?)\]\]', line)
|
||||||
|
|
||||||
|
def yield_links(line):
|
||||||
|
i = 0
|
||||||
|
while i < len(line)-1:
|
||||||
|
sub = line[i:]
|
||||||
|
if sub.startswith('[[./') and ']]' in sub and '.org' in sub: # org link to one org file
|
||||||
|
ridx = sub.index('.org')
|
||||||
|
yield sub[:ridx+4]
|
||||||
|
i += sub.index(']]')
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
for line in article.content:
|
||||||
|
if haslink(line):
|
||||||
|
yield from yield_links(line)
|
||||||
|
|
||||||
|
|
||||||
|
def writetodisk(m: WikiArticle, content: list[str]):
|
||||||
with open(m.filename, 'w') as f:
|
with open(m.filename, 'w') as f:
|
||||||
f.writelines(map(lambda l: l+'\n', content))
|
f.writelines(map(lambda l: l+'\n', content))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
files = [ContentArticle(f) for f in files()]
|
files_ = [ContentArticle(f) for f in files()]
|
||||||
meta = [MetaPage(f) for f in metafiles()]
|
meta_ = [MetaPage(f) for f in metafiles()]
|
||||||
meta = {m.meta: m for m in meta}
|
meta = {m.meta: m for m in meta_}
|
||||||
print(meta)
|
|
||||||
tags = invert_map(files)
|
tags = invert_map(files_)
|
||||||
for t, articles in tags.items():
|
for t, articles in tags.items():
|
||||||
if t in meta:
|
if t in meta:
|
||||||
newcontent = meta[t].replace_content(articles)
|
newcontent = meta[t].enrich(articles)
|
||||||
write_meta_page(meta[t], newcontent)
|
writetodisk(meta[t], newcontent)
|
||||||
|
|
||||||
|
for a in files_:
|
||||||
|
print(a, links(a))
|
||||||
|
Loading…
Reference in New Issue
Block a user