From 0a9c6693255800c6c197a3dcf3614046c296e293 Mon Sep 17 00:00:00 2001
From: David Luevano Alvarado <david@luevano.xyz>
Date: Sun, 9 May 2021 12:37:01 -0600
Subject: semiworking program, still very alpha

---
 ChangeLog                                          |   1 +
 e_dst/a/test2.html                                 |   0
 e_dst/test1.html                                   |   0
 e_src/a/test2.html                                 |   0
 e_src/a/test2.md                                   |  13 ++
 e_src/templates/article/footer.html                |   0
 e_src/templates/article/header.html                |   1 +
 e_src/templates/articles/footer.html               |   0
 e_src/templates/articles/header.html               |   0
 e_src/templates/articles/list_entry.html           |   1 +
 e_src/templates/articles/list_footer.html          |   1 +
 e_src/templates/articles/list_header.html          |   2 +
 e_src/templates/articles/list_separator.html       |   0
 e_src/templates/common/footer.html                 |   2 +
 e_src/templates/common/header.html                 |   8 +
 e_src/templates/tag/footer.html                    |   0
 e_src/templates/tag/header.html                    |   0
 e_src/templates/tag/list_entry.html                |   1 +
 e_src/templates/tag/list_footer.html               |   1 +
 e_src/templates/tag/list_header.html               |   1 +
 e_src/templates/tag/list_separator.html            |   1 +
 e_src/test1.html                                   |   0
 e_src/test1.md                                     |  12 ++
 example_src/a/test3.md                             |   0
 example_src/a/test4.md                             |   0
 example_src/a/test6.html                           |   0
 example_src/b/c/test8.html                         |   0
 example_src/b/c/test9.md                           |   0
 example_src/b/test7.html                           |   0
 example_src/templates/article/article_entry.html   |   1 -
 example_src/templates/article/article_footer.html  |   0
 example_src/templates/article/article_header.html  |   1 -
 .../templates/article/article_list_footer.html     |   1 -
 .../templates/article/article_list_header.html     |   2 -
 .../templates/article/article_separator.html       |   0
 example_src/templates/article/footer.html          |   2 -
 example_src/templates/article/header.html          |   8 -
 example_src/templates/article/index_footer.html    |   0
 example_src/templates/article/index_header.html    |   0
 example_src/templates/article/tag_entry.html       |   1 -
 .../templates/article/tag_index_footer.html        |   0
 .../templates/article/tag_index_header.html        |   0
 example_src/templates/article/tag_list_footer.html |   1 -
 example_src/templates/article/tag_list_header.html |   1 -
 example_src/templates/article/tag_separator.html   |   1 -
 example_src/test.md                                |   0
 example_src/test2.md                               |   0
 example_src/test5.html                             |   0
 src/pyssg/converter.py                             |  62 ++++++++
 src/pyssg/discovery.py                             |  13 +-
 src/pyssg/generator.py                             |  40 +++++
 src/pyssg/page.py                                  |  49 ++++++
 src/pyssg/parser.py                                |  24 ---
 src/pyssg/pyssg.py                                 |  15 +-
 src/pyssg/template.py                              | 164 +++++++++++++++++++++
 src/pyssg/templates.py                             |  83 -----------
 56 files changed, 380 insertions(+), 134 deletions(-)
 create mode 100644 e_dst/a/test2.html
 create mode 100644 e_dst/test1.html
 create mode 100644 e_src/a/test2.html
 create mode 100644 e_src/a/test2.md
 create mode 100644 e_src/templates/article/footer.html
 create mode 100644 e_src/templates/article/header.html
 create mode 100644 e_src/templates/articles/footer.html
 create mode 100644 e_src/templates/articles/header.html
 create mode 100644 e_src/templates/articles/list_entry.html
 create mode 100644 e_src/templates/articles/list_footer.html
 create mode 100644 e_src/templates/articles/list_header.html
 create mode 100644 e_src/templates/articles/list_separator.html
 create mode 100644 e_src/templates/common/footer.html
 create mode 100644 e_src/templates/common/header.html
 create mode 100644 e_src/templates/tag/footer.html
 create mode 100644 e_src/templates/tag/header.html
 create mode 100644 e_src/templates/tag/list_entry.html
 create mode 100644 e_src/templates/tag/list_footer.html
 create mode 100644 e_src/templates/tag/list_header.html
 create mode 100644 e_src/templates/tag/list_separator.html
 create mode 100644 e_src/test1.html
 create mode 100644 e_src/test1.md
 delete mode 100644 example_src/a/test3.md
 delete mode 100644 example_src/a/test4.md
 delete mode 100644 example_src/a/test6.html
 delete mode 100644 example_src/b/c/test8.html
 delete mode 100644 example_src/b/c/test9.md
 delete mode 100644 example_src/b/test7.html
 delete mode 100644 example_src/templates/article/article_entry.html
 delete mode 100644 example_src/templates/article/article_footer.html
 delete mode 100644 example_src/templates/article/article_header.html
 delete mode 100644 example_src/templates/article/article_list_footer.html
 delete mode 100644 example_src/templates/article/article_list_header.html
 delete mode 100644 example_src/templates/article/article_separator.html
 delete mode 100644 example_src/templates/article/footer.html
 delete mode 100644 example_src/templates/article/header.html
 delete mode 100644 example_src/templates/article/index_footer.html
 delete mode 100644 example_src/templates/article/index_header.html
 delete mode 100644 example_src/templates/article/tag_entry.html
 delete mode 100644 example_src/templates/article/tag_index_footer.html
 delete mode 100644 example_src/templates/article/tag_index_header.html
 delete mode 100644 example_src/templates/article/tag_list_footer.html
 delete mode 100644 example_src/templates/article/tag_list_header.html
 delete mode 100644 example_src/templates/article/tag_separator.html
 delete mode 100644 example_src/test.md
 delete mode 100644 example_src/test2.md
 delete mode 100644 example_src/test5.html
 create mode 100644 src/pyssg/converter.py
 create mode 100644 src/pyssg/generator.py
 create mode 100644 src/pyssg/page.py
 delete mode 100644 src/pyssg/parser.py
 create mode 100644 src/pyssg/template.py
 delete mode 100644 src/pyssg/templates.py

