Compare commits
5 Commits
e73b957161
...
2e240aa147
Author | SHA1 | Date | |
---|---|---|---|
2e240aa147 | |||
0279d5f064 | |||
a8e4ba69f9 | |||
2c9524aa55 | |||
da516c96bd |
6
Makefile
6
Makefile
@ -1,16 +1,18 @@
|
||||
all: build
|
||||
|
||||
build:
|
||||
# Build Python package
|
||||
test -d build/ && rm -rf build/ || true
|
||||
test -d dist/ && rm -rf dist/ || true
|
||||
test -d *.egg-info/ && rm -rf *.egg-info/ || true
|
||||
# python setup.py sdist bdist_wheel
|
||||
python -m build
|
||||
rm -rv *.egg-info/
|
||||
|
||||
install:
|
||||
# Install package from built tarball
|
||||
pip install dist/*.tar.gz
|
||||
|
||||
dist:
|
||||
cp:
|
||||
# Copy package to site downloads dir
|
||||
mkdir -p docs/static/downloads
|
||||
cp dist/*.tar.gz docs/static/downloads/
|
||||
|
117
README
117
README
@ -1,6 +1,117 @@
|
||||
reStructuredWeb -- static site generator.
|
||||
=====
|
||||
[rSW]
|
||||
=====
|
||||
|
||||
reStructuredWeb (rSW, reSW or rstW) -- is a highly customizable static site
|
||||
generator for the reStructuredText markup language.
|
||||
|
||||
Docs:
|
||||
|
||||
* https://nixhacks.net/rstw/
|
||||
* https://git/nxhs.cloud/ge/rstw_docs/
|
||||
* https://nixhacks.net/rsw/
|
||||
* https://git.nxhs.cloud/ge/rSW/src/branch/master/docs
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
From PyPI
|
||||
---------
|
||||
|
||||
::
|
||||
|
||||
pip install reSW
|
||||
|
||||
From tarball
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
pip install ./reSW-0.1.2.tar.gz
|
||||
|
||||
Shell completion
|
||||
----------------
|
||||
|
||||
::
|
||||
|
||||
pip install infi.docopt-completion
|
||||
docopt-completion rsw
|
||||
|
||||
Quick start
|
||||
===========
|
||||
|
||||
1. Initialise site with following commands::
|
||||
|
||||
rsw init my_site
|
||||
cd my_site
|
||||
|
||||
2. Create first template and post.
|
||||
|
||||
Template layouts/template.jinja2::
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{ page.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
{{ html | safe }}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Post content/index.rst::
|
||||
|
||||
:title: Hello, World!
|
||||
:date: 1970-01-01
|
||||
|
||||
=============
|
||||
Hello, World!
|
||||
=============
|
||||
|
||||
Hello, there! This is my first site built with *re*\ **Structured**\ *Web*!
|
||||
|
||||
3. Build your site::
|
||||
|
||||
rsw build
|
||||
|
||||
Command Line Interface
|
||||
======================
|
||||
|
||||
::
|
||||
|
||||
Usage: rsw init [--no-makefile] [<name>]
|
||||
rsw build [-c <file>]
|
||||
rsw print [-c <file>] [--default] [--json]
|
||||
rsw (-h | --help | -v | --version)
|
||||
|
||||
Commands:
|
||||
init initialise new site.
|
||||
build build site.
|
||||
print print configuration.
|
||||
|
||||
Options:
|
||||
-c <file>, --config <file> configuaration file.
|
||||
-j, --json JSON output.
|
||||
-d, --default print default config.
|
||||
-M, --no-makefile do not create Makefile.
|
||||
-h, --help print this help message and exit.
|
||||
-v, --version print version and exit.
|
||||
|
||||
Development
|
||||
===========
|
||||
|
||||
Build Python package
|
||||
--------------------
|
||||
|
||||
Variant 1::
|
||||
|
||||
pip install setuptools wheel twine
|
||||
python setup.py sdist bdist_wheel
|
||||
|
||||
Variant 2::
|
||||
|
||||
pip install -U build
|
||||
python -m build
|
||||
|
||||
Via Makefile (`build` package needed)::
|
||||
|
||||
make build
|
||||
|
2
docs/.gitignore
vendored
Normal file
2
docs/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
build/
|
||||
downloads/
|
36
docs/Makefile
Normal file
36
docs/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
# Makefile for reSW
|
||||
|
||||
CONTENTDIR = content
|
||||
STATICDIR = static
|
||||
BUILDDIR = build
|
||||
CONFIG = settings.toml
|
||||
|
||||
all: build
|
||||
|
||||
help:
|
||||
@echo 'Build rSW site'
|
||||
@echo
|
||||
@echo 'Available targets:'
|
||||
@echo
|
||||
@echo ' build build HTML'
|
||||
@echo ' serve run local HTTP server'
|
||||
@echo ' css <theme> generate Pygments stylesheet'
|
||||
@echo
|
||||
@echo 'Run make without target to build html'
|
||||
|
||||
build:
|
||||
test -d "$(BUILDDIR)" && rm -rf "$(BUILDDIR)" || true
|
||||
rsw build -c "$(CONFIG)"
|
||||
|
||||
serve:
|
||||
python -m http.server --directory $(BUILDDIR)/ --bind 0.0.0.0 8080
|
||||
|
||||
css:
|
||||
mkdir -pv "$(STATICDIR)"/css/pygments
|
||||
pygmentize -f html -S $(filter-out $@,$(MAKECMDGOALS)) -a .highlight \
|
||||
> "$(STATICDIR)"/css/pygments/$(filter-out $@,$(MAKECMDGOALS)).css
|
||||
|
||||
%:
|
||||
@:
|
||||
|
||||
.PHONY: all help build serve css
|
39
docs/content/cli.rst
Normal file
39
docs/content/cli.rst
Normal file
@ -0,0 +1,39 @@
|
||||
:title: Command Line Interface
|
||||
:date: 2022-09-30
|
||||
|
||||
======================
|
||||
Command Line Interface
|
||||
======================
|
||||
|
||||
::
|
||||
|
||||
Usage: rsw init [--no-makefile] [<name>]
|
||||
rsw build [-c <file>]
|
||||
rsw print [-c <file>] [--default] [--json]
|
||||
rsw (-h | --help | -v | --version)
|
||||
|
||||
Commands:
|
||||
init initialise new site.
|
||||
build build site.
|
||||
print print configuration.
|
||||
|
||||
Options:
|
||||
-c <file>, --config <file> configuaration file.
|
||||
-j, --json JSON output.
|
||||
-d, --default print default config.
|
||||
-M, --no-makefile do not create Makefile.
|
||||
-h, --help print this help message and exit.
|
||||
-v, --version print version and exit.
|
||||
|
||||
Makefile usage
|
||||
==============
|
||||
|
||||
::
|
||||
|
||||
Available targets:
|
||||
|
||||
build build HTML
|
||||
serve run local HTTP server
|
||||
css <theme> generate Pygments stylesheet
|
||||
|
||||
Run make without target to build html
|
71
docs/content/configuration.rst
Normal file
71
docs/content/configuration.rst
Normal file
@ -0,0 +1,71 @@
|
||||
:title: Configuration
|
||||
:date: 2022-09-22
|
||||
|
||||
=============
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Dirs (``dirs``)
|
||||
===============
|
||||
|
||||
build_dir
|
||||
Default: build
|
||||
|
||||
content_dir
|
||||
Default: content
|
||||
|
||||
templates_dir
|
||||
Default: layouts
|
||||
|
||||
static_dir
|
||||
Default: static
|
||||
|
||||
.. note::
|
||||
|
||||
Content of this diretory will be placed into site root. Use
|
||||
subdirectories for files here, e.g. css/, img/, etc.
|
||||
|
||||
Default settings for pages (``defaults``)
|
||||
=========================================
|
||||
|
||||
template
|
||||
Default: template.jinja2
|
||||
|
||||
Default page template.
|
||||
|
||||
type
|
||||
Default: page
|
||||
|
||||
Default article type.
|
||||
|
||||
Custom site data (``site``)
|
||||
===========================
|
||||
|
||||
datetime_format
|
||||
Default: %Y-%m-%d
|
||||
|
||||
See `Format Codes`_.
|
||||
|
||||
Pygments (``pygments``)
|
||||
=======================
|
||||
|
||||
theme
|
||||
Default: default
|
||||
|
||||
Generate CSS style with following command::
|
||||
|
||||
make css style_name
|
||||
|
||||
See `Pygments Styles`_ and `pygmentize`_.
|
||||
|
||||
Docutils (``docutils``)
|
||||
=======================
|
||||
|
||||
See `Docutils Configuration`_.
|
||||
|
||||
.. Links
|
||||
|
||||
.. _Format Codes: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes
|
||||
.. _Pygments Styles: https://pygments.org/styles/
|
||||
.. _pygmentize: https://pygments.org/docs/cmdline/
|
||||
.. _Docutils Configuration: https://docutils.sourceforge.io/docs/user/config.html
|
114
docs/content/data_sources.rst
Normal file
114
docs/content/data_sources.rst
Normal file
@ -0,0 +1,114 @@
|
||||
:title: Data Sources
|
||||
:date: 2022-09-22
|
||||
|
||||
============
|
||||
Data Sources
|
||||
============
|
||||
|
||||
The diagram below shows the data sources and variables that can be used in
|
||||
templates.
|
||||
|
||||
::
|
||||
|
||||
┌─────────────────┐
|
||||
│ settings.toml ├───► site, pygments_theme ──┐
|
||||
└─────────────────┘ │
|
||||
│
|
||||
┌─────────────────┐ ┌────────▼────────┐
|
||||
│ *.rst ├───► page, html ───► template.jinja2 │
|
||||
└────────┬────────┘ └────────▲────────┘
|
||||
│ │
|
||||
┌────────▼────────┐ │
|
||||
│ Aggregated data ├───► aggr ──────────────────┘
|
||||
└─────────────────┘
|
||||
|
||||
\*.rst Files
|
||||
============
|
||||
|
||||
The \*.rst files contain a part with document attributes called Docinfo (see
|
||||
`field lists`_ and `bibliographic elements`_) and a part with the content of
|
||||
the article.
|
||||
|
||||
You can come up with your own attributes. Attributes can contain only strings.
|
||||
|
||||
There some special attributes used by rSW:
|
||||
|
||||
============ =============== =========================
|
||||
Attribute Required Deafult
|
||||
============ =============== =========================
|
||||
``type`` No page
|
||||
``template`` No template.jinja2
|
||||
``date`` Yes None
|
||||
``title`` No None
|
||||
============ =============== =========================
|
||||
|
||||
type
|
||||
Article type. Can be post for blog posts or ``page`` for standalone
|
||||
pages.
|
||||
|
||||
template
|
||||
The template to be used when rendering the HTML page.
|
||||
|
||||
The attribute value must be the path to the template file relative to the
|
||||
template directory. For example, the templates/index.jinja2 file would be:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
:template: index.jinja2
|
||||
|
||||
The path to the templates directory and default template can be overridden
|
||||
in **settings.toml**.
|
||||
|
||||
date
|
||||
Date in ISO format YYYY-MM-DD. This attribute is used to sort the list of
|
||||
posts. The date format can be overridden in **settings.toml**.
|
||||
|
||||
title
|
||||
Title of the article. It is not required and is not processed by rSW in
|
||||
any way, but it is desirable to fill it for use in templates.
|
||||
|
||||
.. note::
|
||||
|
||||
The ``authors`` attribute is `special`_ and is not yet supported by rSW.
|
||||
Using ``authors`` will result in an error when building the site.
|
||||
|
||||
settings.toml
|
||||
=============
|
||||
|
||||
The configuration file has a special ``site`` section, all data from which is
|
||||
passed to the template unchanged.
|
||||
|
||||
The structure and data types can be arbitrary. The file uses the
|
||||
`TOML <https://toml.io/>`_ format.
|
||||
|
||||
For example, in this way you can pass basic information about the site:
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[site]
|
||||
title = 'My site'
|
||||
name = 'My awesome site'
|
||||
description = 'Awesome site about awesome things'
|
||||
datetime_format = '%d %b %Y'
|
||||
|
||||
A special variable ``pygments_theme`` is also passed to the template from the
|
||||
configuration file. It contains the value of ``pygments.theme``.
|
||||
|
||||
Aggregated data
|
||||
===============
|
||||
|
||||
A dictionary with aggregated data. This data is collected during site
|
||||
generation before HTML-pages are rendered.
|
||||
|
||||
Aggregated data contains lists of blog posts and standalone pages.
|
||||
|
||||
The list of posts is sorted in descending order by date from the ``date``
|
||||
attribute.
|
||||
|
||||
The next article will describe the use of this data in templates.
|
||||
|
||||
.. Links
|
||||
|
||||
.. _field lists: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html\#field-lists
|
||||
.. _bibliographic elements: https://docutils.sourceforge.io/docs/ref/doctree.html#bibliographic-elements
|
||||
.. _special: https://docutils.sourceforge.io/docs/ref/doctree.html#authors
|
199
docs/content/examples.rst
Normal file
199
docs/content/examples.rst
Normal file
@ -0,0 +1,199 @@
|
||||
:title: Examples
|
||||
:date: 2022-09-30
|
||||
|
||||
========
|
||||
Examples
|
||||
========
|
||||
|
||||
Blog site example
|
||||
=================
|
||||
|
||||
For the blog, we will need to create three template files and at least two
|
||||
.rst files.
|
||||
|
||||
Edit your **settings.toml**:
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[defaults]
|
||||
template = 'post.jinja2'
|
||||
type = 'post'
|
||||
|
||||
[site]
|
||||
title = 'My Blog'
|
||||
|
||||
Generate Pygments theme:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
make css default
|
||||
|
||||
Create basic template **layouts/base.jinja2**:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="/css/pygments/{{ pygments_theme }}.css">
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
<title>{{ page.title }} | {{ site.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
{% block content %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Home page template **layouts/index.jinja2**:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% extends "base.jinja2" %}
|
||||
{% block content %}
|
||||
<h1>{{ site.title }}</h1>
|
||||
<ul id="posts">
|
||||
{% for post in aggr.posts %}
|
||||
<li>
|
||||
<a href="{{ post.path }}">{{ post.title }}</a>
|
||||
<span class="meta"> — {{ post.date }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{{ html | safe }}
|
||||
{% endblock %}
|
||||
|
||||
Posts tempalte **layouts/post.jinja2**:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% extends "base.jinja2" %}
|
||||
{% block content %}
|
||||
<a href="/">Back to the home page</a>
|
||||
<article>
|
||||
{{ html | safe }}
|
||||
</article>
|
||||
{% endblock %}
|
||||
|
||||
Create dummy home page **content/index.rst** with fields:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
:title: Homepage
|
||||
:date: 1970-01-01
|
||||
:type: page
|
||||
:template: index.jinja2
|
||||
|
||||
Create first blog post **content/hello_world.rst**:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
:title: Hello, World!
|
||||
:date: 1970-01-01
|
||||
|
||||
=============
|
||||
Hello, World!
|
||||
=============
|
||||
|
||||
Hello, there! This is my first site built with *re*\ **Structured**\ *Web*!
|
||||
|
||||
Now build site:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
make
|
||||
make serve
|
||||
|
||||
Page navigation
|
||||
===============
|
||||
|
||||
This code is used on this site to organize pagination.
|
||||
|
||||
**settings.toml**:
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[site]
|
||||
[[site.sidebar]]
|
||||
title = 'First'
|
||||
url = '/first.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Second'
|
||||
url = '/second.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Third'
|
||||
url = '/third.html'
|
||||
|
||||
**layouts/template.jinja2**:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{# Display Sidebar #}
|
||||
<strong>Contents</strong>
|
||||
<ul id="contents">
|
||||
{% for item in site.sidebar %}
|
||||
<li>
|
||||
<a href="{{ item.url }}">{{ item.title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{# Page content #}
|
||||
<article>
|
||||
{{ html | safe }}
|
||||
</article>
|
||||
|
||||
{# Pagination #}
|
||||
{% for item in site.sidebar %}
|
||||
{% if item.title == page.title %}
|
||||
{% set current = site.sidebar.index(item) %}
|
||||
{% set last = site.sidebar.index(site.sidebar[-1]) %}
|
||||
{% if current == 0 %}
|
||||
{# If curret page is a first page #}
|
||||
<a href="{{ site.sidebar[current+1].url }}">
|
||||
{{ site.sidebar[current+1].title }} --></a>
|
||||
{% elif current == last %}
|
||||
{# If curret page is a last page #}
|
||||
<a href="{{ site.sidebar[current-1].url }}">
|
||||
<-- {{ site.sidebar[current-1].title }}</a></div>
|
||||
{% else %}
|
||||
<a href="{{ site.sidebar[current-1].url }}">
|
||||
<-- {{ site.sidebar[current-1].title }}</a>
|
||||
<a href="{{ site.sidebar[current+1].url }}">
|
||||
{{ site.sidebar[current+1].title }} --></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
**content/index.rst**:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
:title: Homepage
|
||||
:date: 1907-01-01
|
||||
|
||||
=======
|
||||
Welcome
|
||||
=======
|
||||
|
||||
Hello, there!
|
||||
|
||||
Page example e.g. **content/first.rst**:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
:title: First
|
||||
:date: 1907-01-01
|
||||
|
||||
=====
|
||||
First
|
||||
=====
|
||||
|
||||
First page.
|
||||
|
||||
.. note::
|
||||
|
||||
Page ``:title:`` and sidebar's ``title`` in **settings.toml** item must be
|
||||
the same. Otherwise pagination not be displayed.
|
52
docs/content/index.rst
Normal file
52
docs/content/index.rst
Normal file
@ -0,0 +1,52 @@
|
||||
:title: reStructuredWeb
|
||||
:date: 2022-09-22
|
||||
|
||||
|rSW|
|
||||
|
||||
v0.1.2
|
||||
|
||||
reStructuredWeb (rSW, reSW or rstW) — is a highly customizable static site
|
||||
generator for the *re*\ **Structured**\ *Text* markup language.
|
||||
|
||||
Why another site generator?
|
||||
===========================
|
||||
|
||||
Hundreds of static site generators have been written with varying degrees of
|
||||
shittyness. Here are just some of the shortcomings of existing solutions:
|
||||
|
||||
* Bad customization. If the task requires something that is not provided for
|
||||
in regular themes, then you have to strain. Editing a theme is an adventure.
|
||||
* Some of the solutions are extremely primitive and only fit narrow cases.
|
||||
Others, on the contrary, are overcomplicated.
|
||||
* There are very few generators with reStructuredText support.
|
||||
|
||||
Why is reStructuredWeb better?
|
||||
==============================
|
||||
|
||||
* **Small codebase**. About ~300 lines in total.
|
||||
* **Doesn't depend on the presentation layer**. rSW just takes data from
|
||||
files and allows you to insert it into templates.
|
||||
|
||||
That's all. In fact, this is enough for a static site generator.
|
||||
|
||||
**rSW** is built on |Docutils|_ and |Jinja2|_.
|
||||
|
||||
.. |rSW| image::
|
||||
/rsw/img/rsw.svg
|
||||
:alt: [rSW]
|
||||
:align: middle
|
||||
:height: 3em
|
||||
|
||||
.. |Docutils| image::
|
||||
/rsw/img/rst.png
|
||||
:alt: Docutils
|
||||
:align: middle
|
||||
:width: 7em
|
||||
.. _Docutils: https://docutils.sourceforge.io/
|
||||
|
||||
.. |Jinja2| image::
|
||||
/rsw/img/jinja.png
|
||||
:alt: Jinja2
|
||||
:align: middle
|
||||
:width: 3em
|
||||
.. _Jinja2: https://jinja.palletsprojects.com/
|
48
docs/content/install.rst
Normal file
48
docs/content/install.rst
Normal file
@ -0,0 +1,48 @@
|
||||
:title: Installation
|
||||
:date: 2022-09-22
|
||||
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
From PyPI
|
||||
=========
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
pip install reSW
|
||||
|
||||
From tarball
|
||||
============
|
||||
|
||||
1. `Download`_ tarball (`alterntive link </rsw/downloads/reSW-0.1.2.tar.gz>`_)
|
||||
with prebuilt Python package.
|
||||
2. Install via pip:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
pip install ./reSW-0.1.2.tar.gz
|
||||
|
||||
From Source
|
||||
============
|
||||
|
||||
1. `Download`_ source or clone Git repo:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git clone https://git.nxhs.cloud/ge/rSW.git && cd rSW
|
||||
|
||||
2. Install build deps:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
pip install --update build
|
||||
|
||||
3. Build and install Python package:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
.. _Download: https://git.nxhs.cloud/ge/rSW/releases
|
13
docs/content/overview.rst
Normal file
13
docs/content/overview.rst
Normal file
@ -0,0 +1,13 @@
|
||||
:title: Overview
|
||||
:date: 2022-09-22
|
||||
|
||||
========
|
||||
Overview
|
||||
========
|
||||
|
||||
On this page, I will list the important features of the application that you
|
||||
may be looking for.
|
||||
|
||||
* You can create two types of pages: blog posts and standalone pages.
|
||||
* Any page can use its own layout (template).
|
||||
* You can pass arbitrary data to templates. See `Data Sources </rsw/data_sources.html>`_
|
70
docs/content/quick_start.rst
Normal file
70
docs/content/quick_start.rst
Normal file
@ -0,0 +1,70 @@
|
||||
:title: Quick Start
|
||||
:date: 2022-09-22
|
||||
|
||||
===========
|
||||
Quick Start
|
||||
===========
|
||||
|
||||
After installation you must have these file structure::
|
||||
|
||||
./
|
||||
├── content/
|
||||
├── layouts/
|
||||
├── Makefile
|
||||
├── settings.toml
|
||||
└── static/
|
||||
|
||||
Articles mst be placed into content/ dir and have .rst extension.
|
||||
|
||||
Also you can place article into subdirectory as following::
|
||||
|
||||
./
|
||||
└── content/
|
||||
└── hello_world/
|
||||
└── index.rst
|
||||
|
||||
You need to create page template first.
|
||||
|
||||
Create **layouts/template.jinja2** with content:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{ page.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
{{ html | safe }}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Now create first page **content/index.rst**:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
:title: Hello, World!
|
||||
:date: 1970-01-01
|
||||
|
||||
=============
|
||||
Hello, World!
|
||||
=============
|
||||
|
||||
Hello, there! This is my first site built with *re*\ **Structured**\ *Web*!
|
||||
|
||||
Build your site with command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
rsw build
|
||||
# OR
|
||||
make
|
||||
|
||||
build/ directory will be created. Run local HTTP-server to view site:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
make serve
|
||||
|
||||
Local server will be started at `http://127.0.0.1:8080/ <http://127.0.0.1:8080/>`_.
|
47
docs/content/rst_extensions.rst
Normal file
47
docs/content/rst_extensions.rst
Normal file
@ -0,0 +1,47 @@
|
||||
:title: rST Extensions
|
||||
:date: 2022-09-29
|
||||
|
||||
===========================
|
||||
reStructuredText Extensions
|
||||
===========================
|
||||
|
||||
rSW includes support for a few directives and roles that are not part of
|
||||
Docutils.
|
||||
|
||||
code-block
|
||||
==========
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if __name__ == "__main__":
|
||||
# [initialize]
|
||||
app.start(":8000")
|
||||
# [initialize]
|
||||
|
||||
Result:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if __name__ == "__main__":
|
||||
# [initialize]
|
||||
app.start(":8000")
|
||||
# [initialize]
|
||||
|
||||
TODO
|
||||
====
|
||||
|
||||
In plan:
|
||||
|
||||
* Fully featured ``code-block`` (as in `Sphinx`_)
|
||||
* Deleted text (`<del>`)
|
||||
* Inserted text (`<ins>`)
|
||||
* Keystrokes mark (``:kbd:``)
|
||||
* Spoilers (`<details>`, `<summary>`)
|
||||
* Table of Contents (``toctree``)
|
||||
* Abbreviations (``:abbr:``)
|
||||
|
||||
.. _Sphinx: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block
|
130
docs/content/variables.rst
Normal file
130
docs/content/variables.rst
Normal file
@ -0,0 +1,130 @@
|
||||
:title: Variables
|
||||
:date: 2022-09-22
|
||||
|
||||
=========
|
||||
Variables
|
||||
=========
|
||||
|
||||
The following variables are passed to the template. Еach variable corresponds
|
||||
to a data source, which is described in the previous article.
|
||||
|
||||
``page``: dict
|
||||
Dictonary with article attributes. Data structure example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
page = {
|
||||
'title': 'Variables',
|
||||
'date': '2022-09-22',
|
||||
}
|
||||
|
||||
Note that the ``type`` and ``template`` keys are missing. These keys are
|
||||
added implicitly. The ``page`` dict will always contain only the data
|
||||
specified directly in the article.
|
||||
|
||||
Here ``type`` and ``template`` fallbacks to defaults:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
'template': `template.jinja2`
|
||||
'type': 'page',
|
||||
|
||||
Usage example:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
<h1>{{ page.title }}</h1>
|
||||
|
||||
``site``: dict
|
||||
Dict of values from ``site`` section from **settings.toml**. The structure
|
||||
and data types can be arbitrary.
|
||||
|
||||
This data can be used to add custom elements common to the entire site.
|
||||
Below is an example of adding a list of links.
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[site]
|
||||
title = 'My awesome site'
|
||||
description = 'Awesome site about awesome things'
|
||||
|
||||
[[site.links]]
|
||||
title = 'GitHub'
|
||||
url = 'https://github.com/username'
|
||||
|
||||
[[site.links]]
|
||||
title = 'Twitter'
|
||||
url = 'https://twitter.com/username'
|
||||
|
||||
This data is serialized into a dictionary with the following structure:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
site = {
|
||||
'title': 'My awesome site',
|
||||
'description': 'Awesome site about awesome things',
|
||||
'links': [
|
||||
{
|
||||
'title': 'GitHub',
|
||||
'url': 'https://github.com/username',
|
||||
},
|
||||
{
|
||||
'title': 'Twitter',
|
||||
'url': 'https://twitter.com/username',
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
In template:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% for link in site.links %}
|
||||
<a href="{{ link.url }}">{{ link.title }} </a>
|
||||
{% endfor %}
|
||||
|
||||
``aggr``: dict
|
||||
This dictonary contains list of posts and list of pages. The elements of
|
||||
each list consist of dictionaries with strings.
|
||||
|
||||
Structure of the ``aggr`` dictonary:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
aggr = {
|
||||
'posts': [
|
||||
{
|
||||
'title': 'Hello, World!',
|
||||
'date': '1970-01-01',
|
||||
'type': 'post'
|
||||
},
|
||||
{
|
||||
'title': 'reStructuredText Example',
|
||||
'date': '1970-01-01',
|
||||
'type': 'post'
|
||||
}
|
||||
],
|
||||
'pages': [
|
||||
{
|
||||
'title': 'Variables',
|
||||
'date': '2022-09-22'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
These lists are applicable, for example, to display a list of posts on the
|
||||
blog's main page.
|
||||
|
||||
``pygments_theme``: str
|
||||
A string containing the name of the Pygments theme. In **settings.toml**:
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[pygments]
|
||||
theme = 'rrt'
|
||||
|
||||
The default theme is ``default``. An example of usage in a template:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
<link rel="stylesheet" href="/css/pygments/{{ pygments_theme }}.css">
|
68
docs/layouts/template.jinja2
Normal file
68
docs/layouts/template.jinja2
Normal file
@ -0,0 +1,68 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="{{ site.base_url }}/css/pygments/{{ pygments_theme }}.css">
|
||||
<link rel="stylesheet" href="{{ site.base_url }}/css/style.css">
|
||||
<title>{{ page.title }} | {{ site.title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="flex">
|
||||
<div class="col-md-2 sidebar">
|
||||
<p>
|
||||
{% for link in site.links %}
|
||||
<strong><a href="{{ link.url }}" style="text-decoration: none">
|
||||
{{ link.title }} </a></strong>
|
||||
{% endfor %}
|
||||
</p>
|
||||
<strong>Contents</strong>
|
||||
<ul id="contents">
|
||||
{% for item in site.sidebar %}
|
||||
<li>
|
||||
<a href="{{ item.url }}">{{ item.title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<article>
|
||||
{{ html | safe }}
|
||||
</article>
|
||||
|
||||
<div class="pagination" style="margin: 2rem 0;">
|
||||
{% for item in site.sidebar %}
|
||||
{% if item.title == page.title %}
|
||||
{% set current = site.sidebar.index(item) %}
|
||||
{% set last = site.sidebar.index(site.sidebar[-1]) %}
|
||||
{% if current == 0 %}
|
||||
<div class="flex" style="justify-content: space-between">
|
||||
<div></div>
|
||||
<div><a href="{{ site.sidebar[current+1].url }}">
|
||||
{{ site.sidebar[current+1].title }} --></a></div>
|
||||
</div>
|
||||
{% elif current == last %}
|
||||
<div class="flex" style="justify-content: space-between">
|
||||
<div><a href="{{ site.sidebar[current-1].url }}">
|
||||
<-- {{ site.sidebar[current-1].title }}</a></div>
|
||||
<div></div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="flex" style="justify-content: space-between">
|
||||
<div><a href="{{ site.sidebar[current-1].url }}">
|
||||
<-- {{ site.sidebar[current-1].title }}</a></div>
|
||||
<div><a href="{{ site.sidebar[current+1].url }}">
|
||||
{{ site.sidebar[current+1].title }} --></a></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
58
docs/settings.toml
Normal file
58
docs/settings.toml
Normal file
@ -0,0 +1,58 @@
|
||||
[dirs]
|
||||
build_dir = 'build/rsw'
|
||||
|
||||
[pygments]
|
||||
theme = 'vs'
|
||||
|
||||
[site]
|
||||
base_url = '/rsw'
|
||||
title = 'Highly customizable static site generator for reStructuredText markup'
|
||||
name = '[rSW]'
|
||||
|
||||
[[site.links]]
|
||||
title = '[Home]'
|
||||
url = '/rsw'
|
||||
|
||||
[[site.links]]
|
||||
title = '[Docs]'
|
||||
url = '/rsw/overview.html'
|
||||
|
||||
[[site.links]]
|
||||
title = '[Download]'
|
||||
url = 'https://git.nxhs.cloud/ge/rSW'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Overview'
|
||||
url = '/rsw/overview.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Installation'
|
||||
url = '/rsw/install.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Quick Start'
|
||||
url = '/rsw/quick_start.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Data Sources'
|
||||
url = '/rsw/data_sources.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Variables'
|
||||
url = '/rsw/variables.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Configuration'
|
||||
url = '/rsw/configuration.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Command Line Interface'
|
||||
url = '/rsw/cli.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'rST Extensions'
|
||||
url = '/rsw/rst_extensions.html'
|
||||
|
||||
[[site.sidebar]]
|
||||
title = 'Examples'
|
||||
url = '/rsw/examples.html'
|
43
docs/static/css/pygments/vs.css
vendored
Normal file
43
docs/static/css/pygments/vs.css
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
pre { line-height: 125%; }
|
||||
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight { background: #ffffff; }
|
||||
.highlight .c { color: #008000 } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #0000ff } /* Keyword */
|
||||
.highlight .ch { color: #008000 } /* Comment.Hashbang */
|
||||
.highlight .cm { color: #008000 } /* Comment.Multiline */
|
||||
.highlight .cp { color: #0000ff } /* Comment.Preproc */
|
||||
.highlight .cpf { color: #008000 } /* Comment.PreprocFile */
|
||||
.highlight .c1 { color: #008000 } /* Comment.Single */
|
||||
.highlight .cs { color: #008000 } /* Comment.Special */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gh { font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gp { font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .kc { color: #0000ff } /* Keyword.Constant */
|
||||
.highlight .kd { color: #0000ff } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #0000ff } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #0000ff } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #0000ff } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #2b91af } /* Keyword.Type */
|
||||
.highlight .s { color: #a31515 } /* Literal.String */
|
||||
.highlight .nc { color: #2b91af } /* Name.Class */
|
||||
.highlight .ow { color: #0000ff } /* Operator.Word */
|
||||
.highlight .sa { color: #a31515 } /* Literal.String.Affix */
|
||||
.highlight .sb { color: #a31515 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #a31515 } /* Literal.String.Char */
|
||||
.highlight .dl { color: #a31515 } /* Literal.String.Delimiter */
|
||||
.highlight .sd { color: #a31515 } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #a31515 } /* Literal.String.Double */
|
||||
.highlight .se { color: #a31515 } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #a31515 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #a31515 } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #a31515 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #a31515 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #a31515 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #a31515 } /* Literal.String.Symbol */
|
74
docs/static/css/style.css
vendored
Normal file
74
docs/static/css/style.css
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
body {
|
||||
font-family: 'Source Code Pro', monospace;
|
||||
line-height: 1.3;
|
||||
padding: 1rem;
|
||||
}
|
||||
a, a:visited {
|
||||
color: #2003ee;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.col-md-2 {
|
||||
width: 15%;
|
||||
}
|
||||
.col-md-6 {
|
||||
width: 50%;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.flex {
|
||||
flex-direction: column
|
||||
}
|
||||
.col-md-2, .col-md-6 {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
pre {
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.pre {
|
||||
font-size: 85%;
|
||||
}
|
||||
.highlight pre {
|
||||
padding: 1rem;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
span.docutils.literal {
|
||||
padding: 0 4px 2px 4px;
|
||||
color: #a31515;
|
||||
font-size: 80%;
|
||||
}
|
||||
span.docutils.literal span.pre {
|
||||
font-size: 100%;
|
||||
}
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid;
|
||||
border-collapse: collapse;
|
||||
border-color: #000;
|
||||
padding: 0 8px;
|
||||
}
|
||||
th {
|
||||
font-weight: 600;
|
||||
}
|
||||
td p {
|
||||
margin: .5rem 0;
|
||||
}
|
||||
hr {
|
||||
color: #d0d7de;
|
||||
}
|
||||
.admonition {
|
||||
padding: 0 1rem;
|
||||
margin: .5rem 0;
|
||||
border-left: 4px solid #000;
|
||||
}
|
||||
.admonition-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
.sidebar {
|
||||
margin-right: 1rem;
|
||||
}
|
BIN
docs/static/img/jinja.png
vendored
Normal file
BIN
docs/static/img/jinja.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
BIN
docs/static/img/rst.png
vendored
Normal file
BIN
docs/static/img/rst.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
20
docs/static/img/rsw.svg
vendored
Normal file
20
docs/static/img/rsw.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 58 KiB |
@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = 'reSW'
|
||||
version = '0.1.0'
|
||||
version = '0.1.2'
|
||||
description = 'Highly customizable static site generator for reStructuredText markup'
|
||||
readme = 'README'
|
||||
requires-python = ">=3.6"
|
||||
requires-python = ">=3.7"
|
||||
keywords = ['reStructuredText', 'SSG', 'static site generator']
|
||||
license = {text = 'GNU General Public License v3 or later (GPLv3+)'}
|
||||
dependencies = [
|
||||
@ -27,5 +27,11 @@ classifiers = [
|
||||
rsw = 'rsw:cli'
|
||||
|
||||
[tool.setuptools]
|
||||
py-modules = ['rsw']
|
||||
include-package-data = true
|
||||
zip-safe = true
|
||||
|
||||
[tool.setuptools.packages]
|
||||
find = {}
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
rsw = ['*.jinja2']
|
||||
|
@ -43,7 +43,7 @@ This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
"""
|
||||
|
||||
__version__ = '0.1.0'
|
||||
__version__ = '0.1.2'
|
||||
|
||||
import os
|
||||
import sys
|
||||
@ -350,7 +350,7 @@ def build(config: dict):
|
||||
write_to_file(html_file_path, html_page)
|
||||
|
||||
# Copy additional files to build_dir
|
||||
log.info("Copy static files from '{}' and '{}' to '{}'".format(
|
||||
log.info("Copying static files from '{}' and '{}' to '{}'".format(
|
||||
config['dirs']['static_dir'],
|
||||
config['dirs']['content_dir'],
|
||||
config['dirs']['build_dir']))
|
||||
@ -376,7 +376,10 @@ def init(dirname: str = '.', no_makefile: bool = False):
|
||||
|
||||
# Make Makefile
|
||||
if not no_makefile:
|
||||
# Get package dir `this_dir`
|
||||
this_dir, this_filename = os.path.split(__file__)
|
||||
makefile = render_template('Makefile.jinja2',
|
||||
templates_dir = this_dir,
|
||||
content_dir = DEFAULT_CONFIG['dirs']['content_dir'],
|
||||
static_dir = DEFAULT_CONFIG['dirs']['static_dir'],
|
||||
build_dir = DEFAULT_CONFIG['dirs']['build_dir'],
|
Loading…
Reference in New Issue
Block a user