Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/accessibility #19

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ venv/
dist/
build/
adr_viewer.egg-info/
.pytest_cache/
.pytest_cache/
.DS_Store
57 changes: 57 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [1.3.0](https://pypi.org/project/adr-viewer/1.3.0/) - 2022-02-28

### Added
- Ignore badly-formed ADR files and report
- Allow template override and pass in a teplate directory
- Customizing server port

### Fixed
- Some typos

### Removed
- Support for Python 2.7

## [1.2.0](https://pypi.org/project/adr-viewer/1.2.0/) - 2019-06-19

### Added
- Support for Pending ADRs

## [1.1.1](https://pypi.org/project/adr-viewer/1.1.1/) - 2019-02-26

### Added
- Python 3 support


### Fixed
- Included HTML file in package

## [1.1.0](https://pypi.org/project/adr-viewer/1.1.0/) - 2018-09-10

### Added
- Pypi release details
- Accepted records are green
- Superceded records are now grey and have their titles struck through
- Records with unknown state default to white
- Amended records are yellow
- Since multiple statuses are possible in ADR files, we now extract all `p` objects below the Status header and use those for deciding on which style to apply
- Statuses also now represented by icons (colour-blindness)
- Created and updated this project's ADRs and visualised them
- Improved `README.md`

## [1.0.1](https://pypi.org/project/adr-viewer/1.0.1/) - 2018-09-02

### Added
- Classifiers to `setup.py`


## [1.0.0](https://pypi.org/project/adr-viewer/1.0.0/) - 2018-09-02

### Initial Release

65 changes: 60 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,66 @@ $ python setup.py install
Usage: adr-viewer [OPTIONS]

Options:
--adr-path TEXT Directory containing ADR files. [default: doc/adr/]
--output TEXT File to write output to. [default: index.html]
--serve Serve content at http://localhost:8000/
--port INT Custom server port [default: 8000]
--help Show this message and exit.
--adr-path TEXT Directory containing ADR files. [default: doc/adr/]
--output TEXT File to write output to. [default: index.html]
--serve Serve content at http://localhost:8000/
--port INTEGER Change port for the server [default: 8000]
--template-dir TEXT Template directory.
--heading TEXT ADR Page Heading [default: ADR Viewer - ]
--config TEXT Configuration settings [default: config.toml]
--help Show this message and exit.
```

The configuration file (in [TOML](http://toml.io) format) has settings that control the look of the ADR page. These settings are specifically targetted at the colours of the page to aid with those who have colour-blindness.

The colours (the example used here is `green`) can be specified in a number of formats:

- Hex values: #00FF00
- HTML Colour codes: Green
- RGB values: rgb(0,255,0)
- RGB with alpha: rgba(0,255,0,0)
- HSL values: hsl(0,100%,50%)
- HSL with alpha: hsla(0,100%,50%,0)

More information about codes and names for HTML colours can be found [here](http://htmlcolorcodes.com).

The icons for each bar can also be modified using the `.icon` property of each bar. The icon names can be sourced from the [`fontawesome` library's documentation](https://fontawesome.com/v4/icons/).

Note that only ***FREE*** icons are allowed. ***Pro*** icons will not be displayed.

```bash
# Configuration for adr-viewer
# in TOML format http://toml.io

title = "TOML Configuration for adr-viewer colours"

[page]
# Properties for the page
background-color = "white"

[status]
# Properties for the bars that display each ADR

# Accepted
accepted.icon = "fa-check"
accepted.background-color = "lightgreen"

# Amended
amended.icon = "fa-arrow-down"
amended.background-color = "yellow"

# Pending
pending.icon = "fa-hourglass-half"
pending.background-color = "lightblue"

# Superseded
superseded.icon = "fa-times"
superseded.background-color = "lightgrey"
superseded.text-decoration = "line-through"

# Unknown
unknown.icon = "fa-question"
unknown.background-color = "white"
```

The default for `--adr-path` is `doc/adr/` because this is the default path generated by `adr-tools`.
Expand Down
102 changes: 82 additions & 20 deletions adr_viewer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import glob
from jinja2.loaders import FileSystemLoader
import mistune
import os
import glob
import toml
import ast

from bottle import Bottle, run
from bs4 import BeautifulSoup
from jinja2 import Environment, PackageLoader, select_autoescape
import click
from bottle import Bottle, run
from jinja2 import Environment, PackageLoader, select_autoescape
from jinja2.loaders import FileSystemLoader
import mistune


def extract_statuses_from_adr(page_object):
Expand All @@ -31,12 +34,13 @@ def parse_adr_to_config(path):
soup = BeautifulSoup(adr_as_html, features='html.parser')

status = list(extract_statuses_from_adr(soup))

if any([line.startswith("Amended by") for line in status]):
if any([line.startswith("Amended") for line in status]):
status = 'amended'
elif any([line.startswith("Accepted") for line in status]):
status = 'accepted'
elif any([line.startswith("Superseded by") for line in status]):
elif any([line.startswith("Superceded") for line in status]):
status = 'superseded'
elif any([line.startswith("Superseded") for line in status]):
status = 'superseded'
elif any([line.startswith("Pending") for line in status]):
status = 'pending'
Expand All @@ -46,7 +50,7 @@ def parse_adr_to_config(path):
header = soup.find('h1')

if header:
return {
return {
'status': status,
'body': adr_as_html,
'title': header.text
Expand All @@ -58,7 +62,7 @@ def parse_adr_to_config(path):
def render_html(config, template_dir_override=None):

env = Environment(
loader=PackageLoader('adr_viewer', 'templates') if template_dir_override is None else FileSystemLoader(template_dir_override),
loader = PackageLoader('adr_viewer', 'templates') if template_dir_override is None else FileSystemLoader(template_dir_override),
autoescape=select_autoescape(['html', 'xml'])
)

Expand All @@ -80,15 +84,52 @@ def run_server(content, port):
run(app, host='localhost', port=port, quiet=True)


def generate_content(path, template_dir_override=None):
def generate_content(path, template_dir_override=None,
heading=None, configuration=None):

files = get_adr_files("%s/*.md" % path)

if not heading:
heading = 'ADR Viewer - ' + os.path.basename(os.getcwd())

config = {
'project_title': os.path.basename(os.getcwd()),
'records': []
'heading': heading,
'records': [],
'page': []
}

# Set defaults for colours (or use passed in configuration)
conf = {}
if type(configuration) == type(None):
conf = ast.literal_eval('{ \
"accepted": { \
"icon": "fa-check", \
"background-color": "lightgreen"}, \
"amended": {\
"icon": "fa-arrow-down", \
"background-color": "yellow"}, \
"pending": { \
"icon": "fa-hourglass-half", \
"background-color": "lightblue"}, \
"superseded": { \
"icon" : "fa-times",\
"background-color": "lightgrey", \
"text-decoration": "line-through"}, \
"unknown": { \
"icon" : "fa-question", \
"background-color": "white"}}')
config['page'] = ast.literal_eval('{"background-color": "white"}')
else:
conf = configuration['status']
config['page'] = configuration['page']

# Retrieve properties from configuration
for status in conf:
properties = {}
for property in conf[status]:
properties[property] = conf[status][property]
config[status] = properties

for index, adr_file in enumerate(files):

adr_attributes = parse_adr_to_config(adr_file)
Expand All @@ -104,16 +145,37 @@ def generate_content(path, template_dir_override=None):


@click.command()
@click.option('--adr-path', default='doc/adr/', help='Directory containing ADR files.', show_default=True)
@click.option('--output', default='index.html', help='File to write output to.', show_default=True)
@click.option('--serve', default=False, help='Serve content at http://localhost:8000/', is_flag=True)
@click.option('--port', default=8000, help='Change port for the server', show_default=True)
@click.option('--template-dir', default=None, help='Template directory.', show_default=True)
def main(adr_path, output, serve, port, template_dir):
content = generate_content(adr_path, template_dir)
@click.option('--adr-path', default='doc/adr/',
help='Directory containing ADR files.', show_default=True)
@click.option('--output', default='index.html',
help='File to write output to.', show_default=True)
@click.option('--serve', default=False,
help='Serve content at http://localhost:8000/', is_flag=True)
@click.option('--port', default=8000,
help='Change port for the server', show_default=True)
@click.option('--template-dir', default=None,
help='Template directory.', show_default=True)
@click.option('--heading', default='ADR Viewer - ',
help='ADR Page Heading', show_default=True)
@click.option('--config', default='config.toml',
help='Configuration settings', show_default=True)
def main(adr_path, output, serve, port, template_dir, heading, config):
from os.path import exists
# Ensure that there is a configuration file
if exists(config):
configuration_file = toml.load(config)
else:
configuration_file = None

content = generate_content(adr_path, template_dir,
heading, configuration_file)

if serve:
run_server(content, port)
else:
with open(output, 'w') as out:
out.write(content)


if __name__ == '__main__':
main()
32 changes: 32 additions & 0 deletions adr_viewer/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Configuration for adr-viewer
# in TOML format http://toml.io

title = "TOML Configuration for adr-viewer look and feel"

[page]
# Properties for the page
background-color = "white"

[status]
# Properties for the bars that display each ADR

# Accepted
accepted.icon = "fa-check"
accepted.background-color = "lightgreen"

# Amended
amended.icon = "fa-arrow-down"
amended.background-color = "yellow"

# Pending
pending.icon = "fa-hourglass-half"
pending.background-color = "lightblue"

# Superseded
superseded.icon = "fa-times"
superseded.background-color = "lightgrey"
superseded.text-decoration = "line-through"

# Unknown
unknown.icon = "fa-question"
unknown.background-color = "white"
Loading