diff --git a/ChangeLog b/ChangeLog
index 9ae16c6..d551703 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 CHANGES
 =======
 
+* Add working file discovery and destination file structure creation
 * initial template creation, barebones arg parser
 * Prepare barebones package info
 * Update readme
diff --git a/e_dst/a/test2.html b/e_dst/a/test2.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_dst/test1.html b/e_dst/test1.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_src/a/test2.html b/e_src/a/test2.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_src/a/test2.md b/e_src/a/test2.md
new file mode 100644
index 0000000..0eb26ec
--- /dev/null
+++ b/e_src/a/test2.md
@@ -0,0 +1,13 @@
+title: Test 2
+author: David Luévano
+summary: Small summary
+lang: en
+tags: test
+	small
+	archive
+
+This is an article test, again
+
+- asdfg
+- hjikl
+	- ??
diff --git a/e_src/templates/article/footer.html b/e_src/templates/article/footer.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_src/templates/article/header.html b/e_src/templates/article/header.html
new file mode 100644
index 0000000..d2954d9
--- /dev/null
+++ b/e_src/templates/article/header.html
@@ -0,0 +1 @@
+<h1>$$TITLE</h1>
\ No newline at end of file
diff --git a/e_src/templates/articles/footer.html b/e_src/templates/articles/footer.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_src/templates/articles/header.html b/e_src/templates/articles/header.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_src/templates/articles/list_entry.html b/e_src/templates/articles/list_entry.html
new file mode 100644
index 0000000..91d2d75
--- /dev/null
+++ b/e_src/templates/articles/list_entry.html
@@ -0,0 +1 @@
+<li><a href="$$URL">$$DATE - $$TITLE</a></li>
diff --git a/e_src/templates/articles/list_footer.html b/e_src/templates/articles/list_footer.html
new file mode 100644
index 0000000..3d3a44c
--- /dev/null
+++ b/e_src/templates/articles/list_footer.html
@@ -0,0 +1 @@
+</ul>
diff --git a/e_src/templates/articles/list_header.html b/e_src/templates/articles/list_header.html
new file mode 100644
index 0000000..7b504ea
--- /dev/null
+++ b/e_src/templates/articles/list_header.html
@@ -0,0 +1,2 @@
+<h2>Articles</h2>
+<ul>
diff --git a/e_src/templates/articles/list_separator.html b/e_src/templates/articles/list_separator.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_src/templates/common/footer.html b/e_src/templates/common/footer.html
new file mode 100644
index 0000000..308b1d0
--- /dev/null
+++ b/e_src/templates/common/footer.html
@@ -0,0 +1,2 @@
+</body>
+</html>
diff --git a/e_src/templates/common/header.html b/e_src/templates/common/header.html
new file mode 100644
index 0000000..9c423df
--- /dev/null
+++ b/e_src/templates/common/header.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html lang="$$LANG">
+<head>
+<meta charset="utf-8">
+<title>$$TITLE</title>
+$$EXTRAHEAD
+</head>
+<body>
diff --git a/e_src/templates/tag/footer.html b/e_src/templates/tag/footer.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_src/templates/tag/header.html b/e_src/templates/tag/header.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_src/templates/tag/list_entry.html b/e_src/templates/tag/list_entry.html
new file mode 100644
index 0000000..3a7aaad
--- /dev/null
+++ b/e_src/templates/tag/list_entry.html
@@ -0,0 +1 @@
+<a href="$$URL">$$NAME</a>
\ No newline at end of file
diff --git a/e_src/templates/tag/list_footer.html b/e_src/templates/tag/list_footer.html
new file mode 100644
index 0000000..8ce77e5
--- /dev/null
+++ b/e_src/templates/tag/list_footer.html
@@ -0,0 +1 @@
+</p>
diff --git a/e_src/templates/tag/list_header.html b/e_src/templates/tag/list_header.html
new file mode 100644
index 0000000..5bb080d
--- /dev/null
+++ b/e_src/templates/tag/list_header.html
@@ -0,0 +1 @@
+<p>Tags: 
\ No newline at end of file
diff --git a/e_src/templates/tag/list_separator.html b/e_src/templates/tag/list_separator.html
new file mode 100644
index 0000000..c3a6e48
--- /dev/null
+++ b/e_src/templates/tag/list_separator.html
@@ -0,0 +1 @@
+, 
\ No newline at end of file
diff --git a/e_src/test1.html b/e_src/test1.html
new file mode 100644
index 0000000..e69de29
diff --git a/e_src/test1.md b/e_src/test1.md
new file mode 100644
index 0000000..85e97b3
--- /dev/null
+++ b/e_src/test1.md
@@ -0,0 +1,12 @@
+title: Test 1
+author: David Luévano
+summary: Small summary
+lang: en
+tags: test
+	small
+	archive
+
+This is an article test
+
+- asdfg
+- hjikl
diff --git a/example_src/a/test3.md b/example_src/a/test3.md
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/a/test4.md b/example_src/a/test4.md
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/a/test6.html b/example_src/a/test6.html
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/b/c/test8.html b/example_src/b/c/test8.html
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/b/c/test9.md b/example_src/b/c/test9.md
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/b/test7.html b/example_src/b/test7.html
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/templates/article/article_entry.html b/example_src/templates/article/article_entry.html
deleted file mode 100644
index 6e6befd..0000000
--- a/example_src/templates/article/article_entry.html
+++ /dev/null
@@ -1 +0,0 @@
-<li><a href="$$URL">$$DATE $$TITLE</a></li>
diff --git a/example_src/templates/article/article_footer.html b/example_src/templates/article/article_footer.html
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/templates/article/article_header.html b/example_src/templates/article/article_header.html
deleted file mode 100644
index d2954d9..0000000
--- a/example_src/templates/article/article_header.html
+++ /dev/null
@@ -1 +0,0 @@
-<h1>$$TITLE</h1>
\ No newline at end of file
diff --git a/example_src/templates/article/article_list_footer.html b/example_src/templates/article/article_list_footer.html
deleted file mode 100644
index 3d3a44c..0000000
--- a/example_src/templates/article/article_list_footer.html
+++ /dev/null
@@ -1 +0,0 @@
-</ul>
diff --git a/example_src/templates/article/article_list_header.html b/example_src/templates/article/article_list_header.html
deleted file mode 100644
index 7b504ea..0000000
--- a/example_src/templates/article/article_list_header.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<h2>Articles</h2>
-<ul>
diff --git a/example_src/templates/article/article_separator.html b/example_src/templates/article/article_separator.html
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/templates/article/footer.html b/example_src/templates/article/footer.html
deleted file mode 100644
index 308b1d0..0000000
--- a/example_src/templates/article/footer.html
+++ /dev/null
@@ -1,2 +0,0 @@
-</body>
-</html>
diff --git a/example_src/templates/article/header.html b/example_src/templates/article/header.html
deleted file mode 100644
index 48adfef..0000000
--- a/example_src/templates/article/header.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html lang=$$LANG>
-<head>
-<meta charset="utf-8">
-<title>$$TITLE</title>
-$$EXTRAHEAD
-</head>
-<body>
diff --git a/example_src/templates/article/index_footer.html b/example_src/templates/article/index_footer.html
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/templates/article/index_header.html b/example_src/templates/article/index_header.html
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/templates/article/tag_entry.html b/example_src/templates/article/tag_entry.html
deleted file mode 100644
index 3a7aaad..0000000
--- a/example_src/templates/article/tag_entry.html
+++ /dev/null
@@ -1 +0,0 @@
-<a href="$$URL">$$NAME</a>
\ No newline at end of file
diff --git a/example_src/templates/article/tag_index_footer.html b/example_src/templates/article/tag_index_footer.html
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/templates/article/tag_index_header.html b/example_src/templates/article/tag_index_header.html
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/templates/article/tag_list_footer.html b/example_src/templates/article/tag_list_footer.html
deleted file mode 100644
index 8ce77e5..0000000
--- a/example_src/templates/article/tag_list_footer.html
+++ /dev/null
@@ -1 +0,0 @@
-</p>
diff --git a/example_src/templates/article/tag_list_header.html b/example_src/templates/article/tag_list_header.html
deleted file mode 100644
index 7a57395..0000000
--- a/example_src/templates/article/tag_list_header.html
+++ /dev/null
@@ -1 +0,0 @@
-<p>Tags:
\ No newline at end of file
diff --git a/example_src/templates/article/tag_separator.html b/example_src/templates/article/tag_separator.html
deleted file mode 100644
index c3a6e48..0000000
--- a/example_src/templates/article/tag_separator.html
+++ /dev/null
@@ -1 +0,0 @@
-, 
\ No newline at end of file
diff --git a/example_src/test.md b/example_src/test.md
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/test2.md b/example_src/test2.md
deleted file mode 100644
index e69de29..0000000
diff --git a/example_src/test5.html b/example_src/test5.html
deleted file mode 100644
index e69de29..0000000
diff --git a/src/pyssg/converter.py b/src/pyssg/converter.py
new file mode 100644
index 0000000..5af2bd2
--- /dev/null
+++ b/src/pyssg/converter.py
@@ -0,0 +1,62 @@
+import os
+from markdown import Markdown
+from copy import deepcopy
+from .page import Page
+from .template import Template
+
+
+def get_pages(src: str, files: list[str]) -> list[Page]:
+    md: Markdown = Markdown(extensions=['extra', 'meta', 'sane_lists',
+                                        'smarty', 'toc', 'wikilinks'],
+                            output_format='html5')
+
+    pages: list[Page] = []
+
+    for f in files:
+        f_name = os.path.join(src, f)
+
+        content = md.reset().convert(open(f_name).read())
+        f_time = os.stat(f_name).st_mtime
+
+        pages.append(Page(f_name, f_time, content, md.Meta))
+
+    return pages
+
+
+def create_html_files(src: str, dst: str, files: list[str]) -> None:
+    # get the list of page objects
+    pages: list[Page] = get_pages(src, files)
+
+    # read all templates into a template obj
+    template: Template = Template()
+    template.read_templates(src)
+    for p in pages:
+        # t=template, p=page
+        t: Template = deepcopy(template)
+        p.parse_meta()
+
+        # common
+        t.header = t.header.replace("$$LANG", p.lang)
+        t.header = t.header.replace('$$TITLE', p.title)
+        t.header = t.header.replace('$$EXTRAHEAD', f'''
+    <!-- example extra head -->
+    <meta name="robots" content="index, follow">
+    <meta property="og:title" content="{p.title}">
+    <meta property="og:description" content="{p.summary}">''')
+
+        # article entry
+        t.article.header = t.article.header.replace('$$TITLE', p.title)
+
+        print(t.header)
+        print(t.article.header)
+        print(p.c_html)
+        print(t.tags.list_header, sep='')
+        for tag in p.tags:
+            tag_entry = t.tags.list_entry
+            tag_entry = tag_entry.replace('$$NAME', tag)
+            tag_entry = tag_entry.replace('$$URL', p.f_name)
+            print(tag_entry, sep='')
+            print(t.tags.list_separator, sep='')
+        print(t.tags.list_footer)
+        print(t.article.footer)
+        print(t.footer)
diff --git a/src/pyssg/discovery.py b/src/pyssg/discovery.py
index 39c8bb1..606c1d0 100644
--- a/src/pyssg/discovery.py
+++ b/src/pyssg/discovery.py
@@ -11,7 +11,7 @@ def get_file_list(extensions: list[str], exclude: list[str]=None) -> list[str]:
 
         for f in files:
             if f.endswith(tuple(extensions)):
