diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7c77252
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.venv
+settings.yml
+out
+uv.lock
\ No newline at end of file
diff --git a/.python-version b/.python-version
new file mode 100644
index 0000000..e4fba21
--- /dev/null
+++ b/.python-version
@@ -0,0 +1 @@
+3.12
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fc6dee4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+A tool to generate html and gmi static websites from markdown and mp3 files
+
+"simple" folder is an even simpler tool
\ No newline at end of file
diff --git a/publish.py b/publish.py
new file mode 100644
index 0000000..656bd00
--- /dev/null
+++ b/publish.py
@@ -0,0 +1,80 @@
+import os
+import re
+import markdown
+import yaml
+import shutil
+
+htmltemplate = """
+
+
+
+
+ {title}
+
+
+{body}"""
+
+def apply_html_template(body, title):
+ return htmltemplate.format(body=body, title=title)
+
+def md2html(md):
+ return markdown.markdown(md, extensions=['extra', 'nl2br'])
+
+def md2gmi(md):
+ gmi = md
+ gmi = re.sub(r'\[(.*)\]\((.*)\)', r'\n=> \2 \1', gmi)
+ gmi = gmi.replace('* * *', '---')
+ gmi = re.sub(r'^\*(.*)\*$', r'> \1', gmi, flags=re.MULTILINE)
+ gmi = re.sub(r'\*(.*)\*', r'\1', gmi)
+ return gmi
+
+with open("settings.yml", "r", encoding="utf-8") as file:
+ index = yaml.safe_load(file)
+
+htmlhome = "{} {}
".format(index['title'], index['description'])
+gmihome = "# {}\n{}".format(index['title'], index['description'])
+
+os.makedirs("out/html", exist_ok=True)
+os.makedirs("out/gmi", exist_ok=True)
+
+for folderinfo in index['folders']:
+ htmlhome += "\n{} \n".format(folderinfo['title'])
+ gmihome += "\n\n## {}".format(folderinfo['title'])
+
+ if 'texts' in folderinfo:
+ for textinfo in folderinfo['texts']:
+ with open(os.path.join(folderinfo['folder'], textinfo['file']), "r", encoding="utf-8") as mdfile:
+ mdcontent = mdfile.read()
+
+ # clean header
+ mdcontent = re.sub(r'---\n[\s\S]*?\n---\n*', '', mdcontent)
+
+ htmlcontent = md2html(mdcontent)
+ gmicontent = md2gmi(mdcontent)
+
+ with open("out/html/{}".format(textinfo['file']).replace('.md', '.html'), "w", encoding="utf-8") as htmlfile:
+ htmlfile.write(apply_html_template(htmlcontent, "{} | {}".format(textinfo['title'], index['title'])))
+
+ with open("out/gmi/{}".format(textinfo['file']).replace('.md', '.gmi'), "w", encoding="utf-8") as gmifile:
+ gmifile.write(gmicontent)
+
+ if 'restricted' not in textinfo:
+ htmlhome += "{} ".format(textinfo['file'].replace('.md', '.html'), textinfo['title'])
+ gmihome += "\n=> {} {}".format(textinfo['file'].replace('.md', '.gmi').replace(' ', '%20'), textinfo['title'])
+
+ if 'sounds' in folderinfo:
+ for soundinfo in folderinfo['sounds']:
+ shutil.copy(os.path.join(folderinfo['folder'], soundinfo['file']), 'out/html')
+ htmlhome += "{} ".format(soundinfo['title'], soundinfo['file'])
+
+ htmlhome += "\n "
+
+with open("out/html/index.html", "w", encoding="utf-8") as htmlindex:
+ htmlindex.write(apply_html_template(htmlhome, index['title']))
+
+with open("out/gmi/index.gmi", "w", encoding="utf-8") as gmiindex:
+ gmiindex.write(gmihome)
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..05206a6
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,10 @@
+[project]
+name = "publish"
+version = "0.1.0"
+description = "A tool to generate html and gmi static websites from markdown files"
+readme = "README.md"
+requires-python = ">=3.12"
+dependencies = [
+ "markdown>=3.7",
+ "pyyml>=0.0.2",
+]
diff --git a/settings.yml.sample.yaml b/settings.yml.sample.yaml
new file mode 100644
index 0000000..7037acf
--- /dev/null
+++ b/settings.yml.sample.yaml
@@ -0,0 +1,22 @@
+title: Title of my web site
+description: Description of my web site
+folders:
+ - folder: ../path/containing/texts
+ title: Section title
+ texts:
+ - file: file1.md
+ title: Title 1
+ - file: file2.md
+ title: Title 2
+ - folder: ../path/containing/texts
+ title: Other section title
+ texts:
+ - file: file3.md
+ title: Title 3
+ - folder: ../path/containing/sounds
+ title: Sound section title
+ sounds:
+ - file: song1.mp3
+ title: Song 1
+ - file: song 2.mp3
+ title: Song 2