diff --git a/.gitignore b/.gitignore
index 3351d9d..7e78571 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,4 +83,6 @@ typings/
# ignore generated contents-
/doc/out/*
**/thumbnails
-**/thumbnail.png
\ No newline at end of file
+**/thumbnail.png
+/site/dist
+/site/__pycache__
\ No newline at end of file
diff --git a/doc/ast.html b/doc/ast.html
index fc06f6d..9c02028 100644
--- a/doc/ast.html
+++ b/doc/ast.html
@@ -1,30 +1,28 @@
-
+
@@ -32,104 +30,106 @@
\ No newline at end of file
+ return data
+ }
+
diff --git a/lib/app.html b/lib/app.html
index e321874..a5e1141 100644
--- a/lib/app.html
+++ b/lib/app.html
@@ -3,6 +3,7 @@
+ App
diff --git a/site/.python-version b/site/.python-version
new file mode 100644
index 0000000..f870be2
--- /dev/null
+++ b/site/.python-version
@@ -0,0 +1 @@
+3.10.1
diff --git a/site/main.py b/site/main.py
new file mode 100644
index 0000000..d1ebadb
--- /dev/null
+++ b/site/main.py
@@ -0,0 +1,45 @@
+import pathlib
+from ssg.tags import *
+from ssg.utils import *
+from markup import iwmlibdoc_document, sitemap_main
+
+src = pathlib.Path('..')
+content = src / 'lib'
+
+async def main(path:pathlib.Path):
+ """Typical main program, setting up content publishers, defining the site structure and
+ typical order of generating initial pages and observing subsequent changes.
+ """
+
+ # 2. Build the site structure with nested context managers
+ with site('iwmlibdoc', path=path, doc=iwmlibdoc_document) as docsite:
+ # If we use symlinks the css and image files can be modified without
+ # notifications.
+ docsite.symlink(src, 'css')
+ docsite.symlink(src, 'assets')
+ docsite.symlink(src, 'dist')
+ # structures can be created in a loop to ensure indentical hierarchies
+
+ sitemap = page('sitemap.html',
+ title='Sitemap',
+ main=sitemap_main)
+ static_folder(content)
+
+ # 3. Start generation.
+ docsite.generate()
+
+ #print(docsite)
+ # 4. Let's check whether all links are working...
+ # site.validate()
+
+ await docsite.observe_filesystem(timeout=120)
+
+def run():
+ default = pathlib.Path('.') / 'dist'
+ if default.exists():
+ shutil.rmtree(default)
+ default.mkdir(parents=True)
+ asyncio.run(main(default))
+
+if __name__ == "__main__":
+ run()
diff --git a/site/markup.py b/site/markup.py
new file mode 100644
index 0000000..efc5815
--- /dev/null
+++ b/site/markup.py
@@ -0,0 +1,107 @@
+
+from typing import Dict, List
+import ssg.document
+import ssg.utils
+from ssg.tags import *
+from dominate.tags import *
+
+def iwmlibdoc_document(context):
+ doc = ssg.document.document(title=context.title)
+ with doc.head:
+ meta(charset="utf-8")
+ attr(lang=context.language())
+ if isinstance(context, static_page):
+ for tag in context.soup.find_all('link'):
+ if href := tag.attrs.get('href'):
+ link(rel="stylesheet", href=href)
+
+ for tag in context.soup.find_all('script'):
+ if src := tag.attrs.get('src'):
+ script(src=src)
+ else:
+ link(rel="stylesheet", href= "css/doctest.css")
+ link(rel="stylesheet", href= "css/demo.css")
+
+ with doc.body:
+ site_navigation(context)
+ ssg.document.placeholder(key='main', alternatives=['body']) # here goes the special content part
+ site_footer(context)
+ return doc
+
+def site_navigation(context):
+ mainmenu(context)
+ br()
+ br()
+ breadcrumb(context)
+ hr()
+
+
+def level_menu(context, root):
+ for name, child in sorted(context.named_children.items()):
+ if child.folderish():
+ if index := child.named_children.get('index.html'):
+ url = '.' + index.url(relative=root)
+ yield dict(url=url, title=index.title)
+
+ if child.title == name:
+ continue
+ if name.endswith('.html'):
+ url = '.' + child.url(relative=root)
+ yield dict(url=url, title=child.title)
+
+
+def main_menu(context):
+ root = context.menuroot()
+ if context == root:
+ for info in level_menu(root, root):
+ yield info
+ else:
+ yield dict(url= context.up() + 'sitemap.html', title="Home")
+ for info in level_menu(context.parent, root):
+ yield info
+
+@nav(cls="breadcrumb")
+def breadcrumb(context):
+ """
+ {% macro breadcrumb(context) -%}
+
+ {% endmacro %}
+ """
+ for info in context.breadcrumb():
+ if url := info.get('url'):
+ a(info['title'], href=url)
+ else:
+ a(info['title'], href='#')
+
+@nav(cls="mainmenu")
+def mainmenu(context:ssg.generator):
+ for info in main_menu(context):
+ if url := info.get('url'):
+ a(info['title'], href=url)
+ else:
+ a(info['title'], href='#')
+
+@main
+def sitemap_main(context:ssg.generator):
+ root = context.menuroot()
+ h3("Sitemap")
+ with ul(id="sitemap"):
+ for info in getsite().page_infos(relative=root):
+ url = info['url']
+ if url.endswith('.html'):
+ li(a(info['title'], href=url))
+
+@footer
+def site_footer(context):
+ hr()
+ date = ssg.utils.now('en')
+ p(f'Generated by IWMSite {date}')
+
diff --git a/site/requirements.txt b/site/requirements.txt
new file mode 100644
index 0000000..b703ef1
--- /dev/null
+++ b/site/requirements.txt
@@ -0,0 +1,21 @@
+aiohttp
+dominate
+pytest
+Babel
+mypy
+beautifulsoup4
+python-socketio
+requests
+watchdog
+
+# streamlit apps
+streamlit==1.4.0
+openpyxl
+plotly
+fpdf
+
+# architecture overview
+diagrams
+
+# ssg
+git+ssh://git@gitea.iwm-tuebingen.de/Medienentwicklung/iwmsite.git@master