-                out.append(os.path.join(root, f))
+                out.append(os.path.join(root, f).replace(cwd, '')[1:])
 
     return out
 
@@ -27,14 +27,19 @@ def get_dir_structure(exclude: list[str]=None) -> list[str]:
         for d in dirs:
             if root in out:
                 out.remove(root)
-            out.append(os.path.join(root, d).replace(cwd, ''))
+            out.append(os.path.join(root, d))
+
+    return [o.replace(cwd, '')[1:] for o in out]
 
-    return out
 
+def get_all_files(src: str) -> tuple[list[str], list[str], list[str]]:
+    iwd = os.getcwd()
+    os.chdir(src)
 
-def get_all_files():
     md_files = get_file_list(['.md', '.markdown'], ['templates'])
     html_files = get_file_list(['.html'], ['templates'])
     dirs = get_dir_structure(['templates'])
 
+    os.chdir(iwd)
+
     return (dirs, md_files, html_files)
diff --git a/src/pyssg/generator.py b/src/pyssg/generator.py
new file mode 100644
index 0000000..143eae1
--- /dev/null
+++ b/src/pyssg/generator.py
@@ -0,0 +1,40 @@
+import os
+import shutil
+from .discovery import get_all_files
+from .converter import create_html_files
+
+
+def create_dir_structure(dst: str, dirs: list[str]) -> None:
+    iwd = os.getcwd()
+
+    os.chdir(dst)
+    cwd = os.getcwd()
+
+    for d in dirs:
+        # for the dir structure,
+        # doesn't matter if the dir already exists
+        try:
+            os.makedirs(os.path.join(cwd, d))
+        except FileExistsError:
+            pass
+
+    os.chdir(iwd)
+
+
+def copy_html_files(src: str, dst: str, files: list[str]) -> None:
+    src_file = None
+    dst_file = None
+
+    for f in files:
+        src_file = os.path.join(src, f)
+        dst_file = os.path.join(dst, f)
+
+        shutil.copy2(src_file, dst_file)
+
+
+def generate_static_site(src: str, dst: str) -> None:
+    dirs, md_files, html_files = get_all_files(src)
+    create_dir_structure(dst, dirs)
+
+    copy_html_files(src, dst, html_files)
+    create_html_files(src, dst, md_files)
diff --git a/src/pyssg/page.py b/src/pyssg/page.py
new file mode 100644
index 0000000..09486ea
--- /dev/null
+++ b/src/pyssg/page.py
@@ -0,0 +1,49 @@
+from datetime import datetime, timezone
+
+
+class Page:
+    def __init__(self,
+                 f_name: str,
+                 f_time: float,
+                 c_html: str,
+                 c_meta: dict):
+        self.f_name: str = f_name
+        self.f_time: float = f_time
+        self.c_html: str = c_html
+        self.c_meta: dict = c_meta
+
+        self.title: str = None
+        self.author: str = None
+        self.timestamp: str = None
+        self.summary: str = None
+        self.lang: str = None
+        self.tags: list = None
+
+
+    def parse_meta(self):
+        try:
+            self.title = self.c_meta['title'][0]
+        except KeyError:
+            pass
+
+        try:
+            self.author = self.c_meta['author'][0]
+        except KeyError:
+            pass
+
+        self.timestamp = datetime.fromtimestamp(self.f_time, tz=timezone.utc)
+
+        try:
+            self.summary = self.c_meta['summary'][0]
+        except KeyError:
+            pass
+
+        try:
+            self.lang = self.c_meta['lang'][0]
+        except KeyError:
+            pass
+
+        try:
+            self.tags = self.c_meta['tags']
+        except KeyError:
+            pass
diff --git a/src/pyssg/parser.py b/src/pyssg/parser.py
deleted file mode 100644
index 8b8d108..0000000
--- a/src/pyssg/parser.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import os
-from .discovery import get_all_files
-
-
-def create_dir_structure(dirs: list[str]):
-    cwd = os.getcwd()
-
-    for d in dirs:
-        try:
-            os.makedirs(os.path.join(cwd, d[1:]))
-        except FileExistsError:
-            pass
-
-
-def generate_static_site(src: str, dst: str):
-    iwd = os.getcwd()
-
-    os.chdir(src)
-    dirs, md_files, html_files = get_all_files()
-    os.chdir(iwd)
-
-    os.chdir(dst)
-    create_dir_structure(dirs)
-    os.chdir(iwd)
diff --git a/src/pyssg/pyssg.py b/src/pyssg/pyssg.py
index 7378705..5b736ca 100644
--- a/src/pyssg/pyssg.py
+++ b/src/pyssg/pyssg.py
@@ -1,8 +1,8 @@
 import os
 from argparse import ArgumentParser, Namespace
 
