qrn 0.10.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qrn-0.10.0/.DS_Store +0 -0
- qrn-0.10.0/.gitignore +135 -0
- qrn-0.10.0/LICENSE +21 -0
- qrn-0.10.0/Makefile +21 -0
- qrn-0.10.0/PKG-INFO +166 -0
- qrn-0.10.0/README.md +130 -0
- qrn-0.10.0/examples/.DS_Store +0 -0
- qrn-0.10.0/examples/simple/Makefile +24 -0
- qrn-0.10.0/examples/simple/src/_layouts/_footer.haml +15 -0
- qrn-0.10.0/examples/simple/src/_layouts/_head.haml +19 -0
- qrn-0.10.0/examples/simple/src/_layouts/_masthead.haml +6 -0
- qrn-0.10.0/examples/simple/src/_layouts/_menu.haml +13 -0
- qrn-0.10.0/examples/simple/src/_layouts/_sidebar.haml +4 -0
- qrn-0.10.0/examples/simple/src/_layouts/article.haml +21 -0
- qrn-0.10.0/examples/simple/src/_layouts/default.haml +22 -0
- qrn-0.10.0/examples/simple/src/_layouts/example.html +319 -0
- qrn-0.10.0/examples/simple/src/_layouts/page.haml +15 -0
- qrn-0.10.0/examples/simple/src/articles/first_post.md +26 -0
- qrn-0.10.0/examples/simple/src/articles/second_post.md +19 -0
- qrn-0.10.0/examples/simple/src/articles/third_post.haml +22 -0
- qrn-0.10.0/examples/simple/src/index.md +91 -0
- qrn-0.10.0/examples/simple/src/page2.md +12 -0
- qrn-0.10.0/examples/simple/src/page3.md +12 -0
- qrn-0.10.0/examples/simple/src/stylesheets/_colors.scss +17 -0
- qrn-0.10.0/examples/simple/src/stylesheets/_custom.scss +298 -0
- qrn-0.10.0/examples/simple/src/stylesheets/_fonts.scss +19 -0
- qrn-0.10.0/examples/simple/src/stylesheets/_normalize.css +427 -0
- qrn-0.10.0/examples/simple/src/stylesheets/_skeleton.css +418 -0
- qrn-0.10.0/examples/simple/src/stylesheets/styles.scss +45 -0
- qrn-0.10.0/examples/simple/static.py +25 -0
- qrn-0.10.0/examples/walden/Makefile +24 -0
- qrn-0.10.0/examples/walden/process.py +22 -0
- qrn-0.10.0/examples/walden/src/205-0.txt +10598 -0
- qrn-0.10.0/examples/walden/src/_layouts/_footer.haml +28 -0
- qrn-0.10.0/examples/walden/src/_layouts/_head.haml +19 -0
- qrn-0.10.0/examples/walden/src/_layouts/_masthead.haml +6 -0
- qrn-0.10.0/examples/walden/src/_layouts/_menu.haml +13 -0
- qrn-0.10.0/examples/walden/src/_layouts/_sidebar.haml +4 -0
- qrn-0.10.0/examples/walden/src/_layouts/default.haml +18 -0
- qrn-0.10.0/examples/walden/src/_layouts/extra.haml +1 -0
- qrn-0.10.0/examples/walden/src/_layouts/page.haml +17 -0
- qrn-0.10.0/examples/walden/src/articles/attrs.py +23 -0
- qrn-0.10.0/examples/walden/src/articles/baker-farm.md +252 -0
- qrn-0.10.0/examples/walden/src/articles/brute-neighbors.md +415 -0
- qrn-0.10.0/examples/walden/src/articles/conclusion.haml +416 -0
- qrn-0.10.0/examples/walden/src/articles/economy.md +2809 -0
- qrn-0.10.0/examples/walden/src/articles/former-inhabitants-and-winter-visitors.md +430 -0
- qrn-0.10.0/examples/walden/src/articles/higher-laws.md +375 -0
- qrn-0.10.0/examples/walden/src/articles/house-warming.md +511 -0
- qrn-0.10.0/examples/walden/src/articles/reading.md +335 -0
- qrn-0.10.0/examples/walden/src/articles/solitude.md +309 -0
- qrn-0.10.0/examples/walden/src/articles/sounds.html +47 -0
- qrn-0.10.0/examples/walden/src/articles/spring.md +596 -0
- qrn-0.10.0/examples/walden/src/articles/the-bean-field.md +364 -0
- qrn-0.10.0/examples/walden/src/articles/the-pond-in-winter.md +464 -0
- qrn-0.10.0/examples/walden/src/articles/the-ponds.md +791 -0
- qrn-0.10.0/examples/walden/src/articles/the-village.md +180 -0
- qrn-0.10.0/examples/walden/src/articles/visitors.md +429 -0
- qrn-0.10.0/examples/walden/src/articles/where_i_ived_and_what_i_lived_for.md +525 -0
- qrn-0.10.0/examples/walden/src/articles/winter-animals.md +320 -0
- qrn-0.10.0/examples/walden/src/credit.md +41 -0
- qrn-0.10.0/examples/walden/src/index.md +22 -0
- qrn-0.10.0/examples/walden/src/license.md +383 -0
- qrn-0.10.0/examples/walden/src/stylesheets/_colors.scss +17 -0
- qrn-0.10.0/examples/walden/src/stylesheets/_custom.scss +298 -0
- qrn-0.10.0/examples/walden/src/stylesheets/_fonts.scss +19 -0
- qrn-0.10.0/examples/walden/src/stylesheets/_normalize.css +427 -0
- qrn-0.10.0/examples/walden/src/stylesheets/_skeleton.css +418 -0
- qrn-0.10.0/examples/walden/src/stylesheets/styles.scss +6 -0
- qrn-0.10.0/examples/walden/static.py +26 -0
- qrn-0.10.0/pyproject.toml +24 -0
- qrn-0.10.0/src/qrn/__init__.py +0 -0
- qrn-0.10.0/src/qrn/code_generator.py +66 -0
- qrn-0.10.0/src/qrn/components.py +94 -0
- qrn-0.10.0/src/qrn/converters.py +41 -0
- qrn-0.10.0/src/qrn/epy.py +64 -0
- qrn-0.10.0/src/qrn/expander.py +173 -0
- qrn-0.10.0/src/qrn/paml.py +133 -0
- qrn-0.10.0/src/qrn/paml_line_parser.py +124 -0
- qrn-0.10.0/src/qrn/paml_node.py +141 -0
- qrn-0.10.0/src/qrn/pipeline.py +42 -0
- qrn-0.10.0/src/qrn/qrn.py +209 -0
- qrn-0.10.0/src/qrn/rss.py +80 -0
- qrn-0.10.0/src/qrn/utils.py +249 -0
qrn-0.10.0/.DS_Store
ADDED
|
Binary file
|
qrn-0.10.0/.gitignore
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Doctrine specific files
|
|
2
|
+
generated.py
|
|
3
|
+
|
|
4
|
+
# Editor files
|
|
5
|
+
*.sw[onp]
|
|
6
|
+
|
|
7
|
+
# Byte-compiled / optimized / DLL files
|
|
8
|
+
__pycache__/
|
|
9
|
+
*.py[cod]
|
|
10
|
+
*$py.class
|
|
11
|
+
|
|
12
|
+
# C extensions
|
|
13
|
+
*.so
|
|
14
|
+
|
|
15
|
+
# Distribution / packaging
|
|
16
|
+
.Python
|
|
17
|
+
build/
|
|
18
|
+
develop-eggs/
|
|
19
|
+
dist/
|
|
20
|
+
downloads/
|
|
21
|
+
eggs/
|
|
22
|
+
.eggs/
|
|
23
|
+
lib/
|
|
24
|
+
lib64/
|
|
25
|
+
parts/
|
|
26
|
+
sdist/
|
|
27
|
+
var/
|
|
28
|
+
wheels/
|
|
29
|
+
pip-wheel-metadata/
|
|
30
|
+
share/python-wheels/
|
|
31
|
+
*.egg-info/
|
|
32
|
+
.installed.cfg
|
|
33
|
+
*.egg
|
|
34
|
+
MANIFEST
|
|
35
|
+
|
|
36
|
+
# PyInstaller
|
|
37
|
+
# Usually these files are written by a python script from a template
|
|
38
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
39
|
+
*.manifest
|
|
40
|
+
*.spec
|
|
41
|
+
|
|
42
|
+
# Installer logs
|
|
43
|
+
pip-log.txt
|
|
44
|
+
pip-delete-this-directory.txt
|
|
45
|
+
|
|
46
|
+
# Unit test / coverage reports
|
|
47
|
+
htmlcov/
|
|
48
|
+
.tox/
|
|
49
|
+
.nox/
|
|
50
|
+
.coverage
|
|
51
|
+
.coverage.*
|
|
52
|
+
.cache
|
|
53
|
+
nosetests.xml
|
|
54
|
+
coverage.xml
|
|
55
|
+
*.cover
|
|
56
|
+
*.py,cover
|
|
57
|
+
.hypothesis/
|
|
58
|
+
.pytest_cache/
|
|
59
|
+
|
|
60
|
+
# Translations
|
|
61
|
+
*.mo
|
|
62
|
+
*.pot
|
|
63
|
+
|
|
64
|
+
# Django stuff:
|
|
65
|
+
*.log
|
|
66
|
+
local_settings.py
|
|
67
|
+
db.sqlite3
|
|
68
|
+
db.sqlite3-journal
|
|
69
|
+
|
|
70
|
+
# Flask stuff:
|
|
71
|
+
instance/
|
|
72
|
+
.webassets-cache
|
|
73
|
+
|
|
74
|
+
# Scrapy stuff:
|
|
75
|
+
.scrapy
|
|
76
|
+
|
|
77
|
+
# Sphinx documentation
|
|
78
|
+
docs/_build/
|
|
79
|
+
|
|
80
|
+
# PyBuilder
|
|
81
|
+
target/
|
|
82
|
+
|
|
83
|
+
# Jupyter Notebook
|
|
84
|
+
.ipynb_checkpoints
|
|
85
|
+
|
|
86
|
+
# IPython
|
|
87
|
+
profile_default/
|
|
88
|
+
ipython_config.py
|
|
89
|
+
|
|
90
|
+
# pyenv
|
|
91
|
+
.python-version
|
|
92
|
+
|
|
93
|
+
# pipenv
|
|
94
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
95
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
96
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
97
|
+
# install all needed dependencies.
|
|
98
|
+
#Pipfile.lock
|
|
99
|
+
|
|
100
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
101
|
+
__pypackages__/
|
|
102
|
+
|
|
103
|
+
# Celery stuff
|
|
104
|
+
celerybeat-schedule
|
|
105
|
+
celerybeat.pid
|
|
106
|
+
|
|
107
|
+
# SageMath parsed files
|
|
108
|
+
*.sage.py
|
|
109
|
+
|
|
110
|
+
# Environments
|
|
111
|
+
.env
|
|
112
|
+
.venv
|
|
113
|
+
env/
|
|
114
|
+
venv/
|
|
115
|
+
ENV/
|
|
116
|
+
env.bak/
|
|
117
|
+
venv.bak/
|
|
118
|
+
|
|
119
|
+
# Spyder project settings
|
|
120
|
+
.spyderproject
|
|
121
|
+
.spyproject
|
|
122
|
+
|
|
123
|
+
# Rope project settings
|
|
124
|
+
.ropeproject
|
|
125
|
+
|
|
126
|
+
# mkdocs documentation
|
|
127
|
+
/site
|
|
128
|
+
|
|
129
|
+
# mypy
|
|
130
|
+
.mypy_cache/
|
|
131
|
+
.dmypy.json
|
|
132
|
+
dmypy.json
|
|
133
|
+
|
|
134
|
+
# Pyre type checker
|
|
135
|
+
.pyre/
|
qrn-0.10.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Russ Olsen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
qrn-0.10.0/Makefile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
PYTHON=pypy3
|
|
3
|
+
DST_DIR=dist
|
|
4
|
+
|
|
5
|
+
build: $(DST_DIR)
|
|
6
|
+
$(PYTHON) -m build
|
|
7
|
+
|
|
8
|
+
$(DST_DIR):
|
|
9
|
+
mkdir -f $@
|
|
10
|
+
|
|
11
|
+
package:
|
|
12
|
+
$(PYTHON) -m build
|
|
13
|
+
|
|
14
|
+
install_local:
|
|
15
|
+
$(PYTHON) -m pip install .
|
|
16
|
+
|
|
17
|
+
upload_test:
|
|
18
|
+
twine upload -r testpypi dist/*
|
|
19
|
+
|
|
20
|
+
clean:
|
|
21
|
+
rm -rf $(DST_DIR)/*
|
qrn-0.10.0/PKG-INFO
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: qrn
|
|
3
|
+
Version: 0.10.0
|
|
4
|
+
Summary: A simple static site generator
|
|
5
|
+
Project-URL: Homepage, https://github.com/russolsen/qrn
|
|
6
|
+
Project-URL: Bug Tracker, https://github.com/russolsen/qrn/issues
|
|
7
|
+
Author-email: Russ Olsen <russ@russolsen.com>
|
|
8
|
+
License: MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2022 Russ Olsen
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
31
|
+
Classifier: Operating System :: OS Independent
|
|
32
|
+
Classifier: Programming Language :: Python :: 3
|
|
33
|
+
Requires-Python: >=3.7
|
|
34
|
+
Requires-Dist: pyyaml>=6.0
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# QRN: A simple, highly opinionated static site generator
|
|
38
|
+
|
|
39
|
+
QRN is a static site generator that is as simple as I can make
|
|
40
|
+
it while still being useful. QRN assumes that most of your content
|
|
41
|
+
is in markdown format, that you are using sass/scss or plain old css
|
|
42
|
+
for styling. QRN is also geared towards modest sized content, the
|
|
43
|
+
kind of thing you might find in a personal blog.
|
|
44
|
+
|
|
45
|
+
QRN also supports a simple but flexible layout/templating system
|
|
46
|
+
that let's you specify a standard HTML "frame" around your content
|
|
47
|
+
and also embed executable Python code in the content.
|
|
48
|
+
|
|
49
|
+
A key feature of QRN is that it has very few external dependencies.
|
|
50
|
+
QRN is written in a fairly generic Python 3 and requires:
|
|
51
|
+
|
|
52
|
+
* The PyYAML Python library.
|
|
53
|
+
* An external program that turns markdown into HTML (currently pandoc).
|
|
54
|
+
* And external program that turns scss/sass into css (currently sass).
|
|
55
|
+
|
|
56
|
+
That's it. What this means is that QRN is easy to set up and
|
|
57
|
+
(I hope) will continue to work over time as libararies and packages
|
|
58
|
+
change.
|
|
59
|
+
|
|
60
|
+
## What does QRN mean?
|
|
61
|
+
|
|
62
|
+
Ham radio operators use a [shorthand code](https://fieldradio.org/ham-radio-q-codes)
|
|
63
|
+
that has its origins in the early days of telegraphy. QRN is the code that means
|
|
64
|
+
"I am troubled by static noise."
|
|
65
|
+
|
|
66
|
+
## Using QRN
|
|
67
|
+
|
|
68
|
+
QRN works like most static site generators: You prepare a directory with
|
|
69
|
+
roughly the content you want to show up in your final site. When you run
|
|
70
|
+
QRN it transforms your source content into a final output site that you can
|
|
71
|
+
then deploy. The value of QRN is that it performs various transformation as
|
|
72
|
+
it does the copying:
|
|
73
|
+
|
|
74
|
+
* QRN knows how to tranform markdown files into html.
|
|
75
|
+
* QRN knows how to do "include" processing on your content so
|
|
76
|
+
that you can write the common parts of your site once.
|
|
77
|
+
|
|
78
|
+
The key idea behind QRN is that it is extremely opinionated about a few
|
|
79
|
+
things -- mostly around a some key naming conventions and how those
|
|
80
|
+
files are processed into your final static webstite.
|
|
81
|
+
|
|
82
|
+
Specifically:
|
|
83
|
+
|
|
84
|
+
* QRN wants you to put the source for your site under a directory called `src`.
|
|
85
|
+
* QRN generally ignores files and directories whose names start with an underbar (.e.g. `src/_save`).
|
|
86
|
+
* QRN wants you to put the source for all included files and layouts (see below) in `src/_layouts`.
|
|
87
|
+
* When you run QRN it will put the resulting processed, read-to-go site in a directory called `build`.
|
|
88
|
+
* QRN will run all files with a `.html` or `.xml` extension through the `epy` processor (see below).
|
|
89
|
+
* QRN will run all files with a `.haml` extension through the `paml` processor (see below).
|
|
90
|
+
* QRN will run all files with a `.md` extension through the `epy` processor and then convert it to HTML.
|
|
91
|
+
* QRN will run all files with a `.sass` or `.scss` extension through the `sass` processor.
|
|
92
|
+
* Otherwise, QRN will just copy files from `src` to `build`.
|
|
93
|
+
|
|
94
|
+
## File headers and layouts.
|
|
95
|
+
|
|
96
|
+
In general, QRN will recognize YAML headers at the beginning of .md, .html, .xml and .haml files. The headers
|
|
97
|
+
are set off from the file content with three dashes:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
---
|
|
101
|
+
title: A simple html file.
|
|
102
|
+
date: klsdfklj
|
|
103
|
+
---
|
|
104
|
+
<html>
|
|
105
|
+
<body>
|
|
106
|
+
<title>A simple html file.</title>
|
|
107
|
+
</body>
|
|
108
|
+
</html>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## The EPy Processor
|
|
112
|
+
|
|
113
|
+
As mentioned above, QRN runs .md, .html and .xml files through the Embedded Python (or EPy) processor.
|
|
114
|
+
EPy allows you to embed code that is evaluated at site build time in your content.
|
|
115
|
+
EPy uses the common `text <%= some_code() %> more text` syntax, reminencent of
|
|
116
|
+
[Embedded Ruby](https://en.wikipedia.org/wiki/ERuby). Specifically:
|
|
117
|
+
|
|
118
|
+
* `<%= some_code() %>` will insert the result of evaluating the Python code into the text. Thus `1 <%= 100/50 %> 3`
|
|
119
|
+
will result in `1 2 3`.
|
|
120
|
+
* `<%! other_code() !%>` will simply evaluate the Python code and ignore the result.
|
|
121
|
+
|
|
122
|
+
Python's indentation based approach to syntax presents a special challenge to EPy: Requiring significant whitespace
|
|
123
|
+
in embedded code would be error prone and confusing. Instead, EPy strips off leading whitespace and relies on the
|
|
124
|
+
training `:`'s to open code blocks and a special <%! end %> directive to close them. Here, for example is a
|
|
125
|
+
loop in EPy:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
<%! for x in range(1): %>
|
|
129
|
+
The number is <%= x %>
|
|
130
|
+
<%! end %>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
And an `if` statement in EPy:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
<%! count = 0 %>
|
|
137
|
+
<%! if count: %>
|
|
138
|
+
The count is non-zero.
|
|
139
|
+
<%! else: %>
|
|
140
|
+
The counts is zero.
|
|
141
|
+
<%! end %>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Note that the `<%! end %>` does not appear in the actual Python code. It
|
|
145
|
+
is just a marker that the `if` or `for` has ended.
|
|
146
|
+
|
|
147
|
+
## The Paml Processor
|
|
148
|
+
|
|
149
|
+
Similarly, QRN includes a "Paml" processor. Paml is like Haml, but it uses Python
|
|
150
|
+
in place of Ruby. Other than that syntax is more or less Haml. Here's an example:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
---
|
|
154
|
+
kind: partial
|
|
155
|
+
---
|
|
156
|
+
.twelve.columns
|
|
157
|
+
%ul.menu
|
|
158
|
+
%li.menu
|
|
159
|
+
%a{"href": "/index.html"} Contents
|
|
160
|
+
%li.menu
|
|
161
|
+
%a{"href": "/credit.html"} Credits
|
|
162
|
+
%li.menu
|
|
163
|
+
%a{"href": "/license.html"} License
|
|
164
|
+
%li.menu
|
|
165
|
+
%a{"href": "/205-0.txt"} Original File
|
|
166
|
+
```
|
qrn-0.10.0/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# QRN: A simple, highly opinionated static site generator
|
|
2
|
+
|
|
3
|
+
QRN is a static site generator that is as simple as I can make
|
|
4
|
+
it while still being useful. QRN assumes that most of your content
|
|
5
|
+
is in markdown format, that you are using sass/scss or plain old css
|
|
6
|
+
for styling. QRN is also geared towards modest sized content, the
|
|
7
|
+
kind of thing you might find in a personal blog.
|
|
8
|
+
|
|
9
|
+
QRN also supports a simple but flexible layout/templating system
|
|
10
|
+
that let's you specify a standard HTML "frame" around your content
|
|
11
|
+
and also embed executable Python code in the content.
|
|
12
|
+
|
|
13
|
+
A key feature of QRN is that it has very few external dependencies.
|
|
14
|
+
QRN is written in a fairly generic Python 3 and requires:
|
|
15
|
+
|
|
16
|
+
* The PyYAML Python library.
|
|
17
|
+
* An external program that turns markdown into HTML (currently pandoc).
|
|
18
|
+
* And external program that turns scss/sass into css (currently sass).
|
|
19
|
+
|
|
20
|
+
That's it. What this means is that QRN is easy to set up and
|
|
21
|
+
(I hope) will continue to work over time as libararies and packages
|
|
22
|
+
change.
|
|
23
|
+
|
|
24
|
+
## What does QRN mean?
|
|
25
|
+
|
|
26
|
+
Ham radio operators use a [shorthand code](https://fieldradio.org/ham-radio-q-codes)
|
|
27
|
+
that has its origins in the early days of telegraphy. QRN is the code that means
|
|
28
|
+
"I am troubled by static noise."
|
|
29
|
+
|
|
30
|
+
## Using QRN
|
|
31
|
+
|
|
32
|
+
QRN works like most static site generators: You prepare a directory with
|
|
33
|
+
roughly the content you want to show up in your final site. When you run
|
|
34
|
+
QRN it transforms your source content into a final output site that you can
|
|
35
|
+
then deploy. The value of QRN is that it performs various transformation as
|
|
36
|
+
it does the copying:
|
|
37
|
+
|
|
38
|
+
* QRN knows how to tranform markdown files into html.
|
|
39
|
+
* QRN knows how to do "include" processing on your content so
|
|
40
|
+
that you can write the common parts of your site once.
|
|
41
|
+
|
|
42
|
+
The key idea behind QRN is that it is extremely opinionated about a few
|
|
43
|
+
things -- mostly around a some key naming conventions and how those
|
|
44
|
+
files are processed into your final static webstite.
|
|
45
|
+
|
|
46
|
+
Specifically:
|
|
47
|
+
|
|
48
|
+
* QRN wants you to put the source for your site under a directory called `src`.
|
|
49
|
+
* QRN generally ignores files and directories whose names start with an underbar (.e.g. `src/_save`).
|
|
50
|
+
* QRN wants you to put the source for all included files and layouts (see below) in `src/_layouts`.
|
|
51
|
+
* When you run QRN it will put the resulting processed, read-to-go site in a directory called `build`.
|
|
52
|
+
* QRN will run all files with a `.html` or `.xml` extension through the `epy` processor (see below).
|
|
53
|
+
* QRN will run all files with a `.haml` extension through the `paml` processor (see below).
|
|
54
|
+
* QRN will run all files with a `.md` extension through the `epy` processor and then convert it to HTML.
|
|
55
|
+
* QRN will run all files with a `.sass` or `.scss` extension through the `sass` processor.
|
|
56
|
+
* Otherwise, QRN will just copy files from `src` to `build`.
|
|
57
|
+
|
|
58
|
+
## File headers and layouts.
|
|
59
|
+
|
|
60
|
+
In general, QRN will recognize YAML headers at the beginning of .md, .html, .xml and .haml files. The headers
|
|
61
|
+
are set off from the file content with three dashes:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
---
|
|
65
|
+
title: A simple html file.
|
|
66
|
+
date: klsdfklj
|
|
67
|
+
---
|
|
68
|
+
<html>
|
|
69
|
+
<body>
|
|
70
|
+
<title>A simple html file.</title>
|
|
71
|
+
</body>
|
|
72
|
+
</html>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## The EPy Processor
|
|
76
|
+
|
|
77
|
+
As mentioned above, QRN runs .md, .html and .xml files through the Embedded Python (or EPy) processor.
|
|
78
|
+
EPy allows you to embed code that is evaluated at site build time in your content.
|
|
79
|
+
EPy uses the common `text <%= some_code() %> more text` syntax, reminencent of
|
|
80
|
+
[Embedded Ruby](https://en.wikipedia.org/wiki/ERuby). Specifically:
|
|
81
|
+
|
|
82
|
+
* `<%= some_code() %>` will insert the result of evaluating the Python code into the text. Thus `1 <%= 100/50 %> 3`
|
|
83
|
+
will result in `1 2 3`.
|
|
84
|
+
* `<%! other_code() !%>` will simply evaluate the Python code and ignore the result.
|
|
85
|
+
|
|
86
|
+
Python's indentation based approach to syntax presents a special challenge to EPy: Requiring significant whitespace
|
|
87
|
+
in embedded code would be error prone and confusing. Instead, EPy strips off leading whitespace and relies on the
|
|
88
|
+
training `:`'s to open code blocks and a special <%! end %> directive to close them. Here, for example is a
|
|
89
|
+
loop in EPy:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
<%! for x in range(1): %>
|
|
93
|
+
The number is <%= x %>
|
|
94
|
+
<%! end %>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
And an `if` statement in EPy:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
<%! count = 0 %>
|
|
101
|
+
<%! if count: %>
|
|
102
|
+
The count is non-zero.
|
|
103
|
+
<%! else: %>
|
|
104
|
+
The counts is zero.
|
|
105
|
+
<%! end %>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Note that the `<%! end %>` does not appear in the actual Python code. It
|
|
109
|
+
is just a marker that the `if` or `for` has ended.
|
|
110
|
+
|
|
111
|
+
## The Paml Processor
|
|
112
|
+
|
|
113
|
+
Similarly, QRN includes a "Paml" processor. Paml is like Haml, but it uses Python
|
|
114
|
+
in place of Ruby. Other than that syntax is more or less Haml. Here's an example:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
---
|
|
118
|
+
kind: partial
|
|
119
|
+
---
|
|
120
|
+
.twelve.columns
|
|
121
|
+
%ul.menu
|
|
122
|
+
%li.menu
|
|
123
|
+
%a{"href": "/index.html"} Contents
|
|
124
|
+
%li.menu
|
|
125
|
+
%a{"href": "/credit.html"} Credits
|
|
126
|
+
%li.menu
|
|
127
|
+
%a{"href": "/license.html"} License
|
|
128
|
+
%li.menu
|
|
129
|
+
%a{"href": "/205-0.txt"} Original File
|
|
130
|
+
```
|
|
Binary file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
SITE_SCRIPT=static.py
|
|
2
|
+
PYTHON=pypy3
|
|
3
|
+
DST_DIR=build
|
|
4
|
+
PORT=7723
|
|
5
|
+
|
|
6
|
+
.PHONY: release
|
|
7
|
+
release: clean build
|
|
8
|
+
|
|
9
|
+
r: release
|
|
10
|
+
|
|
11
|
+
.PHONY: build
|
|
12
|
+
build:
|
|
13
|
+
$(PYTHON) static.py
|
|
14
|
+
|
|
15
|
+
.PHONY: serve
|
|
16
|
+
serve:
|
|
17
|
+
$(PYTHON) -m http.server --directory $(DST_DIR) $(PORT)
|
|
18
|
+
|
|
19
|
+
s: serve
|
|
20
|
+
|
|
21
|
+
.PHONY: clean
|
|
22
|
+
clean:
|
|
23
|
+
rm -rf $(DST_DIR)/*
|
|
24
|
+
rm -f static.log
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: partial
|
|
3
|
+
---
|
|
4
|
+
- this_no = int(self.page.get('number', -1))
|
|
5
|
+
- previous_no = find_page('number', this_no - 1)
|
|
6
|
+
- next_no = find_page('number', this_no + 1)
|
|
7
|
+
.container.footer
|
|
8
|
+
- if previous_no:
|
|
9
|
+
.navarrow#previous
|
|
10
|
+
<
|
|
11
|
+
= anchor_for_page( previous_no )
|
|
12
|
+
- if next_no:
|
|
13
|
+
.navarrow#next
|
|
14
|
+
= anchor_for_page( next_no )
|
|
15
|
+
>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: partial
|
|
3
|
+
---
|
|
4
|
+
%head
|
|
5
|
+
%meta{"charset": "utf-8"}
|
|
6
|
+
%title= page.site.title
|
|
7
|
+
|
|
8
|
+
%meta{'name': 'description' ,'content': ''}
|
|
9
|
+
%meta{'name': 'author' ,'content': ''}
|
|
10
|
+
|
|
11
|
+
%meta{'name': 'viewport', 'content': 'width=device-width, initial-scale=1, maximum-scale=1'}
|
|
12
|
+
|
|
13
|
+
%link{'rel': "stylesheet", 'href': '/stylesheets/styles.css'}
|
|
14
|
+
|
|
15
|
+
%link{"rel": "shortcut icon",'href': "images/favicon.ico"}
|
|
16
|
+
%link{"rel": "apple-touch-icon",'href': "images/apple-touch-icon.png"}
|
|
17
|
+
%link{"rel": "apple-touch-icon",'sizes': "72x72",'href': "images/apple-touch-icon-72x72.png"}
|
|
18
|
+
%link{"rel": "apple-touch-icon",'sizes': "114x114",'href':"images/apple-touch-icon-114x114.png"}
|
|
19
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: partial
|
|
3
|
+
---
|
|
4
|
+
.twelve.columns
|
|
5
|
+
%ul.menu
|
|
6
|
+
%li.menu
|
|
7
|
+
%a{"href": "/index.html"} Contents
|
|
8
|
+
%li.menu
|
|
9
|
+
%a{"href": "/credit.html"} Credits
|
|
10
|
+
%li.menu
|
|
11
|
+
%a{"href": "/license.html"} License
|
|
12
|
+
%li.menu
|
|
13
|
+
%a{"href": "/205-0.txt"} Original File
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: layout
|
|
3
|
+
---
|
|
4
|
+
%html
|
|
5
|
+
= include('_head.haml')
|
|
6
|
+
%body
|
|
7
|
+
#header
|
|
8
|
+
%a{"href": "/"}
|
|
9
|
+
= self.page.site.title
|
|
10
|
+
.main
|
|
11
|
+
%h1#articleTitle
|
|
12
|
+
= self.page.title
|
|
13
|
+
#content
|
|
14
|
+
#authors
|
|
15
|
+
%a{"href": "https://example.com"}= self.page.author
|
|
16
|
+
,
|
|
17
|
+
= self.page.date
|
|
18
|
+
#article
|
|
19
|
+
= include(self.path, full_path=True)
|
|
20
|
+
#footer
|
|
21
|
+
= include('_footer.haml')
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: layout
|
|
3
|
+
---
|
|
4
|
+
%html
|
|
5
|
+
= include('_head.haml')
|
|
6
|
+
%body
|
|
7
|
+
.container.page
|
|
8
|
+
.row
|
|
9
|
+
.twelve.columns.header
|
|
10
|
+
= include('_masthead.haml')
|
|
11
|
+
.row
|
|
12
|
+
.row
|
|
13
|
+
.twelve.columns.left.main
|
|
14
|
+
%h2= self.page.title
|
|
15
|
+
%h3
|
|
16
|
+
By
|
|
17
|
+
= self.page.author
|
|
18
|
+
.text
|
|
19
|
+
= include(self.path, full_path=True)
|
|
20
|
+
.row
|
|
21
|
+
.twelve.columns.left.footer
|
|
22
|
+
= include('_footer.haml')
|