about summary refs log tree commit diff
path: root/strike
diff options
context:
space:
mode:
authorStarfall <us@starfall.systems>2023-12-05 09:59:19 -0600
committerStarfall <us@starfall.systems>2023-12-05 10:03:27 -0600
commit90058697439ee3f048f0f42b61ca5ea677e9b5cc (patch)
tree60b61ef629551112f2e78c6a25c814703dce72f7 /strike
parenta43a3e0c273e50d30561328f090d2fad249c7dd6 (diff)
strike: merge as subdir
Diffstat (limited to 'strike')
-rw-r--r--strike/CONTRIBUTING10
-rw-r--r--strike/README56
-rw-r--r--strike/sample/blog/also-exclude.html1
-rw-r--r--strike/sample/blog/empty.html0
-rw-r--r--strike/sample/blog/exclude.html1
-rw-r--r--strike/sample/blog/happy.html1
-rw-r--r--strike/sample/blog/subdir/index.html1
-rw-r--r--strike/sample/blog/with-frontmatter.html6
-rw-r--r--strike/sample/html/empty.html14
-rw-r--r--strike/sample/html/happy.html15
-rw-r--r--strike/sample/html/subdir/index.html15
-rw-r--r--strike/sample/html/with-frontmatter.html17
-rw-r--r--strike/sample/strike.ini19
-rw-r--r--strike/sample/template.html14
-rw-r--r--strike/strike.py70
15 files changed, 240 insertions, 0 deletions
diff --git a/strike/CONTRIBUTING b/strike/CONTRIBUTING
new file mode 100644
index 0000000..2f2508f
--- /dev/null
+++ b/strike/CONTRIBUTING
@@ -0,0 +1,10 @@
+Patches are accepted via email <us@starfall.systems> or Matrix DM (check https://starfall.systems/contact for the latest information).
+
+If anyone actually contributes, feel free to suggest a license change with the first patch. Check https://git.starfall.systems/www-starfall-systems/tree/COPYING.md for our thoughts - AGPL or MPL is probably fine.
+
+PATCH CHECKLIST
+---------------
+* Code style matches everything else (PEP8 compliance is suggested but not required as I've already decided to indent with tabs, feel free to go to 90-110 character lines as appropriate)
+* Documentation updated to describe new behavior
+* Example case(s) written in sample/blog
+* `./strike.py sample` run and output in sample/html looks as expected (you can use `git diff` to verify nothing except last-modified lines are changed)
diff --git a/strike/README b/strike/README
new file mode 100644
index 0000000..dd6448e
--- /dev/null
+++ b/strike/README
@@ -0,0 +1,56 @@
+   _____ __       _ __      
+  / ___// /______(_) /_____ 
+  \__ \/ __/ ___/ / //_/ _ \
+ ___/ / /_/ /  / / ,< /  __/
+/____/\__/_/  /_/_/|_|\___/ 
+============================
+
+A static site generator that does exactly what we need it to and no more.
+
+(c) 2021 Starfall <starfall.systems>, all rights reserved until I decide it's in a good enough state for others to use.
+
+Strike has simple goals:
+1. Read HTML page contents from files in the source folder
+2. Add boilerplate (head, header, footer, etc)
+3. Save to output folder
+
+And some stretch goals:
+ * Create an extra page listing all generated pages in order of creation date (newest first)
+ * As above, but as an RSS feed
+ * Add links to next & previous generated pages
+ * Turn the extra page into a flexible component that can be added into any other page
+ * Use different templates on different files
+ * Markup parsing (see below)
+ * More robust created/modified date handling - needs more specification (markup changes vs. template changes, caching original creation date because posix systems don't actually provide that, etc.)
+
+strike.ini file
+---------------
+
+Strike should be passed the location of a .ini file or a directory containing a file named strike.ini. This is a text file in Python's configparser format (for now). You can see an example config file with all supported options at sample/strike.ini.
+
+Markup
+------
+
+TBD. No markup is used at the moment.
+
+reStructuredText fulfills most of our desires: https://docutils.sourceforge.io/rst.html
+It generates <section>s and has specific markup for page titles.
+
+Templating
+----------
+
+TBD. 
+
+Right now, templates are just passed to Python's str.format(). You can use these variables by default:
+
+{content} : Complete file contents.
+{meta[title]} : Filename, with extension dropped.
+{meta[date]} : File modification date, in HTTP header format (e.g. "Sat, 23 Oct 2021 18:28:37 GMT")
+
+Front matter
+------------
+
+* Front matter is indicated by starting a file with a line that contains exactly three dashes and nothing else ("---\n").
+* Front matter is closed by another line that containts exactly three dashes and nothing else.
+* Every line between the opening and closing line should be key=value pairs.
+* Front matter is stored into the 'meta' dict, so you can overwrite meta[title] or meta[date] if you want to.
diff --git a/strike/sample/blog/also-exclude.html b/strike/sample/blog/also-exclude.html
new file mode 100644
index 0000000..6ce0fb1
--- /dev/null
+++ b/strike/sample/blog/also-exclude.html
@@ -0,0 +1 @@
+This file shouldn't be processed by Strike either.
diff --git a/strike/sample/blog/empty.html b/strike/sample/blog/empty.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/strike/sample/blog/empty.html
diff --git a/strike/sample/blog/exclude.html b/strike/sample/blog/exclude.html
new file mode 100644
index 0000000..d881dce
--- /dev/null
+++ b/strike/sample/blog/exclude.html
@@ -0,0 +1 @@
+This file should be excluded from processing when Strike is processed using strike.ini
diff --git a/strike/sample/blog/happy.html b/strike/sample/blog/happy.html
new file mode 100644
index 0000000..af5626b
--- /dev/null
+++ b/strike/sample/blog/happy.html
@@ -0,0 +1 @@
+Hello, world!
diff --git a/strike/sample/blog/subdir/index.html b/strike/sample/blog/subdir/index.html
new file mode 100644
index 0000000..b66efd5
--- /dev/null
+++ b/strike/sample/blog/subdir/index.html
@@ -0,0 +1 @@
+This file in a subdirectory of the input directory should also be processed.
diff --git a/strike/sample/blog/with-frontmatter.html b/strike/sample/blog/with-frontmatter.html
new file mode 100644
index 0000000..5195292
--- /dev/null
+++ b/strike/sample/blog/with-frontmatter.html
@@ -0,0 +1,6 @@
+---
+title=Custom Title
+---
+Things before this line should not appear in the output.
+---
+Including the delimiter in body content shouldn't be an issue.
diff --git a/strike/sample/html/empty.html b/strike/sample/html/empty.html
new file mode 100644
index 0000000..b1a01ea
--- /dev/null
+++ b/strike/sample/html/empty.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang=en-US dir=ltr>
+<title>empty</title>
+<meta charset=UTF-8>
+<meta name=robots content="noindex, nofollow">
+<meta name=viewport content="width=device-width, initial-scale=1">
+<meta http-equiv=last-modified content="Fri, 29 Oct 2021 04:55:33 GMT">
+
+<section>
+	
+</section>
+<footer>
+	<p>This page was generated by <a href=https://git.starfall.systems/strike>Strike</a>.  
+</footer>
diff --git a/strike/sample/html/happy.html b/strike/sample/html/happy.html
new file mode 100644
index 0000000..9f4b32f
--- /dev/null
+++ b/strike/sample/html/happy.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang=en-US dir=ltr>
+<title>happy</title>
+<meta charset=UTF-8>
+<meta name=robots content="noindex, nofollow">
+<meta name=viewport content="width=device-width, initial-scale=1">
+<meta http-equiv=last-modified content="Fri, 29 Oct 2021 04:55:33 GMT">
+
+<section>
+	Hello, world!
+
+</section>
+<footer>
+	<p>This page was generated by <a href=https://git.starfall.systems/strike>Strike</a>.  
+</footer>
diff --git a/strike/sample/html/subdir/index.html b/strike/sample/html/subdir/index.html
new file mode 100644
index 0000000..bdeaad0
--- /dev/null
+++ b/strike/sample/html/subdir/index.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang=en-US dir=ltr>
+<title>index</title>
+<meta charset=UTF-8>
+<meta name=robots content="noindex, nofollow">
+<meta name=viewport content="width=device-width, initial-scale=1">
+<meta http-equiv=last-modified content="Fri, 29 Oct 2021 22:31:45 GMT">
+
+<section>
+	This file in a subdirectory of the input directory should also be processed.
+
+</section>
+<footer>
+	<p>This page was generated by <a href=https://git.starfall.systems/strike>Strike</a>.  
+</footer>
diff --git a/strike/sample/html/with-frontmatter.html b/strike/sample/html/with-frontmatter.html
new file mode 100644
index 0000000..99627a1
--- /dev/null
+++ b/strike/sample/html/with-frontmatter.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang=en-US dir=ltr>
+<title>Custom Title</title>
+<meta charset=UTF-8>
+<meta name=robots content="noindex, nofollow">
+<meta name=viewport content="width=device-width, initial-scale=1">
+<meta http-equiv=last-modified content="Fri, 29 Oct 2021 04:55:33 GMT">
+
+<section>
+	Things before this line should not appear in the output.
+---
+Including the delimiter in body content shouldn't be an issue.
+
+</section>
+<footer>
+	<p>This page was generated by <a href=https://git.starfall.systems/strike>Strike</a>.  
+</footer>
diff --git a/strike/sample/strike.ini b/strike/sample/strike.ini
new file mode 100644
index 0000000..86bc8c3
--- /dev/null
+++ b/strike/sample/strike.ini
@@ -0,0 +1,19 @@
+[Input]
+# Directory with all of the markup files that you want Strike to process.
+# Location should be relative to this config file.
+directory = blog
+# Files in the input directory to exclude.
+# Location should be relative to the default input directory.
+excludes = exclude.html
+	also-exclude.html
+
+[Templates]
+# For now, Strike only supports using a single template, named default.
+default = template.html
+
+[Output]
+# Directory to put the output into.
+directory = html
+
+# That's all for now. In the future, we hope to allow the use of multiple templates,
+# letting you choose individual directories and files for each template.
diff --git a/strike/sample/template.html b/strike/sample/template.html
new file mode 100644
index 0000000..2552906
--- /dev/null
+++ b/strike/sample/template.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang=en-US dir=ltr>
+<title>{meta[title]}</title>
+<meta charset=UTF-8>
+<meta name=robots content="noindex, nofollow">
+<meta name=viewport content="width=device-width, initial-scale=1">
+<meta http-equiv=last-modified content="{meta[date]}">
+
+<section>
+	{content}
+</section>
+<footer>
+	<p>This page was generated by <a href=https://git.starfall.systems/strike>Strike</a>.  
+</footer>
diff --git a/strike/strike.py b/strike/strike.py
new file mode 100644
index 0000000..03d991e
--- /dev/null
+++ b/strike/strike.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+import os
+from time import gmtime, strftime
+from argparse import ArgumentParser
+from configparser import ConfigParser
+from pathlib import Path
+
+def handle_args():
+	parser = ArgumentParser()
+	parser.add_argument('config', help='location of strike.ini file (or a directory containing it)')
+	return parser.parse_args()
+
+def read_config(location):
+	location = Path(location)
+	config = ConfigParser()
+	if location.is_dir():
+		location = location/'strike.ini'
+	if not location.exists():
+		raise FileNotFoundError(f'Config file not found at {location}.')
+	config.read(location)
+	return location.resolve().parent, config
+
+def handle_file(file):
+	meta = dict(
+		title = file.stem,
+		date = strftime('%a, %d %b %Y %H:%M:%S GMT', gmtime(file.stat().st_mtime))
+	)
+	contents = file.read_text()
+	delim = '---\n'
+	if contents.startswith(delim):
+		parts = contents.split(delim, maxsplit=2)
+		meta.update(dict((key.strip(), value.strip())
+			for key, value in (line.split('=') for line in parts[1].splitlines())
+		))
+		contents = parts[2]
+	return contents, meta
+
+def apply_template(content, meta, template="{content}"):
+	return template.format(
+		content = content,
+		meta = meta
+	)
+
+def main():
+	args = handle_args()
+	basedir, config = read_config(args.config)
+
+	input_dir = basedir/config['Input']['directory']
+
+	try: exclusions = config['Input']['excludes'].splitlines()
+	except KeyError: exclusions = {}
+
+	default_template = basedir/config['Templates']['default']
+	template = default_template.read_text()
+
+	output_dir = basedir/config['Output']['directory']
+
+	for path, _, files in os.walk(input_dir):
+		loc = os.path.relpath(path, input_dir)
+		(output_dir/loc).mkdir(parents=True, exist_ok=True)
+		for file in files:
+			if file in exclusions:
+				continue
+			contents, meta = handle_file(input_dir/loc/file)
+			output = apply_template(contents, meta, template)
+			(output_dir/loc/file).write_text(output)
+
+if __name__ == '__main__':
+	import sys
+	sys.exit(main())