-from .templates import create_templates
-from .parser import generate_static_site
+from .template import Template
+from .generator import generate_static_site
 
 
 def get_options() -> Namespace:
@@ -31,13 +31,20 @@ def get_options() -> Namespace:
     return parser.parse_args()
 
 
-def main():
+def main() -> None:
     opts = vars(get_options())
     src = opts['src']
     dst = opts['dst']
 
     if opts['init']:
-        create_templates(src, dst)
+        try:
+            os.mkdir(src)
+            os.makedirs(os.path.join(dst, 'tag'))
+        except FileExistsError:
+            pass
+
+        template = Template()
+        template.write_templates(src)
         return
 
     if opts['build']:
diff --git a/src/pyssg/template.py b/src/pyssg/template.py
new file mode 100644
index 0000000..c85df72
--- /dev/null
+++ b/src/pyssg/template.py
@@ -0,0 +1,164 @@
+import os
+
+
+class HF:
+    def __init__(self):
+        self.header: str = None
+        self.footer: str = None
+
+
+class Common(HF):
+    def __init__(self):
+        self.list_header: str = None
+        self.list_footer: str = None
+        self.list_entry: str = None
+        self.list_separator: str = None
+
+
+class Template(HF):
+    def __init__(self):
+        self.article: HF = HF()
+        self.articles: Common = Common()
+        self.tags: Common = Common()
+
+
+    def write_templates(self, src: str) -> None:
+        # get initial working directory
+        iwd = os.getcwd()
+        os.chdir(src)
+
+        # create templates dir
+        os.mkdir('templates')
+        os.chdir('templates')
+
+        # common
+        os.mkdir('common')
+        os.chdir('common')
+        self.__write_template('header.html',
+                              ['<!DOCTYPE html>\n',
+                               '<html lang="$$LANG">\n',
+                               '<head>\n',
+                               '<meta charset="utf-8">\n',
+                               '<title>$$TITLE</title>\n',
+                               '$$EXTRAHEAD\n',
+                               '</head>\n',
+                               '<body>\n'])
+        self.__write_template('footer.html',
+                              ['</body>\n',
+                               '</html>\n'])
+
+        # go back to templates
+        os.chdir('..')
+
+        # article entry
+        os.mkdir('article')
+        os.chdir('article')
+        self.__write_template('header.html',
+                              ['<h1>$$TITLE</h1>'])
+        self.__write_template('footer.html',
+                              [''])
+
+        # go back to templates
+        os.chdir('..')
+
+        # article index (articles)
+        os.mkdir('articles')
+        os.chdir('articles')
+        self.__write_template('header.html',
+                              [''])
+        self.__write_template('list_header.html',
+                              ['<h2>Articles</h2>\n',
+                               '<ul>\n'])
+        self.__write_template('list_entry.html',
+                              ['<li><a href="$$URL">$$DATE - $$TITLE</a></li>\n'])
+        self.__write_template('list_separator.html',
+                              [''])
+        self.__write_template('list_footer.html',
+                              ['</ul>\n'])
+        self.__write_template('footer.html',
+                              [''])
+
+        # go back to templates
+        os.chdir('..')
+
+        # tag
+        os.mkdir('tag')
+        os.chdir('tag')
+        self.__write_template('header.html',
+                              [''])
+        self.__write_template('list_header.html',
+                              ['<p>Tags: '])
+        self.__write_template('list_entry.html',
+                              ['<a href="$$URL">$$NAME</a>'])
+        self.__write_template('list_separator.html',
+                              [', '])
+        self.__write_template('list_footer.html',
+                              ['</p>\n'])
+        self.__write_template('footer.html',
+                              [''])
+
+        # return to initial working directory
+        os.chdir(iwd)
+
+
+    def read_templates(self, src: str) -> None:
+        # get initial working directory
+        iwd = os.getcwd()
+        os.chdir(os.path.join(src, 'templates'))
+
+        # common
+        os.chdir('common')
+        self.header = self.__read_template('header.html')
+        self.footer = self.__read_template('footer.html')
+
+        # go back to templates
+        os.chdir('..')
+
+        # article entry
+        os.chdir('article')
+        self.article.header = self.__read_template('header.html')
+        self.article.footer = self.__read_template('footer.html')
+
+        # go back to templates
+        os.chdir('..')
+
+        # article index
+        os.chdir('articles')
+        self.articles.header = self.__read_template('header.html')
+        self.articles.list_header = \
+                self.__read_template('list_header.html')
+        self.articles.list_entry = \
+                self.__read_template('list_entry.html')
+        self.articles.list_separator = \
+                self.__read_template('list_separator.html')
+        self.articles.list_footer = \
+                self.__read_template('list_footer.html')
+        self.articles.footer = self.__read_template('footer.html')
+
+        # go back to templates
+        os.chdir('..')
+
+        # tag
+        os.chdir('tag')
+        self.tags.header = self.__read_template('header.html')
+        self.tags.list_header = self.__read_template('list_header.html')
+        self.tags.list_entry = self.__read_template('list_entry.html')
+        self.tags.list_separator = self.__read_template('list_separator.html')
+        self.tags.list_footer = self.__read_template('list_footer.html')
+        self.tags.footer = self.__read_template('footer.html')
+
+        # return to initial working directory
+        os.chdir(iwd)
+
+
+    def __write_template(self, file_name: str, content: list[str]) -> None:
+        with open(file_name, 'w+') as f:
+            for c in content:
+                f.write(c)
+
+    def __read_template(self, file_name: str) -> str:
+        out: str = None
+        with open(file_name, 'r') as f:
+            out = f.read()
+
+        return out
diff --git a/src/pyssg/templates.py b/src/pyssg/templates.py
deleted file mode 100644
index 9ae2e96..0000000
--- a/src/pyssg/templates.py
+++ /dev/null
@@ -1,83 +0,0 @@
-import os
-
-
-def create_templates(src: str, dst: str):
-    # get initial working directory
-    iwd = os.getcwd()
-    print('creating dir structure...')
-
-    # create main dirs
-    try:
-        os.mkdir(src)
-        os.mkdir(dst)
-    except FileExistsError:
-        pass
-
-    os.chdir(src)
-
-    # create templates dir
-    os.mkdir('templates')
-    os.chdir('templates')
-
-    # create article (blog) barebones template
-    os.mkdir('article')
-    with open('article/header.html', 'w+') as f:
-        f.write('<!DOCTYPE html>\n')
-        f.write('<html lang=$$LANG>\n')
-        f.write('<head>\n')
-        f.write('<meta charset="utf-8">\n')
-        f.write('<title>$$TITLE</title>\n')
-        f.write('$$EXTRAHEAD\n')
-        f.write('</head>\n')
-        f.write('<body>\n')
-
-    with open('article/footer.html', 'w+') as f:
-        f.write('</body>\n')
-        f.write('</html>\n')
-
-    with open('article/index_header.html', 'w+') as f:
-        f.write('')
-
-    with open('article/tag_list_header.html', 'w+') as f:
-        f.write('<p>Tags:')
-
-    with open('article/tag_entry.html', 'w+') as f:
-        f.write('<a href="$$URL">$$NAME</a>')
-
-    with open('article/tag_separator.html', 'w+') as f:
-        f.write(', ')
-
-    with open('article/tag_list_footer.html', 'w+') as f:
-        f.write('</p>\n')
-
-    with open('article/article_list_header.html', 'w+') as f:
-        f.write('<h2>Articles</h2>\n')
-        f.write('<ul>\n')
-
-    with open('article/article_entry.html', 'w+') as f:
-        f.write('<li><a href="$$URL">$$DATE $$TITLE</a></li>\n')
-
-    with open('article/article_separator.html', 'w+') as f:
-        f.write('')
-
-    with open('article/article_list_footer.html', 'w+') as f:
-        f.write('</ul>\n')
-
-    with open('article/index_footer.html', 'w+') as f:
-        f.write('')
-
-    with open('article/tag_index_header.html', 'w+') as f:
-        f.write('')
-
-    with open('article/tag_index_footer.html', 'w+') as f:
-        f.write('')
-
-    with open('article/article_header.html', 'w+') as f:
-        f.write('<h1>$$TITLE</h1>')
-
-    with open('article/article_footer.html', 'w+') as f:
-        f.write('')
-
-    # return to initial working directory
-    os.chdir(iwd)
-    print('done creating dir structure...')
-- 
cgit v1.2.3-70-g09d2