feat(website_template): Added website template as submodule

the website-template repo was added as a git submodule so that the
site could be templated easier.

!8 nofusscomputing/infrastructure/website-template!2
This commit is contained in:
2022-08-29 10:29:24 +09:30
parent 53d5d3ff62
commit 70f0facb11
23 changed files with 5 additions and 1450 deletions

3
.gitmodules vendored
View File

@ -2,3 +2,6 @@
path = gitlab-ci
url = https://gitlab.com/nofusscomputing/projects/gitlab-ci.git
branch = master
[submodule "website-template"]
path = website-template
url = https://gitlab.com/nofusscomputing/infrastructure/website-template.git

View File

@ -1,125 +0,0 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
# docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

View File

@ -1,7 +0,0 @@
# License
Copyright (C) 2021 No Fuss Computing
All Rights Reserved.
Not yet suitable for public release.

View File

@ -1,2 +0,0 @@
include versioneer.py
include tags/_version.py

View File

@ -1,128 +0,0 @@
# No Fuss Computing's Tags Plugin for MKDocs
Modified version from: [github.com/ginsburgnm/mkdocs-plugin-tags](https://github.com/ginsburgnm/mkdocs-plugin-tags)
## Previous Readme below - tags
Support for tags in the yaml-metadata in the header of markdown files.
Extracts this metadata and creates a "Tags" page which lists all tags
and all pages for each tag.
## Quick Demo
Install this plugin (it will also install mkdocs if required)
```bash
pip install mkdocs-plugin-tags
```
Create a new documentation folder:
```bash
mkdocs new demo
```
Edit the `.md` files to add initial metadata. Currently, the metadata has to be
enclosed in `---` lines, and must include a `title:` property
(otherwise the page will appear as "untitled" in the tags page). So, for example:
```bash
cd demo
cd docs
cat > index.md
---
title: Welcome
tags:
- testing
- unimportant
---
# Welcome to MkDocs
For full documentation visit [mkdocs.org](https://mkdocs.org).
^D
```
Edit `mkdocs.yml` to include this plugin:
```yaml
plugins:
- tags:
```
Run the server:
```bash
mkdocs serve --livereload
```
Visit the URL `/tags` (it should appear in the nav panel).
This is an auto-generated page which contains the tags as level 2 headers,
and under each tag, a listing of the pages which declare that tag in the
metadata section.
![example screenshot](doc/imgs/screenshot.png)
## How it works
On each build (even with `--livereload`), all the `.md` files composing the
site are scanned, their "triple-dash-delimted" yaml header is extracted and
parsed, and the list of tags is collected.
After that, a new temporal file is created (by default in `aux/tags.md`, but
this is customizable) which contains the generated tags page, in markdown
format. This file is not in the documents folder to avoid retriggering a
build, but it is added to the list of files to be converted to HTML by mkdocs.
## Customization
The layout of the tags page is a markdown file with jinja2 embedded contents.
The package provides such a template by default, with the following content:
```markdown
---
title: Tags
---
# Contents grouped by tag
{% for tag, pages in tags %}
## <span class="tag">{{tag}}</span>
{% for page in pages %}
* [{{page.title}}]({{page.filename}})
{% endfor %}
{% endfor %}
```
You can style the `h2.tag` element via CSS, if you want.
You can also provide your own markdown template, in case that you want a
different layout or metadata. The `page` object contains all the metadata
in a mkdocs page, and in addition a `.filename` attribute, which contains
the file name of the source of the page (relative to the docs folder),
which can be used to link to that page.
The full customizable options for the plugin are:
* `tags_folder`: Folder in which the auxiliar tags markdown file will be written
(`aux` by default, relative to the folder in which `mkdocs` is invoked).
It can be set to an absolute path, such as `/tmp/mysite/aux`.
The required folders are created.
* `tags_template`: path to the file which contains the markdown-jinja template
for the tags page. It is `None` by default, which means that the
package-provided template is used. It can be an absolute path,
or relative to the folder in which `mkdocs` is run.
* `css_name`: this allows you to pick what name styles the tag that appears on
the top of the page that contains a tag. This way things won't be overloaded
For example, this can be put at `mkdocs.yaml`:
```yaml
plugins:
- search
- tags:
tags_folder: /tmp/mysite/aux
tags_template: docs/theme/tags.md.template
```

View File

@ -1 +0,0 @@
mkdocs==1.2.3

View File

@ -1,27 +0,0 @@
[metadata]
name = mkdocs-plugin-tags
author = No Fuss Computing
author_email = helpdesk@nofusscomputing.com
url = https://gitlab.com/nofusscomputing/infrastructure/website
description = "Create tags in mkdocs"
long_description_content_type = text/markdown
long_description = file: README.md
license = MIT
keywords = "mkdocs python markdown tags"
classifiers =
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Operating System :: OS Independent
Intended Audience :: Information Technology
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Topic :: Security :: Cryptography
[versioneer]
VCS = git
style = pep440
versionfile_source = tags/_version.py
versionfile_build = tags/_version.py
tag_prefix =
parentdir_prefix = tags-

View File

@ -1,19 +0,0 @@
"""
Setup the plugin
"""
from setuptools import setup, find_packages
setup(
version='0.0.1',
python_requires='>=3.6',
install_requires=[
'mkdocs==1.2.3',
],
packages=find_packages(exclude=['*.tests']),
package_data={'tags': ['templates/*.md.template']},
entry_points={
'mkdocs.plugins': [
'tags = tags.plugin:TagsPlugin'
]
}
)

View File

@ -1,3 +0,0 @@
from . import _version
__version__ = _version.get_versions()['version']

View File

@ -1,644 +0,0 @@
# This file helps to compute a version number in source trees obtained from
# git-archive tarball (such as those provided by githubs download-from-tag
# feature). Distribution tarballs (built by setup.py sdist) and build
# directories (produced by setup.py build) will contain a much shorter file
# that just contains the computed version number.
# This file is released into the public domain. Generated by
# versioneer-0.21 (https://github.com/python-versioneer/python-versioneer)
"""Git implementation of _version.py."""
import errno
import os
import re
import subprocess
import sys
from typing import Callable, Dict
def get_keywords():
"""Get the keywords needed to look up the version information."""
# these strings will be replaced by git during git-archive.
# setup.py/versioneer.py will grep for the variable names, so they must
# each be defined on a line of their own. _version.py will just call
# get_keywords().
git_refnames = "$Format:%d$"
git_full = "$Format:%H$"
git_date = "$Format:%ci$"
keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
return keywords
class VersioneerConfig:
"""Container for Versioneer configuration parameters."""
def get_config():
"""Create, populate and return the VersioneerConfig() object."""
# these strings are filled in when 'setup.py versioneer' creates
# _version.py
cfg = VersioneerConfig()
cfg.VCS = "git"
cfg.style = "pep440"
cfg.tag_prefix = ""
cfg.parentdir_prefix = "tags-"
cfg.versionfile_source = "tags/_version.py"
cfg.verbose = False
return cfg
class NotThisMethod(Exception):
"""Exception raised if a method is not valid for the current scenario."""
LONG_VERSION_PY: Dict[str, str] = {}
HANDLERS: Dict[str, Dict[str, Callable]] = {}
def register_vcs_handler(vcs, method): # decorator
"""Create decorator to mark a method as the handler of a VCS."""
def decorate(f):
"""Store f in HANDLERS[vcs][method]."""
if vcs not in HANDLERS:
HANDLERS[vcs] = {}
HANDLERS[vcs][method] = f
return f
return decorate
def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
env=None):
"""Call the given command(s)."""
assert isinstance(commands, list)
process = None
for command in commands:
try:
dispcmd = str([command] + args)
# remember shell=False, so use git.cmd on windows, not just git
process = subprocess.Popen([command] + args, cwd=cwd, env=env,
stdout=subprocess.PIPE,
stderr=(subprocess.PIPE if hide_stderr
else None))
break
except OSError:
e = sys.exc_info()[1]
if e.errno == errno.ENOENT:
continue
if verbose:
print("unable to run %s" % dispcmd)
print(e)
return None, None
else:
if verbose:
print("unable to find command, tried %s" % (commands,))
return None, None
stdout = process.communicate()[0].strip().decode()
if process.returncode != 0:
if verbose:
print("unable to run %s (error)" % dispcmd)
print("stdout was %s" % stdout)
return None, process.returncode
return stdout, process.returncode
def versions_from_parentdir(parentdir_prefix, root, verbose):
"""Try to determine the version from the parent directory name.
Source tarballs conventionally unpack into a directory that includes both
the project name and a version string. We will also support searching up
two directory levels for an appropriately named parent directory
"""
rootdirs = []
for _ in range(3):
dirname = os.path.basename(root)
if dirname.startswith(parentdir_prefix):
return {"version": dirname[len(parentdir_prefix):],
"full-revisionid": None,
"dirty": False, "error": None, "date": None}
rootdirs.append(root)
root = os.path.dirname(root) # up a level
if verbose:
print("Tried directories %s but none started with prefix %s" %
(str(rootdirs), parentdir_prefix))
raise NotThisMethod("rootdir doesn't start with parentdir_prefix")
@register_vcs_handler("git", "get_keywords")
def git_get_keywords(versionfile_abs):
"""Extract version information from the given file."""
# the code embedded in _version.py can just fetch the value of these
# keywords. When used from setup.py, we don't want to import _version.py,
# so we do it with a regexp instead. This function is not used from
# _version.py.
keywords = {}
try:
with open(versionfile_abs, "r") as fobj:
for line in fobj:
if line.strip().startswith("git_refnames ="):
mo = re.search(r'=\s*"(.*)"', line)
if mo:
keywords["refnames"] = mo.group(1)
if line.strip().startswith("git_full ="):
mo = re.search(r'=\s*"(.*)"', line)
if mo:
keywords["full"] = mo.group(1)
if line.strip().startswith("git_date ="):
mo = re.search(r'=\s*"(.*)"', line)
if mo:
keywords["date"] = mo.group(1)
except OSError:
pass
return keywords
@register_vcs_handler("git", "keywords")
def git_versions_from_keywords(keywords, tag_prefix, verbose):
"""Get version information from git keywords."""
if "refnames" not in keywords:
raise NotThisMethod("Short version file found")
date = keywords.get("date")
if date is not None:
# Use only the last line. Previous lines may contain GPG signature
# information.
date = date.splitlines()[-1]
# git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
# datestamp. However we prefer "%ci" (which expands to an "ISO-8601
# -like" string, which we must then edit to make compliant), because
# it's been around since git-1.5.3, and it's too difficult to
# discover which version we're using, or to work around using an
# older one.
date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
refnames = keywords["refnames"].strip()
if refnames.startswith("$Format"):
if verbose:
print("keywords are unexpanded, not using")
raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
refs = {r.strip() for r in refnames.strip("()").split(",")}
# starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
# just "foo-1.0". If we see a "tag: " prefix, prefer those.
TAG = "tag: "
tags = {r[len(TAG):] for r in refs if r.startswith(TAG)}
if not tags:
# Either we're using git < 1.8.3, or there really are no tags. We use
# a heuristic: assume all version tags have a digit. The old git %d
# expansion behaves like git log --decorate=short and strips out the
# refs/heads/ and refs/tags/ prefixes that would let us distinguish
# between branches and tags. By ignoring refnames without digits, we
# filter out many common branch names like "release" and
# "stabilization", as well as "HEAD" and "master".
tags = {r for r in refs if re.search(r'\d', r)}
if verbose:
print("discarding '%s', no digits" % ",".join(refs - tags))
if verbose:
print("likely tags: %s" % ",".join(sorted(tags)))
for ref in sorted(tags):
# sorting will prefer e.g. "2.0" over "2.0rc1"
if ref.startswith(tag_prefix):
r = ref[len(tag_prefix):]
# Filter out refs that exactly match prefix or that don't start
# with a number once the prefix is stripped (mostly a concern
# when prefix is '')
if not re.match(r'\d', r):
continue
if verbose:
print("picking %s" % r)
return {"version": r,
"full-revisionid": keywords["full"].strip(),
"dirty": False, "error": None,
"date": date}
# no suitable tags, so version is "0+unknown", but full hex is still there
if verbose:
print("no suitable tags, using unknown + full revision id")
return {"version": "0+unknown",
"full-revisionid": keywords["full"].strip(),
"dirty": False, "error": "no suitable tags", "date": None}
@register_vcs_handler("git", "pieces_from_vcs")
def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
"""Get version from 'git describe' in the root of the source tree.
This only gets called if the git-archive 'subst' keywords were *not*
expanded, and _version.py hasn't already been rewritten with a short
version string, meaning we're inside a checked out source tree.
"""
GITS = ["git"]
TAG_PREFIX_REGEX = "*"
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
TAG_PREFIX_REGEX = r"\*"
_, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root,
hide_stderr=True)
if rc != 0:
if verbose:
print("Directory %s not under git control" % root)
raise NotThisMethod("'git rev-parse --git-dir' returned error")
# if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
# if there isn't one, this yields HEX[-dirty] (no NUM)
describe_out, rc = runner(GITS, ["describe", "--tags", "--dirty",
"--always", "--long",
"--match",
"%s%s" % (tag_prefix, TAG_PREFIX_REGEX)],
cwd=root)
# --long was added in git-1.5.5
if describe_out is None:
raise NotThisMethod("'git describe' failed")
describe_out = describe_out.strip()
full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root)
if full_out is None:
raise NotThisMethod("'git rev-parse' failed")
full_out = full_out.strip()
pieces = {}
pieces["long"] = full_out
pieces["short"] = full_out[:7] # maybe improved later
pieces["error"] = None
branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"],
cwd=root)
# --abbrev-ref was added in git-1.6.3
if rc != 0 or branch_name is None:
raise NotThisMethod("'git rev-parse --abbrev-ref' returned error")
branch_name = branch_name.strip()
if branch_name == "HEAD":
# If we aren't exactly on a branch, pick a branch which represents
# the current commit. If all else fails, we are on a branchless
# commit.
branches, rc = runner(GITS, ["branch", "--contains"], cwd=root)
# --contains was added in git-1.5.4
if rc != 0 or branches is None:
raise NotThisMethod("'git branch --contains' returned error")
branches = branches.split("\n")
# Remove the first line if we're running detached
if "(" in branches[0]:
branches.pop(0)
# Strip off the leading "* " from the list of branches.
branches = [branch[2:] for branch in branches]
if "master" in branches:
branch_name = "master"
elif not branches:
branch_name = None
else:
# Pick the first branch that is returned. Good or bad.
branch_name = branches[0]
pieces["branch"] = branch_name
# parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
# TAG might have hyphens.
git_describe = describe_out
# look for -dirty suffix
dirty = git_describe.endswith("-dirty")
pieces["dirty"] = dirty
if dirty:
git_describe = git_describe[:git_describe.rindex("-dirty")]
# now we have TAG-NUM-gHEX or HEX
if "-" in git_describe:
# TAG-NUM-gHEX
mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
if not mo:
# unparsable. Maybe git-describe is misbehaving?
pieces["error"] = ("unable to parse git-describe output: '%s'"
% describe_out)
return pieces
# tag
full_tag = mo.group(1)
if not full_tag.startswith(tag_prefix):
if verbose:
fmt = "tag '%s' doesn't start with prefix '%s'"
print(fmt % (full_tag, tag_prefix))
pieces["error"] = ("tag '%s' doesn't start with prefix '%s'"
% (full_tag, tag_prefix))
return pieces
pieces["closest-tag"] = full_tag[len(tag_prefix):]
# distance: number of commits since tag
pieces["distance"] = int(mo.group(2))
# commit: short hex revision ID
pieces["short"] = mo.group(3)
else:
# HEX: no tags
pieces["closest-tag"] = None
count_out, rc = runner(GITS, ["rev-list", "HEAD", "--count"], cwd=root)
pieces["distance"] = int(count_out) # total number of commits
# commit date: see ISO-8601 comment in git_versions_from_keywords()
date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip()
# Use only the last line. Previous lines may contain GPG signature
# information.
date = date.splitlines()[-1]
pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
return pieces
def plus_or_dot(pieces):
"""Return a + if we don't already have one, else return a ."""
if "+" in pieces.get("closest-tag", ""):
return "."
return "+"
def render_pep440(pieces):
"""Build up version string, with post-release "local version identifier".
Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty
Exceptions:
1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
rendered += plus_or_dot(pieces)
rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
if pieces["dirty"]:
rendered += ".dirty"
else:
# exception #1
rendered = "0+untagged.%d.g%s" % (pieces["distance"],
pieces["short"])
if pieces["dirty"]:
rendered += ".dirty"
return rendered
def render_pep440_branch(pieces):
"""TAG[[.dev0]+DISTANCE.gHEX[.dirty]] .
The ".dev0" means not master branch. Note that .dev0 sorts backwards
(a feature branch will appear "older" than the master branch).
Exceptions:
1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
if pieces["branch"] != "master":
rendered += ".dev0"
rendered += plus_or_dot(pieces)
rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
if pieces["dirty"]:
rendered += ".dirty"
else:
# exception #1
rendered = "0"
if pieces["branch"] != "master":
rendered += ".dev0"
rendered += "+untagged.%d.g%s" % (pieces["distance"],
pieces["short"])
if pieces["dirty"]:
rendered += ".dirty"
return rendered
def pep440_split_post(ver):
"""Split pep440 version string at the post-release segment.
Returns the release segments before the post-release and the
post-release version number (or -1 if no post-release segment is present).
"""
vc = str.split(ver, ".post")
return vc[0], int(vc[1] or 0) if len(vc) == 2 else None
def render_pep440_pre(pieces):
"""TAG[.postN.devDISTANCE] -- No -dirty.
Exceptions:
1: no tags. 0.post0.devDISTANCE
"""
if pieces["closest-tag"]:
if pieces["distance"]:
# update the post release segment
tag_version, post_version = pep440_split_post(pieces["closest-tag"])
rendered = tag_version
if post_version is not None:
rendered += ".post%d.dev%d" % (post_version+1, pieces["distance"])
else:
rendered += ".post0.dev%d" % (pieces["distance"])
else:
# no commits, use the tag as the version
rendered = pieces["closest-tag"]
else:
# exception #1
rendered = "0.post0.dev%d" % pieces["distance"]
return rendered
def render_pep440_post(pieces):
"""TAG[.postDISTANCE[.dev0]+gHEX] .
The ".dev0" means dirty. Note that .dev0 sorts backwards
(a dirty tree will appear "older" than the corresponding clean one),
but you shouldn't be releasing software with -dirty anyways.
Exceptions:
1: no tags. 0.postDISTANCE[.dev0]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
rendered += ".post%d" % pieces["distance"]
if pieces["dirty"]:
rendered += ".dev0"
rendered += plus_or_dot(pieces)
rendered += "g%s" % pieces["short"]
else:
# exception #1
rendered = "0.post%d" % pieces["distance"]
if pieces["dirty"]:
rendered += ".dev0"
rendered += "+g%s" % pieces["short"]
return rendered
def render_pep440_post_branch(pieces):
"""TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] .
The ".dev0" means not master branch.
Exceptions:
1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
rendered += ".post%d" % pieces["distance"]
if pieces["branch"] != "master":
rendered += ".dev0"
rendered += plus_or_dot(pieces)
rendered += "g%s" % pieces["short"]
if pieces["dirty"]:
rendered += ".dirty"
else:
# exception #1
rendered = "0.post%d" % pieces["distance"]
if pieces["branch"] != "master":
rendered += ".dev0"
rendered += "+g%s" % pieces["short"]
if pieces["dirty"]:
rendered += ".dirty"
return rendered
def render_pep440_old(pieces):
"""TAG[.postDISTANCE[.dev0]] .
The ".dev0" means dirty.
Exceptions:
1: no tags. 0.postDISTANCE[.dev0]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
rendered += ".post%d" % pieces["distance"]
if pieces["dirty"]:
rendered += ".dev0"
else:
# exception #1
rendered = "0.post%d" % pieces["distance"]
if pieces["dirty"]:
rendered += ".dev0"
return rendered
def render_git_describe(pieces):
"""TAG[-DISTANCE-gHEX][-dirty].
Like 'git describe --tags --dirty --always'.
Exceptions:
1: no tags. HEX[-dirty] (note: no 'g' prefix)
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"]:
rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
else:
# exception #1
rendered = pieces["short"]
if pieces["dirty"]:
rendered += "-dirty"
return rendered
def render_git_describe_long(pieces):
"""TAG-DISTANCE-gHEX[-dirty].
Like 'git describe --tags --dirty --always -long'.
The distance/hash is unconditional.
Exceptions:
1: no tags. HEX[-dirty] (note: no 'g' prefix)
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
else:
# exception #1
rendered = pieces["short"]
if pieces["dirty"]:
rendered += "-dirty"
return rendered
def render(pieces, style):
"""Render the given version pieces into the requested style."""
if pieces["error"]:
return {"version": "unknown",
"full-revisionid": pieces.get("long"),
"dirty": None,
"error": pieces["error"],
"date": None}
if not style or style == "default":
style = "pep440" # the default
if style == "pep440":
rendered = render_pep440(pieces)
elif style == "pep440-branch":
rendered = render_pep440_branch(pieces)
elif style == "pep440-pre":
rendered = render_pep440_pre(pieces)
elif style == "pep440-post":
rendered = render_pep440_post(pieces)
elif style == "pep440-post-branch":
rendered = render_pep440_post_branch(pieces)
elif style == "pep440-old":
rendered = render_pep440_old(pieces)
elif style == "git-describe":
rendered = render_git_describe(pieces)
elif style == "git-describe-long":
rendered = render_git_describe_long(pieces)
else:
raise ValueError("unknown style '%s'" % style)
return {"version": rendered, "full-revisionid": pieces["long"],
"dirty": pieces["dirty"], "error": None,
"date": pieces.get("date")}
def get_versions():
"""Get version information or return default if unable to do so."""
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
# __file__, we can work backwards from there to the root. Some
# py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
# case we can only use expanded keywords.
cfg = get_config()
verbose = cfg.verbose
try:
return git_versions_from_keywords(get_keywords(), cfg.tag_prefix,
verbose)
except NotThisMethod:
pass
try:
root = os.path.realpath(__file__)
# versionfile_source is the relative path from the top of the source
# tree (where the .git directory might live) to this file. Invert
# this to find the root from __file__.
for _ in cfg.versionfile_source.split('/'):
root = os.path.dirname(root)
except NameError:
return {"version": "0+unknown", "full-revisionid": None,
"dirty": None,
"error": "unable to find root of source tree",
"date": None}
try:
pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
return render(pieces, cfg.style)
except NotThisMethod:
pass
try:
if cfg.parentdir_prefix:
return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
except NotThisMethod:
pass
return {"version": "0+unknown", "full-revisionid": None,
"dirty": None,
"error": "unable to compute version", "date": None}

View File

@ -1,151 +0,0 @@
#!/usr/bin/env python
"""
This plugin generates tags file as well as inserts markdown
at the beginning of a file that has tags
@Adopted from
JL Diaz (c) 2019
MIT License
"""
from collections import defaultdict
from pathlib import Path
from re import search, DOTALL, MULTILINE
from yaml import load, FullLoader, YAMLError
from jinja2 import Environment, FileSystemLoader
from mkdocs.structure.files import File
from mkdocs.plugins import BasePlugin
from mkdocs.config.config_options import Type
from mkdocs.__main__ import log
class TagsPlugin(BasePlugin):
"""
Creates "tags.md" file containing a list of the pages grouped by tags
It uses the info in the YAML metadata of each page, for the pages which
provide a "tags" keyword (whose value is a list of strings)
"""
config_scheme = (
('filename', Type(str, default='tags.md')),
('folder', Type(str, default='aux')),
('template', Type(str)),
('css_name', Type(str, default='.button')),
)
def __init__(self):
self.metadata = []
self.tag_dict = None
self.filename = "tags.md"
self.folder = "aux"
self.template = None
self.css_name = ".button"
self.templ = None
#pylint: disable=unused-argument
def on_page_markdown(self, markdown, page, config, files):
"""
takes markdown, page, config, and files
currently modifies the markdown to add a button to click to get related tag info
tag is customizeable by adding css that keys off the `self.css_name`
"""
page_url = page.url.split("/")
tags_link = ''
for i in range(len(page_url) - 1):
tags_link = tags_link + '../'
tags_link = tags_link + str(self.filename).strip('.md')
if tags_link[-1] != '/':
tags_link = tags_link + '/'
if 'tags' in page.meta:
swap_mark = [f"[{x}]({tags_link}#{x.lower()}){{{self.css_name}}}"
for x in page.meta['tags']]
swap_mark.append('\n')
return f'{" ".join(swap_mark)}{markdown}'
return markdown
def on_config(self, config):
"""Load config options"""
self.filename = Path(self.config.get("filename") or self.filename)
self.folder = Path(self.config.get("folder") or self.folder)
self.css_name = self.config.get("css_name")
# Make sure that the tags folder is absolute, and exists
if not self.folder.is_absolute():
self.folder = Path(config["docs_dir"]) / ".." / self.folder
if not self.folder.exists():
self.folder.mkdir(parents=True)
if self.config.get("template"):
self.template = Path(self.config.get("template"))
if self.template is None:
self.template = Path(__file__).parent.joinpath(
"templates"
).joinpath("tags.md.template")
environment = Environment(
loader=FileSystemLoader(searchpath=str(self.template.parent))
)
self.templ = environment.get_template(str(self.template.name))
def on_files(self, files, config):
"""Load files to check for tags"""
self.metadata = [
get_metadata(x.src_path, config['docs_dir'])
for x in files if x.src_path.endswith(".md")
]
# Create new file with tags
self.generate_tags_file()
# New file to add to the build
newfile = File(
path=str(self.filename),
src_dir=str(self.folder),
dest_dir=config["site_dir"],
use_directory_urls=False
)
files.append(newfile)
def generate_tags_page(self, data):
"""Generate the tags to be populated on the
mkdocs tag page"""
css_name = self.css_name
if css_name[0:1] == '.':
css_name = css_name[1:len(css_name)]
return self.templ.render(
tags=sorted(data.items(), key=lambda t: t[0].lower()),
css_name = css_name,
)
def generate_tags_file(self):
"""Generate a file to be stored on the mkdocs page"""
sorted_meta = sorted(self.metadata, key=lambda e: e.get("year", 5000) if e else 0)
self.tag_dict = defaultdict(list)
for meta in sorted_meta:
if not meta:
continue
if "title" not in meta:
meta["title"] = meta['filename'].split("/")[-1].strip('.md')
tags = meta.get("tags", [])
for tag in tags:
self.tag_dict[tag].append(meta)
with open(str(self.folder / self.filename), "w", encoding='utf-8') as fname:
fname.write(self.generate_tags_page(self.tag_dict))
# Helper functions
def get_metadata(name, path):
"""Get the metadata off of a file"""
filename = Path(path) / Path(name)
with filename.open() as fname:
match_string = search(r"\A\s*---\n.*?\n---", fname.read(), flags=DOTALL | MULTILINE)
if match_string:
try:
metadata = match_string.group(0).strip('---')
meta = load(metadata, Loader=FullLoader)
meta.update(filename=name)
return meta
except YAMLError as err:
log.error("Couldn't parse %s yaml due to %s", fname, err)
return None

View File

@ -1,7 +0,0 @@
# Contents grouped by tag
{% for tag, pages in tags %}
## <span class="{{css_name}}">{{tag}}</span>
{% for page in pages %}
* [{{page.title}}]({{page.filename}})
{% endfor %}{% endfor %}

View File

@ -1,127 +1,9 @@
site_name: No Fuss Computing
site_description: A wiki with random bits of information you may find useful.
site_url: https://nofusscomputing.com
site_author: No Fuss Computing
copyright: Copyright &copy; No Fuss Computing 2021
#site_favicon: favicon.ico
# site_dir: 'docs/static/mkdocs_build'
docs_dir: 'pages'
site_dir: build
INHERIT: website-template/mkdocs.yml
repo_name: Website
#repo_url: https://gitlab.com/nofusscomputing/infrastructure/website
repo_url: https://gitlab.com/nofusscomputing/infrastructure/website
#edit_uri: '-/blob/pages'
#edit_uri: '-/blob/master/pages/'
edit_uri: ''
theme:
name: material
logo: assets/logo.png
custom_dir: theme-overrides
icon:
repo: fontawesome/brands/gitlab # (1)!
locale: en
font: false
features:
- navigation.tracking
- navigation.tabs
- navigation.tabs.sticky
- navigation.expand
- navigation.indexes
- toc.integrate
- navigation.top
- header.autohide
- navigation.sections
palette:
- scheme: default
primary: indigo
accent: indigo
toggle:
icon: material/lightbulb-outline
name: Switch to dark mode
- scheme: slate
primary: indigo
accent: indigo
toggle:
icon: material/lightbulb
name: Switch to light mode
plugins:
- tags:
filename: tags.md
folder: pages
css_name: ".tags"
- search:
lang: en
- git-revision-date-localized:
type: iso_date
enable_creation_date: true
exclude:
- index.md
- tags.md
# - minify:
# minify_html: true
extra:
homepage: https://nofusscomputing.com
version: 1.0
social:
- link: https://hub.docker.com/u/nofusscomputing
name: DockerHub
icon: fontawesome/brands/docker
- link: https://facebook.com/NoFussComputing
name: Facebook
icon: fontawesome/brands/facebook
- link: https://gitlab.com/nofusscomputing
name: Gitlab
icon: fontawesome/brands/gitlab
- link: https://github.com/NoFussComputing
name: Github
icon: fontawesome/brands/github
# - link: https://readthedocs.org/profiles/nofusscomputing/
# nane: ReadTheDocs
# icon: fontawesome/brands/readthedocs
# link: https://
blog:
dir: articles
author: jon_nfc
author_image: https://gitlab.com/uploads/-/system/user/avatar/4125177/avatar.png
words_read_per_minute: 300
list_length: 25
extended_preview: true
extra_css:
- stylesheets/extra.css
markdown_extensions:
- def_list
- pymdownx.tasklist:
custom_checkbox: true
- meta
- attr_list
- admonition
- pymdownx.details
- pymdownx.superfences
- pymdownx.tabbed:
alternate_style: true
# - pymdownx.emoji:
# emoji_index: !!python/name:materialx.emoji.twemoji
# emoji_generator: !!python/name:materialx.emoji.to_svg
# options:
# custom_icons:
# - .icons
nav:
- Home: index.md

View File

@ -2,7 +2,7 @@ mkdocs-minify-plugin==0.5.0
mkdocs-material-extensions==1.0.3
wheel
mkdocs-material==8.1.7
./custom-plugins/mkdocs-plugin-tags
./website-template/custom-plugins/mkdocs-plugin-tags
mkdocs-git-revision-date-localized-plugin==0.11.1
pymdown-extensions==9.1
Jinja2==3.0.3

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"/></svg>

Before

Width:  |  Height:  |  Size: 663 B

View File

@ -1,27 +0,0 @@
{% extends "base.html" %}
{% block content %}
<span itemscope itemtype="https://schema.org/CreativeWork">
{% if page.meta.type == "blog" %}
<span itemprop="hasPart" itemscope itemtype="https://schema.org/BlogPosting">
{% elif page.meta.type == "article" %}
<span itemprop="hasPart" itemscope itemtype="https://schema.org/Article">
{% endif %}
<h1 itemprop="name">{{ page.title }}</h1>
{% include "partials/article_metadata.html" %}
<hr>
<span itemprop="text">{{ page.content }}</span>
<span itemprop="publisher" itemscope itemtype="https://schema.org/Organization" style="font-size: 10px;">
Published by: <span itemprop="name">{{ config.site_name }}</span>, <span itemprop="url">{{ config.site_url }}</span>
</span>
{% if page.meta.copyrightHolder %}
<br>
<span itemprop="copyrightHolder" itemscope itemtype="https://schema.org/Person" style="font-size: 10px;">
Copyright <span itemprop="name">{{ page.meta.copyrightHolder }}</span>
</span>
{% endif %}
{% if page.meta.type %}</span>{% endif %}
</span>
{% endblock %}

View File

@ -1,38 +0,0 @@
{% extends "base.html" %}
{% block content %}
{{ page.content }}
{% set article_posts = [] %}
{% for page in nav.pages %}
{% if page.url.startswith(config.extra.blog.dir) and page.meta.date is defined %}
<!-- or "" suppresses "None" output-->
{{ article_posts.append( page ) or "" }}
{% endif %}
{% endfor %}
<span itemscope itemtype="https://schema.org/CreativeWork">
{% for page in (article_posts|sort(attribute="meta.date", reverse=True))[:config.extra.blog.list_length] %}
{% if page.meta.type == "blog" %}
<span itemprop="hasPart" itemscope itemtype="https://schema.org/BlogPosting">
{% elif page.meta.type == "article" %}
<span itemprop="hasPart" itemscope itemtype="https://schema.org/Article">
{% endif %}
<h2 itemprop="name"><a href="{{ page.url|url }}" itemprop="url">{{ page.title }}</a></h2>
<hr>
{% include "partials/article_metadata.html" %}
<p>
{{ page.meta.description }}
</p>
<!-- Use a hidden p tag to provide a preview -->
{% if config.extra.blog.extended_preview %}
<a href="{{ page.url|url }}#more">
<span class="twemoji">
{% include ".icons/octicons/arrow-right-24.svg" %}
</span>
Continue reading
<hr>
</a>
{% endif %}
{% if page.meta.type %}</span>{% endif %}
{% endfor %}
</span>
{% endblock %}

View File

@ -1,68 +0,0 @@
{% extends "base.html" %}
{% block content %}
<div itemscope itemtype="https://schema.org/WebSite">
{{ page.content }}
{% set article_posts = [] %}
{% for page in nav.pages %}
{% if page.url.startswith(config.extra.blog.dir) and page.meta.date is defined %}
<!-- or "" suppresses "None" output-->
{{ article_posts.append( page ) or "" }}
{% endif %}
{% endfor %}
<div class="container">
<div class="row" >
<div itemprop="hasPart" itemscope itemtype="https://schema.org/CreativeWork" class="column">
<a itemprop="url" href="articles/index.html"><h2 itemprop="name">Articles</h2></a>
<ul>
{% for page in (article_posts|sort(attribute="meta.date", reverse=True))[:config.extra.blog.list_length] %}
{% if page.meta.type == "blog" %}
<li itemprop="hasPart" itemscope itemtype="https://schema.org/BlogPosting">
{% elif page.meta.type == "article" %}
<li itemprop="hasPart" itemscope itemtype="https://schema.org/Article">
{% else %}
<li>
{% endif %}
<p>
<h3><a itemprop="url" href="{{ page.url|url }}"><span itemprop="name">{{ page.title }}</span></a></h3>
<aside class="mdx-author">
<span>
<span itemprop="author" itemscope itemtype="https://schema.org/Person">
<img itemprop="image" alt={{ config.extra.blog.author }} src={{ config.extra.blog.author_image }} style="vertical-align: middle;">
<strong style="padding-left: 5px;" itemprop="name" >{{ config.extra.blog.author }}</strong>
</span>
<span class="twemoji">
{% include ".icons/octicons/calendar-24.svg" %}
</span>
<span itemprop="dateCreated">{{ page.meta.date.strftime("%Y-%m-%d") }}</span> ·
<span class="twemoji">
{% include ".icons/octicons/clock-24.svg" %}
</span>
<!--Min reading time is 1 minute-->
{% set read_time = page.content | wordcount // config.extra.blog.words_read_per_minute|default(300, true) %}
{% if read_time == 0 %}
{% set read_time = 1 %}
{% endif %}
<span itemprop="timeRequired">{{ read_time }} min</span> read
</span>
</aside>
</p>
</li>
{% endfor %}
</ul>
</div>
<div class="column">
<h2>Quick Links</h2>
<ul>
<li><h3>About us</h3></li>
<li><h3><a href="operations/index.html">Operations</a></h3></li>
<li><h3><a href="projects/index.html">Our Projects</a></h3></li>
<li><h3>link 4</h3></li>
</ul>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,7 +0,0 @@
<a href="{{ page.url|url }}">
<span class="twemoji">
{% include ".icons/octicons/arrow-right-24.svg" %}
</span>
Continue reading
<hr>
</a>

View File

@ -1,32 +0,0 @@
<aside class="mdx-author">
{% if config.extra.blog.author_image is defined %}
<p>
<img alt={{ config.extra.blog.author }} src={{ config.extra.blog.author_image }}>
</p>
{% endif %}
<p>
<span itemprop="author" itemscope itemtype="https://schema.org/Person">
{% if config.extra.blog.author %}
<strong itemprop="name">{{ config.extra.blog.author }}</strong>
·
{% endif %}
{% include "partials/article_social.html" %}
</span>
<span>
<span class="twemoji">
{% include ".icons/octicons/calendar-24.svg" %}
</span>
<span itemprop="dateCreated">{{ page.meta.date.strftime("%Y-%m-%d") }}</span> ·
{% if page.meta.git_revision_date_localized %}Updated <span itemprop="dateModified">{{ page.meta.git_revision_date_localized.replace("\n", "").replace("\r", "") }}</span> <br>{% endif %}
<span class="twemoji">
{% include ".icons/octicons/clock-24.svg" %}
</span>
<!--Min reading time is 1 minute-->
{% set read_time = page.content | wordcount // config.extra.blog.words_read_per_minute|default(300, true) %}
{% if read_time == 0 %}
{% set read_time = 1 %}
{% endif %}
<span itemprop="timeRequired">{{ read_time }} min </span>read
</span>
</p>
</aside>

View File

@ -1,17 +0,0 @@
{% if config.extra.social %}
{% set ns = namespace() %}
{% for social in config.extra.social %}
{% set title = social.name %}
{% if not title and "//" in social.link %}
{% set _,url = social.link.split("//") %}
{% set title = url.split("/")[0] %}
{% endif %}
{% if ns.line_break is defined %}
{{ ns.line_break }}
{% endif %}
<a href="{{ social.link }}" target="_blank" rel="noopener" title="{{ title | e }}" class="twemoji">
{% include ".icons/" ~ social.icon ~ ".svg" %}
</a>
{% set ns.line_break = " · " %}
{% endfor %}
{% endif %}

View File

@ -1,14 +0,0 @@
{#-
This file was automatically generated - do not edit
-#}
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
{% include "partials/copyright.html" %}
{% if config.extra.social %}
{% include "partials/social.html" %}
{% endif %}
</div>
</div>
</footer>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{%- for file in pages -%}
{% if not file.page.is_link %}
<url>
<loc>{% if file.page.canonical_url %}{{ file.page.canonical_url|e }}{% else %}{{ file.page.abs_url|e }}{% endif %}</loc>
{% if file.page.meta.git_revision_date_localized %}<lastmod>{{ file.page.meta.git_revision_date_localized.replace("\n", "").replace("\r", "").replace('<span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date">', '').replace('</span>','') }}</lastmod>{% endif %}
<changefreq>weekly</changefreq>
</url>
{%- endif -%}
{% endfor %}
</urlset>