diff --git a/.gitignore b/.gitignore index e69de29..4d43738 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +/venv diff --git a/app.py b/app.py new file mode 100755 index 0000000..056a737 --- /dev/null +++ b/app.py @@ -0,0 +1,462 @@ +#!/usr/bin/env python3 + +import bottle +import datetime +import dateutil +import functools +import jinja2 +import pyld +import re +import requests + +from bottle import jinja2_template as template, request, response +from string import Template + +# This only exists for exporting the bottle app object for a WSGI server such as Gunicorn +application = bottle.app() + +# Directories to search for HTML templates +bottle.TEMPLATE_PATH = [ './templates' ] + +def query(query_string, jsonld_frame=None): + """ + Send query to Fuseki via HTTP. + Return the query results. + """ + + http_request = requests.post( + 'http://localhost:7000/dokk', + data = { 'format': 'json', 'query': query_string}) + + results = http_request.json() + + if jsonld_frame: + results = pyld.jsonld.frame(results, jsonld_frame, options={'omitGraph':False}) + + return results + +def human_size(bytes, B=False): + """ + Convert a file size in bytes to a human friendly form. + This is only used in templates when showing file sizes. + """ + + for unit in [ 'B' if B else '', 'K', 'M', 'G', 'T', 'P' ]: + if bytes < 1024: break + bytes = bytes / 1024 + + return '{}{}'.format(round(bytes), unit).rjust(5) + +template = functools.partial(template, template_settings = { + 'filters': { + 'datetime': lambda date: dateutil.parser.parse(date).strftime('%b %-d, %Y - %H:%M%z%Z'), + 'human_size': human_size + }, + 'globals': { + 'now': lambda: datetime.datetime.now(datetime.timezone.utc), + 'request': request, + 'url': application.get_url, + }, + 'autoescape': True +}) + +@bottle.error(404) +def error404(error): + """ + Custom 404 page. + + :param error: bottle.HTTPError given by Bottle when calling abort(404). + """ + + return '[404] {}'.format(error.body) + +@bottle.get('/static/', name='static') +def static(filename): + """ + Path for serving static files. + """ + + return bottle.static_file(filename, root='./static/') + +@bottle.get('/', name='homepage') +def homepage(): + """ + """ + + return template('index.html') + +@bottle.get('/library', name='library') +def library(): + """ + """ + + data = query( + ''' + PREFIX library: + PREFIX license: + + CONSTRUCT { + ?item library:title ?title; + library:author ?author ; + library:license ?license . + ?license license:id ?license_id ; + license:name ?license_name . + } + WHERE { + ?item library:title ?title ; + library:author ?author ; + library:license ?license . + + OPTIONAL { + ?license license:id ?license_id_optional ; + license:name ?license_name_optional . + } + + BIND(COALESCE(?license_id_optional, SUBSTR(STR(?license), 14)) AS ?license_id) + BIND(COALESCE(?license_name_optional, SUBSTR(STR(?license), 14)) AS ?license_name) + } + ORDER BY UCASE(?title) + ''', + { + '@context': { + 'library': 'dokk:library:', + 'license': 'dokk:license:', + 'library:author': { '@container': '@set' }, + 'library:license': { '@container': '@set' } + }, + 'library:title': {} + }) + + return template('library.html', data=data) + +@bottle.get('/library/', name='library_item') +def library_item(item_id): + """ + """ + + item_iri = '' + + try: + with open('../blob.dokk.org/pdf_to_text/' + item_id + '.txt', 'r') as file: + item_plaintext = file.read() + except: + item_plaintext = '' + + data = query(f''' + PREFIX library: + PREFIX license: + + CONSTRUCT {{ + ?item library:title ?title ; + library:author ?author ; + library:license ?license . + + ?license license:id ?license_id ; + license:name ?license_name . + }} + WHERE {{ + ?item + library:title ?title ; + library:author ?author ; + library:license ?license . + + FILTER (?item = {item_iri}) + + OPTIONAL {{ + ?license license:id ?license_id_optional ; + license:name ?license_name_optional . + }} + + BIND(COALESCE(?license_id_optional, SUBSTR(STR(?license), 14)) AS ?license_id) + BIND(COALESCE(?license_name_optional, SUBSTR(STR(?license), 14)) AS ?license_name) + }} + ''', + { + '@context': { + 'library': 'dokk:library:', + 'license': 'dokk:license:', + 'library:author': { '@container': '@set' }, + 'library:license': { '@container': '@set' } + }, + 'library:title': {} + }) + + return template('library_item.html', data=data['@graph'][0], item_id=item_id, plaintext=item_plaintext) + +@bottle.get('/license', name='licenses') +def licenses(): + """ + """ + + data = query( + ''' + PREFIX license: + + SELECT * + WHERE { + ?license license:id ?id ; + license:name ?name. + } + ORDER BY ASC(UCASE(?name)) + ''') + + return template('licenses.html', data=data) + +@bottle.get('/manpages', name='manpages') +def manpages(): + """ + """ + + data = query( + ''' + PREFIX mp: + + SELECT DISTINCT ?distribution ?version + WHERE { + [] mp:source [ + mp:distribution_version ?version ; + mp:distribution_name ?distribution ; + ] . + } + ORDER BY ?distribution ?version + ''') + + return template('manpages.html', data=data) + +@bottle.get('/manpages//', name='manpages_distribution') +def manpages_distribution(distribution, version): + """ + List packages by distribution. + """ + + data = query( + f''' + PREFIX mp: + + SELECT DISTINCT ?package + WHERE {{ + ?id mp:source [ + mp:distribution_name "{distribution}" ; + mp:distribution_version "{version}" ; + mp:package ?package ; + ] . + }} + ORDER BY ?package + ''') + + return template('manpages_distribution.html', data=data, distribution=distribution, version=version) + +@bottle.get('/manpages///', name='manpages_package') +def manpages_package(distribution, version, package): + """ + List manpages by package. + """ + + data = query( + f''' + PREFIX mp: + + SELECT ?id ?filename + WHERE {{ + ?id mp:source [ + mp:package "{package}" ; + mp:distribution_version "{version}" ; + mp:distribution_name "{distribution}" ; + mp:filename ?filename ; + ] . + }} + ORDER BY ?filename + ''') + + return template('manpages_package.html', data=data, distribution=distribution, version=version, package=package) + +@bottle.get('/manpages////.
.', name='manpages_page') +def manpages_page(distribution, version, package, name, section, lang): + """ + Display a single manpage. + """ + + page_id = f'' + + # These characters where url-encoded when creating the RDF data because they + # make invalid URIs. This means for example that in the graph the URIs will be + # encoded with %23 instead of # + page_id = page_id.replace(' ', '_') \ + .replace('[', '%5B') \ + .replace(']', '%5D') \ + .replace('#', '%23') + + data = query( + f''' + PREFIX mp: + + DESCRIBE {page_id} + ''', + { + '@context': { + 'mp': 'dokk:manpages:', + }, + 'mp:source': {}, + }) + + # Replace references to other manpages with links. + # Manpages have a section "See also" at the bottom where they suggest other pages. + # For example: + # SEE ALSO + # cdk(3), cdk_screen(3), cdk_display(3), cdk_binding(3), cdk_util(3) + # We convert these strings to links to other pages. + # Example: ls(1) -> ls(1) + # regex explanation: + # - some manpages use a bold or italic name, so we match an optional + # tag + # - match valid characters for a manpage, assign name + # - match optional closing or tags + # - match '(' + # - match number, assign name
+ # - match ')' + html = data['@graph'][0]['mp:html'] + html = re.sub ( + '(?:|)?(?P[\w_.:-]+)(?:|)?\((?P
[0-9]\w*)\)', + lambda match: + f'''{match.group('page')}({match.group('section')})''', + html) + + data['@graph'][0]['mp:html'] = html + + return template('manpage.html', data=data['@graph'][0], distribution=distribution, + version=version, package=package, name=name, section=section, lang=lang) + +@bottle.get('/manpages/.
', name='manpages_disambiguation') +def manpages_disambiguation(name, section): + """ + Show a list of manpages that match and
+ """ + + data = query( + f''' + PREFIX mp: + + DESCRIBE ?page + WHERE {{ + ?page mp:name_lowercase "{name}" ; + mp:section_lowercase "{section}" . + }} + ''', + { + '@context': { + 'mp': 'dokk:manpages:', + }, + 'mp:source': {}, + }) + + return template('manpage_disambiguation.html', name=name, section=section, data=data) + +@bottle.get('/license/', name='license') +def license(id): + """ + """ + + license_iri = 'license:' + id + + data = query(Template( + ''' + PREFIX license: + + DESCRIBE $license + ''').substitute(license=license_iri)) + + return template('license.html', data=data) + +@bottle.get('/mimi_and_eunice', name='mimi_and_eunice') +def mimi_and_eunice(): + """ + """ + + data = query( + ''' + PREFIX mimi_eunice: + PREFIX xsd: + + SELECT ?number ?title + WHERE { + ?id mimi_eunice:title ?title . + BIND (SUBSTR(STR(?id), 22) as ?number) + } + ORDER BY ?number + ''') + + return template('mimi_and_eunice.html', data=data) + +@bottle.get('/mimi_and_eunice/', name='mimi_and_eunice_strip') +def mimi_and_eunice_strip(number): + """ + """ + + iri = '' + + data = query(Template( + ''' + PREFIX license: + PREFIX mimi_eunice: + + DESCRIBE $iri ?license + WHERE { + $iri mimi_eunice:license ?license + } + ''').substitute(iri=iri), + { + '@context': { + 'license': 'dokk:license:', + 'mimi_eunice': 'dokk:mimi_and_eunice:', + 'mimi_eunice:tag': { '@container': '@set' }, + 'mimi_eunice:transcript': { '@container': '@set' } + }, + 'mimi_eunice:license': {}, + 'mimi_eunice:transcript': { + 'mimi_eunice:order': {} + } + }) + + return template('mimi_and_eunice_strip.html', data=data['@graph'][0]) + +@bottle.get('/articles', name='articles') +def articles(): + """ + """ + + data = query( + ''' + PREFIX : + + SELECT ?iri ?title + WHERE { + ?iri :title ?title + } + ORDER BY ?title + ''') + + return template('articles.html', data=data) + +@bottle.get('/', name='article') +def article(id): + """ + """ + + data = query( + f''' + PREFIX : + + DESCRIBE + ''', + { + '@context': { + 'a': 'dokk:articles:' + } + }) + + if '@graph' not in data or len(data['@graph']) < 1: + bottle.abort(404, "Article doesn't exist.") + + return template('article.html', data=data['@graph'][0]) diff --git a/dokk.png b/dokk.png new file mode 100644 index 0000000..126555a Binary files /dev/null and b/dokk.png differ diff --git a/dokk.svg b/dokk.svg new file mode 100644 index 0000000..ccc56b4 --- /dev/null +++ b/dokk.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..84562f6 Binary files /dev/null and b/favicon.ico differ diff --git a/index.html b/index.html deleted file mode 100644 index 715fa78..0000000 --- a/index.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - DOKK - - - - -

- DOKK is a free, community-curated data repository. -

-

- Join the - mailing list - or download the - data, - and participate to create a free database of the world's knowledge. - Let's build it together! - -



- IRC: #peers at irc.libera.chat -

- - diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1e37561 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +bottle +jinja2 +pyld +python-dateutil +requests diff --git a/static/css/asciidoctor.css b/static/css/asciidoctor.css new file mode 100644 index 0000000..6b63163 --- /dev/null +++ b/static/css/asciidoctor.css @@ -0,0 +1,2420 @@ +/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */ +/* Uncomment the following line when using as a custom stylesheet */ +/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; +} + +a { + background: none; +} + +a:focus { + outline: thin dotted; +} + +a:active, +a:hover { + outline: 0; +} + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +b, +strong { + font-weight: bold; +} + +abbr { + font-size: 0.9em; +} + +abbr[title] { + cursor: help; + border-bottom: 1px dotted #dddddf; + text-decoration: none; +} + +dfn { + font-style: italic; +} + +hr { + height: 0; +} + +mark { + background: #ff0; + color: #000; +} + +code, +kbd, +pre, +samp { + font-family: monospace; + font-size: 1em; +} + +pre { + white-space: pre-wrap; +} + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +small { + font-size: 80%; +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + border: 0; +} + +svg:not(:root) { + overflow: hidden; +} + +figure { + margin: 0; +} + +audio, +video { + display: inline-block; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +fieldset { + border: 1px solid silver; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +legend { + border: 0; + padding: 0; +} + +button, +input, +select, +textarea { + font-family: inherit; + font-size: 100%; + margin: 0; +} + +button, +input { + line-height: normal; +} + +button, +select { + text-transform: none; +} + +button, +html input[type=button], +input[type=reset], +input[type=submit] { + -webkit-appearance: button; + cursor: pointer; +} + +button[disabled], +html input[disabled] { + cursor: default; +} + +input[type=checkbox], +input[type=radio] { + padding: 0; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +*, +::before, +::after { + box-sizing: border-box; +} + +html, +body { + font-size: 100%; +} + +body { + background: #fff; + color: rgba(0, 0, 0, 0.8); + padding: 0; + margin: 0; + font-family: "Noto Serif", "DejaVu Serif", serif; + line-height: 1; + position: relative; + cursor: auto; + tab-size: 4; + word-wrap: anywhere; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; +} + +a:hover { + cursor: pointer; +} + +img, +object, +embed { + max-width: 100%; + height: auto; +} + +object, +embed { + height: 100%; +} + +img { + -ms-interpolation-mode: bicubic; +} + +.left { + float: left !important; +} + +.right { + float: right !important; +} + +.text-left { + text-align: left !important; +} + +.text-right { + text-align: right !important; +} + +.text-center { + text-align: center !important; +} + +.text-justify { + text-align: justify !important; +} + +.hide { + display: none; +} + +img, +object, +svg { + display: inline-block; + vertical-align: middle; +} + +textarea { + height: auto; + min-height: 50px; +} + +select { + width: 100%; +} + +.subheader, +.admonitionblock td.content > .title, +.audioblock > .title, +.exampleblock > .title, +.imageblock > .title, +.listingblock > .title, +.literalblock > .title, +.stemblock > .title, +.openblock > .title, +.paragraph > .title, +.quoteblock > .title, +table.tableblock > .title, +.verseblock > .title, +.videoblock > .title, +.dlist > .title, +.olist > .title, +.ulist > .title, +.qlist > .title, +.hdlist > .title { + line-height: 1.45; + color: #7a2518; + font-weight: 400; + margin-top: 0; + margin-bottom: 0.25em; +} + +div, +dl, +dt, +dd, +ul, +ol, +li, +h1, +h2, +h3, +#toctitle, +.sidebarblock > .content > .title, +h4, +h5, +h6, +pre, +form, +p, +blockquote, +th, +td { + margin: 0; + padding: 0; +} + +a { + color: #2156a5; + text-decoration: underline; + line-height: inherit; +} + +a:hover, +a:focus { + color: #1d4b8f; +} + +a img { + border: 0; +} + +p { + line-height: 1.6; + margin-bottom: 1.25em; + text-rendering: optimizeLegibility; +} + +p aside { + font-size: 0.875em; + line-height: 1.35; + font-style: italic; +} + +h1, +h2, +h3, +#toctitle, +.sidebarblock > .content > .title, +h4, +h5, +h6 { + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-weight: 300; + font-style: normal; + color: #ba3925; + text-rendering: optimizeLegibility; + margin-top: 1em; + margin-bottom: 0.5em; + line-height: 1.0125em; +} + +h1 small, +h2 small, +h3 small, +#toctitle small, +.sidebarblock > .content > .title small, +h4 small, +h5 small, +h6 small { + font-size: 60%; + color: #e99b8f; + line-height: 0; +} + +h1 { + font-size: 2.125em; +} + +h2 { + font-size: 1.6875em; +} + +h3, +#toctitle, +.sidebarblock > .content > .title { + font-size: 1.375em; +} + +h4, +h5 { + font-size: 1.125em; +} + +h6 { + font-size: 1em; +} + +hr { + border: solid #dddddf; + border-width: 1px 0 0; + clear: both; + margin: 1.25em 0 1.1875em; +} + +em, +i { + font-style: italic; + line-height: inherit; +} + +strong, +b { + font-weight: bold; + line-height: inherit; +} + +small { + font-size: 60%; + line-height: inherit; +} + +code { + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + font-weight: 400; + color: rgba(0, 0, 0, 0.9); +} + +ul, +ol, +dl { + line-height: 1.6; + margin-bottom: 1.25em; + list-style-position: outside; + font-family: inherit; +} + +ul, +ol { + margin-left: 1.5em; +} + +ul li ul, +ul li ol { + margin-left: 1.25em; + margin-bottom: 0; +} + +ul.circle { + list-style-type: circle; +} + +ul.disc { + list-style-type: disc; +} + +ul.square { + list-style-type: square; +} + +ul.circle ul:not([class]), +ul.disc ul:not([class]), +ul.square ul:not([class]) { + list-style: inherit; +} + +ol li ul, +ol li ol { + margin-left: 1.25em; + margin-bottom: 0; +} + +dl dt { + margin-bottom: 0.3125em; + font-weight: bold; +} + +dl dd { + margin-bottom: 1.25em; +} + +blockquote { + margin: 0 0 1.25em; + padding: 0.5625em 1.25em 0 1.1875em; + border-left: 1px solid #ddd; +} + +blockquote, +blockquote p { + line-height: 1.6; + color: rgba(0, 0, 0, 0.85); +} + +@media screen and (min-width: 768px) { + h1, + h2, + h3, + #toctitle, + .sidebarblock > .content > .title, + h4, + h5, + h6 { + line-height: 1.2; + } + + h1 { + font-size: 2.75em; + } + + h2 { + font-size: 2.3125em; + } + + h3, + #toctitle, + .sidebarblock > .content > .title { + font-size: 1.6875em; + } + + h4 { + font-size: 1.4375em; + } +} + +table { + background: #fff; + margin-bottom: 1.25em; + border: 1px solid #dedede; + word-wrap: normal; +} + +table thead, +table tfoot { + background: #f7f8f7; +} + +table thead tr th, +table thead tr td, +table tfoot tr th, +table tfoot tr td { + padding: 0.5em 0.625em 0.625em; + font-size: inherit; + color: rgba(0, 0, 0, 0.8); + text-align: left; +} + +table tr th, +table tr td { + padding: 0.5625em 0.625em; + font-size: inherit; + color: rgba(0, 0, 0, 0.8); +} + +table tr.even, +table tr.alt { + background: #f8f8f7; +} + +table thead tr th, +table tfoot tr th, +table tbody tr td, +table tr td, +table tfoot tr td { + line-height: 1.6; +} + +h1, +h2, +h3, +#toctitle, +.sidebarblock > .content > .title, +h4, +h5, +h6 { + line-height: 1.2; + word-spacing: -0.05em; +} + +h1 strong, +h2 strong, +h3 strong, +#toctitle strong, +.sidebarblock > .content > .title strong, +h4 strong, +h5 strong, +h6 strong { + font-weight: 400; +} + +.center { + margin-left: auto; + margin-right: auto; +} + +.stretch { + width: 100%; +} + +.clearfix::before, +.clearfix::after, +.float-group::before, +.float-group::after { + content: " "; + display: table; +} + +.clearfix::after, +.float-group::after { + clear: both; +} + +:not(pre).nobreak { + word-wrap: normal; +} + +:not(pre).nowrap { + white-space: nowrap; +} + +:not(pre).pre-wrap { + white-space: pre-wrap; +} + +:not(pre):not([class^=L]) > code { + font-size: 0.9375em; + font-style: normal !important; + letter-spacing: 0; + padding: 0.1em 0.5ex; + word-spacing: -0.15em; + background: #f7f7f8; + border-radius: 4px; + line-height: 1.45; + text-rendering: optimizeSpeed; +} + +pre { + color: rgba(0, 0, 0, 0.9); + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + line-height: 1.45; + text-rendering: optimizeSpeed; +} + +pre code, +pre pre { + color: inherit; + font-size: inherit; + line-height: inherit; +} + +pre > code { + display: block; +} + +pre.nowrap, +pre.nowrap pre { + white-space: pre; + word-wrap: normal; +} + +em em { + font-style: normal; +} + +strong strong { + font-weight: 400; +} + +.keyseq { + color: rgba(51, 51, 51, 0.8); +} + +kbd { + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + display: inline-block; + color: rgba(0, 0, 0, 0.8); + font-size: 0.65em; + line-height: 1.45; + background: #f7f7f7; + border: 1px solid #ccc; + border-radius: 3px; + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em #fff inset; + margin: 0 0.15em; + padding: 0.2em 0.5em; + vertical-align: middle; + position: relative; + top: -0.1em; + white-space: nowrap; +} + +.keyseq kbd:first-child { + margin-left: 0; +} + +.keyseq kbd:last-child { + margin-right: 0; +} + +.menuseq, +.menuref { + color: #000; +} + +.menuseq b:not(.caret), +.menuref { + font-weight: inherit; +} + +.menuseq { + word-spacing: -0.02em; +} + +.menuseq b.caret { + font-size: 1.25em; + line-height: 0.8; +} + +.menuseq i.caret { + font-weight: bold; + text-align: center; + width: 0.45em; +} + +b.button::before, +b.button::after { + position: relative; + top: -1px; + font-weight: 400; +} + +b.button::before { + content: "["; + padding: 0 3px 0 2px; +} + +b.button::after { + content: "]"; + padding: 0 2px 0 3px; +} + +p a > code:hover { + color: rgba(0, 0, 0, 0.9); +} + +#header, +#content, +#footnotes, +#footer { + width: 100%; + margin: 0 auto; + max-width: 62.5em; + *zoom: 1; + position: relative; + padding-left: 0.9375em; + padding-right: 0.9375em; +} + +#header::before, +#header::after, +#content::before, +#content::after, +#footnotes::before, +#footnotes::after, +#footer::before, +#footer::after { + content: " "; + display: table; +} + +#header::after, +#content::after, +#footnotes::after, +#footer::after { + clear: both; +} + +#content { + margin-top: 1.25em; +} + +#content::before { + content: none; +} + +#header > h1:first-child { + color: rgba(0, 0, 0, 0.85); + margin-top: 2.25rem; + margin-bottom: 0; +} + +#header > h1:first-child + #toc { + margin-top: 8px; + border-top: 1px solid #dddddf; +} + +#header > h1:only-child, +body.toc2 #header > h1:nth-last-child(2) { + border-bottom: 1px solid #dddddf; + padding-bottom: 8px; +} + +#header .details { + border-bottom: 1px solid #dddddf; + line-height: 1.45; + padding-top: 0.25em; + padding-bottom: 0.25em; + padding-left: 0.25em; + color: rgba(0, 0, 0, 0.6); + display: flex; + flex-flow: row wrap; +} + +#header .details span:first-child { + margin-left: -0.125em; +} + +#header .details span.email a { + color: rgba(0, 0, 0, 0.85); +} + +#header .details br { + display: none; +} + +#header .details br + span::before { + content: "\00a0\2013\00a0"; +} + +#header .details br + span.author::before { + content: "\00a0\22c5\00a0"; + color: rgba(0, 0, 0, 0.85); +} + +#header .details br + span#revremark::before { + content: "\00a0|\00a0"; +} + +#header #revnumber { + text-transform: capitalize; +} + +#header #revnumber::after { + content: "\00a0"; +} + +#content > h1:first-child:not([class]) { + color: rgba(0, 0, 0, 0.85); + border-bottom: 1px solid #dddddf; + padding-bottom: 8px; + margin-top: 0; + padding-top: 1rem; + margin-bottom: 1.25rem; +} + +#toc { + border-bottom: 1px solid #e7e7e9; + padding-bottom: 0.5em; +} + +#toc > ul { + margin-left: 0.125em; +} + +#toc ul.sectlevel0 > li > a { + font-style: italic; +} + +#toc ul.sectlevel0 ul.sectlevel1 { + margin: 0.5em 0; +} + +#toc ul { + font-family: "Open Sans", "DejaVu Sans", sans-serif; + list-style-type: none; +} + +#toc li { + line-height: 1.3334; + margin-top: 0.3334em; +} + +#toc a { + text-decoration: none; +} + +#toc a:active { + text-decoration: underline; +} + +#toctitle { + color: #7a2518; + font-size: 1.2em; +} + +@media screen and (min-width: 768px) { + #toctitle { + font-size: 1.375em; + } + + body.toc2 { + padding-left: 15em; + padding-right: 0; + } + + #toc.toc2 { + margin-top: 0 !important; + background: #f8f8f7; + position: fixed; + width: 15em; + left: 0; + top: 0; + border-right: 1px solid #e7e7e9; + border-top-width: 0 !important; + border-bottom-width: 0 !important; + z-index: 1000; + padding: 1.25em 1em; + height: 100%; + overflow: auto; + } + + #toc.toc2 #toctitle { + margin-top: 0; + margin-bottom: 0.8rem; + font-size: 1.2em; + } + + #toc.toc2 > ul { + font-size: 0.9em; + margin-bottom: 0; + } + + #toc.toc2 ul ul { + margin-left: 0; + padding-left: 1em; + } + + #toc.toc2 ul.sectlevel0 ul.sectlevel1 { + padding-left: 0; + margin-top: 0.5em; + margin-bottom: 0.5em; + } + + body.toc2.toc-right { + padding-left: 0; + padding-right: 15em; + } + + body.toc2.toc-right #toc.toc2 { + border-right-width: 0; + border-left: 1px solid #e7e7e9; + left: auto; + right: 0; + } +} + +@media screen and (min-width: 1280px) { + body.toc2 { + padding-left: 20em; + padding-right: 0; + } + + #toc.toc2 { + width: 20em; + } + + #toc.toc2 #toctitle { + font-size: 1.375em; + } + + #toc.toc2 > ul { + font-size: 0.95em; + } + + #toc.toc2 ul ul { + padding-left: 1.25em; + } + + body.toc2.toc-right { + padding-left: 0; + padding-right: 20em; + } +} + +#content #toc { + border: 1px solid #e0e0dc; + margin-bottom: 1.25em; + padding: 1.25em; + background: #f8f8f7; + border-radius: 4px; +} + +#content #toc > :first-child { + margin-top: 0; +} + +#content #toc > :last-child { + margin-bottom: 0; +} + +#footer { + max-width: none; + background: rgba(0, 0, 0, 0.8); + padding: 1.25em; +} + +#footer-text { + color: rgba(255, 255, 255, 0.8); + line-height: 1.44; +} + +#content { + margin-bottom: 0.625em; +} + +.sect1 { + padding-bottom: 0.625em; +} + +@media screen and (min-width: 768px) { + #content { + margin-bottom: 1.25em; + } + + .sect1 { + padding-bottom: 1.25em; + } +} + +.sect1:last-child { + padding-bottom: 0; +} + +.sect1 + .sect1 { + border-top: 1px solid #e7e7e9; +} + +#content h1 > a.anchor, +h2 > a.anchor, +h3 > a.anchor, +#toctitle > a.anchor, +.sidebarblock > .content > .title > a.anchor, +h4 > a.anchor, +h5 > a.anchor, +h6 > a.anchor { + position: absolute; + z-index: 1001; + width: 1.5ex; + margin-left: -1.5ex; + display: block; + text-decoration: none !important; + visibility: hidden; + text-align: center; + font-weight: 400; +} + +#content h1 > a.anchor::before, +h2 > a.anchor::before, +h3 > a.anchor::before, +#toctitle > a.anchor::before, +.sidebarblock > .content > .title > a.anchor::before, +h4 > a.anchor::before, +h5 > a.anchor::before, +h6 > a.anchor::before { + content: "\00A7"; + font-size: 0.85em; + display: block; + padding-top: 0.1em; +} + +#content h1:hover > a.anchor, +#content h1 > a.anchor:hover, +h2:hover > a.anchor, +h2 > a.anchor:hover, +h3:hover > a.anchor, +#toctitle:hover > a.anchor, +.sidebarblock > .content > .title:hover > a.anchor, +h3 > a.anchor:hover, +#toctitle > a.anchor:hover, +.sidebarblock > .content > .title > a.anchor:hover, +h4:hover > a.anchor, +h4 > a.anchor:hover, +h5:hover > a.anchor, +h5 > a.anchor:hover, +h6:hover > a.anchor, +h6 > a.anchor:hover { + visibility: visible; +} + +#content h1 > a.link, +h2 > a.link, +h3 > a.link, +#toctitle > a.link, +.sidebarblock > .content > .title > a.link, +h4 > a.link, +h5 > a.link, +h6 > a.link { + color: #ba3925; + text-decoration: none; +} + +#content h1 > a.link:hover, +h2 > a.link:hover, +h3 > a.link:hover, +#toctitle > a.link:hover, +.sidebarblock > .content > .title > a.link:hover, +h4 > a.link:hover, +h5 > a.link:hover, +h6 > a.link:hover { + color: #a53221; +} + +details, +.audioblock, +.imageblock, +.literalblock, +.listingblock, +.stemblock, +.videoblock { + margin-bottom: 1.25em; +} + +details { + margin-left: 1.25rem; +} + +details > summary { + cursor: pointer; + display: block; + position: relative; + line-height: 1.6; + margin-bottom: 0.625rem; + outline: none; + -webkit-tap-highlight-color: transparent; +} + +details > summary::-webkit-details-marker { + display: none; +} + +details > summary::before { + content: ""; + border: solid transparent; + border-left-color: currentColor; + border-width: 0.3em 0 0.3em 0.5em; + position: absolute; + top: 0.5em; + left: -1.25rem; + transform: translateX(15%); +} + +details[open] > summary::before { + border: solid transparent; + border-top-color: currentColor; + border-width: 0.5em 0.3em 0; + transform: translateY(15%); +} + +details > summary::after { + content: ""; + width: 1.25rem; + height: 1em; + position: absolute; + top: 0.3em; + left: -1.25rem; +} + +.admonitionblock td.content > .title, +.audioblock > .title, +.exampleblock > .title, +.imageblock > .title, +.listingblock > .title, +.literalblock > .title, +.stemblock > .title, +.openblock > .title, +.paragraph > .title, +.quoteblock > .title, +table.tableblock > .title, +.verseblock > .title, +.videoblock > .title, +.dlist > .title, +.olist > .title, +.ulist > .title, +.qlist > .title, +.hdlist > .title { + text-rendering: optimizeLegibility; + text-align: left; + font-family: "Noto Serif", "DejaVu Serif", serif; + font-size: 1rem; + font-style: italic; +} + +table.tableblock.fit-content > caption.title { + white-space: nowrap; + width: 0; +} + +.paragraph.lead > p, +#preamble > .sectionbody > [class=paragraph]:first-of-type p { + font-size: 1.21875em; + line-height: 1.6; + color: rgba(0, 0, 0, 0.85); +} + +.admonitionblock > table { + border-collapse: separate; + border: 0; + background: none; + width: 100%; +} + +.admonitionblock > table td.icon { + text-align: center; + width: 80px; +} + +.admonitionblock > table td.icon img { + max-width: none; +} + +.admonitionblock > table td.icon .title { + font-weight: bold; + font-family: "Open Sans", "DejaVu Sans", sans-serif; + text-transform: uppercase; +} + +.admonitionblock > table td.content { + padding-left: 1.125em; + padding-right: 1.25em; + border-left: 1px solid #dddddf; + color: rgba(0, 0, 0, 0.6); + word-wrap: anywhere; +} + +.admonitionblock > table td.content > :last-child > :last-child { + margin-bottom: 0; +} + +.exampleblock > .content { + border: 1px solid #e6e6e6; + margin-bottom: 1.25em; + padding: 1.25em; + background: #fff; + border-radius: 4px; +} + +.sidebarblock { + border: 1px solid #dbdbd6; + margin-bottom: 1.25em; + padding: 1.25em; + background: #f3f3f2; + border-radius: 4px; +} + +.sidebarblock > .content > .title { + color: #7a2518; + margin-top: 0; + text-align: center; +} + +.exampleblock > .content > :first-child, +.sidebarblock > .content > :first-child { + margin-top: 0; +} + +.exampleblock > .content > :last-child, +.exampleblock > .content > :last-child > :last-child, +.exampleblock > .content .olist > ol > li:last-child > :last-child, +.exampleblock > .content .ulist > ul > li:last-child > :last-child, +.exampleblock > .content .qlist > ol > li:last-child > :last-child, +.sidebarblock > .content > :last-child, +.sidebarblock > .content > :last-child > :last-child, +.sidebarblock > .content .olist > ol > li:last-child > :last-child, +.sidebarblock > .content .ulist > ul > li:last-child > :last-child, +.sidebarblock > .content .qlist > ol > li:last-child > :last-child { + margin-bottom: 0; +} + +.literalblock pre, +.listingblock > .content > pre { + border-radius: 4px; + overflow-x: auto; + padding: 1em; + font-size: 0.8125em; +} + +@media screen and (min-width: 768px) { + .literalblock pre, + .listingblock > .content > pre { + font-size: 0.90625em; + } +} + +@media screen and (min-width: 1280px) { + .literalblock pre, + .listingblock > .content > pre { + font-size: 1em; + } +} + +.literalblock pre, +.listingblock > .content > pre:not(.highlight), +.listingblock > .content > pre[class=highlight], +.listingblock > .content > pre[class^="highlight "] { + background: #f7f7f8; +} + +.literalblock.output pre { + color: #f7f7f8; + background: rgba(0, 0, 0, 0.9); +} + +.listingblock > .content { + position: relative; +} + +.listingblock code[data-lang]::before { + display: none; + content: attr(data-lang); + position: absolute; + font-size: 0.75em; + top: 0.425rem; + right: 0.5rem; + line-height: 1; + text-transform: uppercase; + color: inherit; + opacity: 0.5; +} + +.listingblock:hover code[data-lang]::before { + display: block; +} + +.listingblock.terminal pre .command::before { + content: attr(data-prompt); + padding-right: 0.5em; + color: inherit; + opacity: 0.5; +} + +.listingblock.terminal pre .command:not([data-prompt])::before { + content: "$"; +} + +.listingblock pre.highlightjs { + padding: 0; +} + +.listingblock pre.highlightjs > code { + padding: 1em; + border-radius: 4px; +} + +.listingblock pre.prettyprint { + border-width: 0; +} + +.prettyprint { + background: #f7f7f8; +} + +pre.prettyprint .linenums { + line-height: 1.45; + margin-left: 2em; +} + +pre.prettyprint li { + background: none; + list-style-type: inherit; + padding-left: 0; +} + +pre.prettyprint li code[data-lang]::before { + opacity: 1; +} + +pre.prettyprint li:not(:first-child) code[data-lang]::before { + display: none; +} + +table.linenotable { + border-collapse: separate; + border: 0; + margin-bottom: 0; + background: none; +} + +table.linenotable td[class] { + color: inherit; + vertical-align: top; + padding: 0; + line-height: inherit; + white-space: normal; +} + +table.linenotable td.code { + padding-left: 0.75em; +} + +table.linenotable td.linenos, +pre.pygments .linenos { + border-right: 1px solid; + opacity: 0.35; + padding-right: 0.5em; + user-select: none; +} + +pre.pygments span.linenos { + display: inline-block; + margin-right: 0.75em; +} + +.quoteblock { + margin: 0 1em 1.25em 1.5em; + display: table; +} + +.quoteblock:not(.excerpt) > .title { + margin-left: -1.5em; + margin-bottom: 0.75em; +} + +.quoteblock blockquote, +.quoteblock p { + color: rgba(0, 0, 0, 0.85); + font-size: 1.15rem; + line-height: 1.75; + word-spacing: 0.1em; + letter-spacing: 0; + font-style: italic; + text-align: justify; +} + +.quoteblock blockquote { + margin: 0; + padding: 0; + border: 0; +} + +.quoteblock blockquote::before { + content: "\201c"; + float: left; + font-size: 2.75em; + font-weight: bold; + line-height: 0.6em; + margin-left: -0.6em; + color: #7a2518; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.quoteblock blockquote > .paragraph:last-child p { + margin-bottom: 0; +} + +.quoteblock .attribution { + margin-top: 0.75em; + margin-right: 0.5ex; + text-align: right; +} + +.verseblock { + margin: 0 1em 1.25em; +} + +.verseblock pre { + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-size: 1.15rem; + color: rgba(0, 0, 0, 0.85); + font-weight: 300; + text-rendering: optimizeLegibility; +} + +.verseblock pre strong { + font-weight: 400; +} + +.verseblock .attribution { + margin-top: 1.25rem; + margin-left: 0.5ex; +} + +.quoteblock .attribution, +.verseblock .attribution { + font-size: 0.9375em; + line-height: 1.45; + font-style: italic; +} + +.quoteblock .attribution br, +.verseblock .attribution br { + display: none; +} + +.quoteblock .attribution cite, +.verseblock .attribution cite { + display: block; + letter-spacing: -0.025em; + color: rgba(0, 0, 0, 0.6); +} + +.quoteblock.abstract blockquote::before, +.quoteblock.excerpt blockquote::before, +.quoteblock .quoteblock blockquote::before { + display: none; +} + +.quoteblock.abstract blockquote, +.quoteblock.abstract p, +.quoteblock.excerpt blockquote, +.quoteblock.excerpt p, +.quoteblock .quoteblock blockquote, +.quoteblock .quoteblock p { + line-height: 1.6; + word-spacing: 0; +} + +.quoteblock.abstract { + margin: 0 1em 1.25em; + display: block; +} + +.quoteblock.abstract > .title { + margin: 0 0 0.375em; + font-size: 1.15em; + text-align: center; +} + +.quoteblock.excerpt > blockquote, +.quoteblock .quoteblock { + padding: 0 0 0.25em 1em; + border-left: 0.25em solid #dddddf; +} + +.quoteblock.excerpt, +.quoteblock .quoteblock { + margin-left: 0; +} + +.quoteblock.excerpt blockquote, +.quoteblock.excerpt p, +.quoteblock .quoteblock blockquote, +.quoteblock .quoteblock p { + color: inherit; + font-size: 1.0625rem; +} + +.quoteblock.excerpt .attribution, +.quoteblock .quoteblock .attribution { + color: inherit; + font-size: 0.85rem; + text-align: left; + margin-right: 0; +} + +p.tableblock:last-child { + margin-bottom: 0; +} + +td.tableblock > .content { + margin-bottom: 1.25em; + word-wrap: anywhere; +} + +td.tableblock > .content > :last-child { + margin-bottom: -1.25em; +} + +table.tableblock, +th.tableblock, +td.tableblock { + border: 0 solid #dedede; +} + +table.grid-all > * > tr > * { + border-width: 1px; +} + +table.grid-cols > * > tr > * { + border-width: 0 1px; +} + +table.grid-rows > * > tr > * { + border-width: 1px 0; +} + +table.frame-all { + border-width: 1px; +} + +table.frame-ends { + border-width: 1px 0; +} + +table.frame-sides { + border-width: 0 1px; +} + +table.frame-none > colgroup + * > :first-child > *, +table.frame-sides > colgroup + * > :first-child > * { + border-top-width: 0; +} + +table.frame-none > :last-child > :last-child > *, +table.frame-sides > :last-child > :last-child > * { + border-bottom-width: 0; +} + +table.frame-none > * > tr > :first-child, +table.frame-ends > * > tr > :first-child { + border-left-width: 0; +} + +table.frame-none > * > tr > :last-child, +table.frame-ends > * > tr > :last-child { + border-right-width: 0; +} + +table.stripes-all > * > tr, +table.stripes-odd > * > tr:nth-of-type(odd), +table.stripes-even > * > tr:nth-of-type(even), +table.stripes-hover > * > tr:hover { + background: #f8f8f7; +} + +th.halign-left, +td.halign-left { + text-align: left; +} + +th.halign-right, +td.halign-right { + text-align: right; +} + +th.halign-center, +td.halign-center { + text-align: center; +} + +th.valign-top, +td.valign-top { + vertical-align: top; +} + +th.valign-bottom, +td.valign-bottom { + vertical-align: bottom; +} + +th.valign-middle, +td.valign-middle { + vertical-align: middle; +} + +table thead th, +table tfoot th { + font-weight: bold; +} + +tbody tr th { + background: #f7f8f7; +} + +tbody tr th, +tbody tr th p, +tfoot tr th, +tfoot tr th p { + color: rgba(0, 0, 0, 0.8); + font-weight: bold; +} + +p.tableblock > code:only-child { + background: none; + padding: 0; +} + +p.tableblock { + font-size: 1em; +} + +ol { + margin-left: 1.75em; +} + +ul li ol { + margin-left: 1.5em; +} + +dl dd { + margin-left: 1.125em; +} + +dl dd:last-child, +dl dd:last-child > :last-child { + margin-bottom: 0; +} + +li p, +ul dd, +ol dd, +.olist .olist, +.ulist .ulist, +.ulist .olist, +.olist .ulist { + margin-bottom: 0.625em; +} + +ul.checklist, +ul.none, +ol.none, +ul.no-bullet, +ol.no-bullet, +ol.unnumbered, +ul.unstyled, +ol.unstyled { + list-style-type: none; +} + +ul.no-bullet, +ol.no-bullet, +ol.unnumbered { + margin-left: 0.625em; +} + +ul.unstyled, +ol.unstyled { + margin-left: 0; +} + +li > p:empty:only-child::before { + content: ""; + display: inline-block; +} + +ul.checklist > li > p:first-child { + margin-left: -1em; +} + +ul.checklist > li > p:first-child > .fa-square-o:first-child, +ul.checklist > li > p:first-child > .fa-check-square-o:first-child { + width: 1.25em; + font-size: 0.8em; + position: relative; + bottom: 0.125em; +} + +ul.checklist > li > p:first-child > input[type=checkbox]:first-child { + margin-right: 0.25em; +} + +ul.inline { + display: flex; + flex-flow: row wrap; + list-style: none; + margin: 0 0 0.625em -1.25em; +} + +ul.inline > li { + margin-left: 1.25em; +} + +.unstyled dl dt { + font-weight: 400; + font-style: normal; +} + +ol.arabic { + list-style-type: decimal; +} + +ol.decimal { + list-style-type: decimal-leading-zero; +} + +ol.loweralpha { + list-style-type: lower-alpha; +} + +ol.upperalpha { + list-style-type: upper-alpha; +} + +ol.lowerroman { + list-style-type: lower-roman; +} + +ol.upperroman { + list-style-type: upper-roman; +} + +ol.lowergreek { + list-style-type: lower-greek; +} + +.hdlist > table, +.colist > table { + border: 0; + background: none; +} + +.hdlist > table > tbody > tr, +.colist > table > tbody > tr { + background: none; +} + +td.hdlist1, +td.hdlist2 { + vertical-align: top; + padding: 0 0.625em; +} + +td.hdlist1 { + font-weight: bold; + padding-bottom: 1.25em; +} + +td.hdlist2 { + word-wrap: anywhere; +} + +.literalblock + .colist, +.listingblock + .colist { + margin-top: -0.5em; +} + +.colist td:not([class]):first-child { + padding: 0.4em 0.75em 0; + line-height: 1; + vertical-align: top; +} + +.colist td:not([class]):first-child img { + max-width: none; +} + +.colist td:not([class]):last-child { + padding: 0.25em 0; +} + +.thumb, +.th { + line-height: 0; + display: inline-block; + border: 4px solid #fff; + box-shadow: 0 0 0 1px #ddd; +} + +.imageblock.left { + margin: 0.25em 0.625em 1.25em 0; +} + +.imageblock.right { + margin: 0.25em 0 1.25em 0.625em; +} + +.imageblock > .title { + margin-bottom: 0; +} + +.imageblock.thumb, +.imageblock.th { + border-width: 6px; +} + +.imageblock.thumb > .title, +.imageblock.th > .title { + padding: 0 0.125em; +} + +.image.left, +.image.right { + margin-top: 0.25em; + margin-bottom: 0.25em; + display: inline-block; + line-height: 0; +} + +.image.left { + margin-right: 0.625em; +} + +.image.right { + margin-left: 0.625em; +} + +a.image { + text-decoration: none; + display: inline-block; +} + +a.image object { + pointer-events: none; +} + +sup.footnote, +sup.footnoteref { + font-size: 0.875em; + position: static; + vertical-align: super; +} + +sup.footnote a, +sup.footnoteref a { + text-decoration: none; +} + +sup.footnote a:active, +sup.footnoteref a:active { + text-decoration: underline; +} + +#footnotes { + padding-top: 0.75em; + padding-bottom: 0.75em; + margin-bottom: 0.625em; +} + +#footnotes hr { + width: 20%; + min-width: 6.25em; + margin: -0.25em 0 0.75em; + border-width: 1px 0 0; +} + +#footnotes .footnote { + padding: 0 0.375em 0 0.225em; + line-height: 1.3334; + font-size: 0.875em; + margin-left: 1.2em; + margin-bottom: 0.2em; +} + +#footnotes .footnote a:first-of-type { + font-weight: bold; + text-decoration: none; + margin-left: -1.05em; +} + +#footnotes .footnote:last-of-type { + margin-bottom: 0; +} + +#content #footnotes { + margin-top: -0.625em; + margin-bottom: 0; + padding: 0.75em 0; +} + +div.unbreakable { + page-break-inside: avoid; +} + +.big { + font-size: larger; +} + +.small { + font-size: smaller; +} + +.underline { + text-decoration: underline; +} + +.overline { + text-decoration: overline; +} + +.line-through { + text-decoration: line-through; +} + +.aqua { + color: #00bfbf; +} + +.aqua-background { + background: #00fafa; +} + +.black { + color: #000; +} + +.black-background { + background: #000; +} + +.blue { + color: #0000bf; +} + +.blue-background { + background: #0000fa; +} + +.fuchsia { + color: #bf00bf; +} + +.fuchsia-background { + background: #fa00fa; +} + +.gray { + color: #606060; +} + +.gray-background { + background: #7d7d7d; +} + +.green { + color: #006000; +} + +.green-background { + background: #007d00; +} + +.lime { + color: #00bf00; +} + +.lime-background { + background: #00fa00; +} + +.maroon { + color: #600000; +} + +.maroon-background { + background: #7d0000; +} + +.navy { + color: #000060; +} + +.navy-background { + background: #00007d; +} + +.olive { + color: #606000; +} + +.olive-background { + background: #7d7d00; +} + +.purple { + color: #600060; +} + +.purple-background { + background: #7d007d; +} + +.red { + color: #bf0000; +} + +.red-background { + background: #fa0000; +} + +.silver { + color: #909090; +} + +.silver-background { + background: #bcbcbc; +} + +.teal { + color: #006060; +} + +.teal-background { + background: #007d7d; +} + +.white { + color: #bfbfbf; +} + +.white-background { + background: #fafafa; +} + +.yellow { + color: #bfbf00; +} + +.yellow-background { + background: #fafa00; +} + +span.icon > .fa { + cursor: default; +} + +a span.icon > .fa { + cursor: inherit; +} + +.admonitionblock td.icon [class^="fa icon-"] { + font-size: 2.5em; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); + cursor: default; +} + +.admonitionblock td.icon .icon-note::before { + content: "\f05a"; + color: #19407c; +} + +.admonitionblock td.icon .icon-tip::before { + content: "\f0eb"; + text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); + color: #111; +} + +.admonitionblock td.icon .icon-warning::before { + content: "\f071"; + color: #bf6900; +} + +.admonitionblock td.icon .icon-caution::before { + content: "\f06d"; + color: #bf3400; +} + +.admonitionblock td.icon .icon-important::before { + content: "\f06a"; + color: #bf0000; +} + +.conum[data-value] { + display: inline-block; + color: #fff !important; + background: rgba(0, 0, 0, 0.8); + border-radius: 50%; + text-align: center; + font-size: 0.75em; + width: 1.67em; + height: 1.67em; + line-height: 1.67em; + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-style: normal; + font-weight: bold; +} + +.conum[data-value] * { + color: #fff !important; +} + +.conum[data-value] + b { + display: none; +} + +.conum[data-value]::after { + content: attr(data-value); +} + +pre .conum[data-value] { + position: relative; + top: -0.125em; +} + +b.conum * { + color: inherit !important; +} + +.conum:not([data-value]):empty { + display: none; +} + +dt, +th.tableblock, +td.content, +div.footnote { + text-rendering: optimizeLegibility; +} + +h1, +h2, +p, +td.content, +span.alt, +summary { + letter-spacing: -0.01em; +} + +p strong, +td.content strong, +div.footnote strong { + letter-spacing: -0.005em; +} + +p, +blockquote, +dt, +td.content, +td.hdlist1, +span.alt, +summary { + font-size: 1.0625rem; +} + +p { + margin-bottom: 1.25rem; +} + +.sidebarblock p, +.sidebarblock dt, +.sidebarblock td.content, +p.tableblock { + font-size: 1em; +} + +.exampleblock > .content { + background: #fffef7; + border-color: #e0e0dc; + box-shadow: 0 1px 4px #e0e0dc; +} + +.print-only { + display: none !important; +} + +@page { + margin: 1.25cm 0.75cm; +} + +@media print { + * { + box-shadow: none !important; + text-shadow: none !important; + } + + html { + font-size: 80%; + } + + a { + color: inherit !important; + text-decoration: underline !important; + } + + a.bare, + a[href^="#"], + a[href^="mailto:"] { + text-decoration: none !important; + } + + a[href^="http:"]:not(.bare)::after, + a[href^="https:"]:not(.bare)::after { + content: "(" attr(href) ")"; + display: inline-block; + font-size: 0.875em; + padding-left: 0.25em; + } + + abbr[title] { + border-bottom: 1px dotted; + } + + abbr[title]::after { + content: " (" attr(title) ")"; + } + + pre, + blockquote, + tr, + img, + object, + svg { + page-break-inside: avoid; + } + + thead { + display: table-header-group; + } + + svg { + max-width: 100%; + } + + p, + blockquote, + dt, + td.content { + font-size: 1em; + orphans: 3; + widows: 3; + } + + h2, + h3, + #toctitle, + .sidebarblock > .content > .title { + page-break-after: avoid; + } + + #header, + #content, + #footnotes, + #footer { + max-width: none; + } + + #toc, + .sidebarblock, + .exampleblock > .content { + background: none !important; + } + + #toc { + border-bottom: 1px solid #dddddf !important; + padding-bottom: 0 !important; + } + + body.book #header { + text-align: center; + } + + body.book #header > h1:first-child { + border: 0 !important; + margin: 2.5em 0 1em; + } + + body.book #header .details { + border: 0 !important; + display: block; + padding: 0 !important; + } + + body.book #header .details span:first-child { + margin-left: 0 !important; + } + + body.book #header .details br { + display: block; + } + + body.book #header .details br + span::before { + content: none !important; + } + + body.book #toc { + border: 0 !important; + text-align: left !important; + padding: 0 !important; + margin: 0 !important; + } + + body.book #toc, + body.book #preamble, + body.book h1.sect0, + body.book .sect1 > h2 { + page-break-before: always; + } + + .listingblock code[data-lang]::before { + display: block; + } + + #footer { + padding: 0 0.9375em; + } + + .hide-on-print { + display: none !important; + } + + .print-only { + display: block !important; + } + + .hide-for-print { + display: none !important; + } + + .show-for-print { + display: inherit !important; + } +} + +@media amzn-kf8, print { + #header > h1:first-child { + margin-top: 1.25rem; + } + + .sect1 { + padding: 0 !important; + } + + .sect1 + .sect1 { + border: 0; + } + + #footer { + background: none; + } + + #footer-text { + color: rgba(0, 0, 0, 0.6); + font-size: 0.9em; + } +} + +@media amzn-kf8 { + #header, + #content, + #footnotes, + #footer { + padding: 0; + } +} diff --git a/static/css/dokk.css b/static/css/dokk.css new file mode 100644 index 0000000..587f6d2 --- /dev/null +++ b/static/css/dokk.css @@ -0,0 +1,90 @@ +html, body { + font-size: 1rem; + height: 100%; + margin: 0; + padding: 0; + width: 100%; +} + +body > .index { + padding: 1rem; +} + +body > .library { + +} + +body > .library_item { + +} + + body > .library_item > .header { + background: black; + color: white; + padding: .75rem 1rem; + } + + body > .library_item > .header > a, + body > .library_item > .header > a:hover, + body > .library_item > .header > a:visited { + color: inherit; + font-size: 1rem; + text-decoration: none; + } + + body > .library_item object { + box-shadow: 0 0 2rem 0 #AAA; + height: 80vh; + width: 100%; + } + + body > .library_item > .details { + padding: 3rem 5rem; + } + +body > .mimi_and_eunice_strip { + padding: 1rem; +} + + body > .mimi_and_eunice_strip > img { + width: 100% + } + +/* manpages */ +.manpages { + padding: 1rem; +} + + .manpages > .path { + margin-bottom: 2rem; + } + + .manpages > .manpage { + font-family: monospace; + max-width: 80ch; + } + + .manpages > .manpage > table.head { + width: 100%; + } + + .manpages > .manpage td.head-ltitle { + text-align: left; + } + + .manpages > .manpage td.head-vol { + text-align: center; + } + + .manpages > .manpage td.head-rtitle { + text-align: right; + } + +body > .articles { + font-family: sans-serif; + padding: 1rem; +} + + body > .articles > .path { + margin-bottom: 1rem; + } diff --git a/static/css/mandoc.css b/static/css/mandoc.css new file mode 100644 index 0000000..1dae127 --- /dev/null +++ b/static/css/mandoc.css @@ -0,0 +1,368 @@ +/* $Id: mandoc.css,v 1.52 2022/07/06 14:34:59 schwarze Exp $ */ +/* + * Standard style sheet for mandoc(1) -Thtml and man.cgi(8). + * + * Written by Ingo Schwarze . + * I place this file into the public domain. + * Permission to use, copy, modify, and distribute it for any purpose + * with or without fee is hereby granted, without any conditions. + */ + +/* Global defaults. */ + +html { max-width: 65em; + --bg: #FFFFFF; + --fg: #000000; } +body { background: var(--bg); + color: var(--fg); + font-family: Helvetica,Arial,sans-serif; } +h1, h2 { font-size: 110%; } +table { margin-top: 0em; + margin-bottom: 0em; + border-collapse: collapse; } +/* Some browsers set border-color in a browser style for tbody, + * but not for table, resulting in inconsistent border styling. */ +tbody { border-color: inherit; } +tr { border-color: inherit; } +td { vertical-align: top; + padding-left: 0.2em; + padding-right: 0.2em; + border-color: inherit; } +ul, ol, dl { margin-top: 0em; + margin-bottom: 0em; } +li, dt { margin-top: 1em; } +pre { font-family: inherit; } + +.permalink { border-bottom: thin dotted; + color: inherit; + font: inherit; + text-decoration: inherit; } +* { clear: both } + +/* Search form and search results. */ + +fieldset { border: thin solid silver; + border-radius: 1em; + text-align: center; } +input[name=expr] { + width: 25%; } + +table.results { margin-top: 1em; + margin-left: 2em; + font-size: smaller; } + +/* Header and footer lines. */ + +div[role=doc-pageheader] { + display: flex; + border-bottom: 1px dotted #808080; + margin-bottom: 1em; + font-size: smaller; } +.head-ltitle { flex: 1; } +.head-vol { flex: 0 1 auto; + text-align: center; } +.head-rtitle { flex: 1; + text-align: right; } + +div[role=doc-pagefooter] { + display: flex; + justify-content: space-between; + border-top: 1px dotted #808080; + margin-top: 1em; + font-size: smaller; } +.foot-left { flex: 1; } +.foot-date { flex: 0 1 auto; + text-align: center; } +.foot-os { flex: 1; + text-align: right; } + +/* Sections and paragraphs. */ + +main { margin-left: 3.8em; } +.Nd { } +section.Sh { } +h2.Sh { margin-top: 1.2em; + margin-bottom: 0.6em; + margin-left: -3.2em; } +section.Ss { } +h3.Ss { margin-top: 1.2em; + margin-bottom: 0.6em; + margin-left: -1.2em; + font-size: 105%; } +.Pp { margin: 0.6em 0em; } +.Sx { } +.Xr { } + +/* Displays and lists. */ + +.Bd { } +.Bd-indent { margin-left: 3.8em; } + +.Bl-bullet { list-style-type: disc; + padding-left: 1em; } +.Bl-bullet > li { } +.Bl-dash { list-style-type: none; + padding-left: 0em; } +.Bl-dash > li:before { + content: "\2014 "; } +.Bl-item { list-style-type: none; + padding-left: 0em; } +.Bl-item > li { } +.Bl-compact > li { + margin-top: 0em; } + +.Bl-enum { padding-left: 2em; } +.Bl-enum > li { } +.Bl-compact > li { + margin-top: 0em; } + +.Bl-diag { } +.Bl-diag > dt { + font-style: normal; + font-weight: bold; } +.Bl-diag > dd { + margin-left: 0em; } +.Bl-hang { } +.Bl-hang > dt { } +.Bl-hang > dd { + margin-left: 5.5em; } +.Bl-inset { } +.Bl-inset > dt { } +.Bl-inset > dd { + margin-left: 0em; } +.Bl-ohang { } +.Bl-ohang > dt { } +.Bl-ohang > dd { + margin-left: 0em; } +.Bl-tag { margin-top: 0.6em; + margin-left: 5.5em; } +.Bl-tag > dt { + float: left; + margin-top: 0em; + margin-left: -5.5em; + padding-right: 0.5em; + vertical-align: top; } +.Bl-tag > dd { + clear: right; + column-count: 1; /* Force block formatting context. */ + width: 100%; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0.6em; + vertical-align: top; } +.Bl-compact { margin-top: 0em; } +.Bl-compact > dd { + margin-bottom: 0em; } +.Bl-compact > dt { + margin-top: 0em; } + +.Bl-column { } +.Bl-column > tbody > tr { } +.Bl-column > tbody > tr > td { + margin-top: 1em; } +.Bl-compact > tbody > tr > td { + margin-top: 0em; } + +.Rs { font-style: normal; + font-weight: normal; } +.RsA { } +.RsB { font-style: italic; + font-weight: normal; } +.RsC { } +.RsD { } +.RsI { font-style: italic; + font-weight: normal; } +.RsJ { font-style: italic; + font-weight: normal; } +.RsN { } +.RsO { } +.RsP { } +.RsQ { } +.RsR { } +.RsT { text-decoration: underline; } +.RsU { } +.RsV { } + +.eqn { } +.tbl td { vertical-align: middle; } + +.HP { margin-left: 3.8em; + text-indent: -3.8em; } + +/* Semantic markup for command line utilities. */ + +table.Nm { } +code.Nm { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Fl { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Cm { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ar { font-style: italic; + font-weight: normal; } +.Op { display: inline flow; } +.Ic { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ev { font-style: normal; + font-weight: normal; + font-family: monospace; } +.Pa { font-style: italic; + font-weight: normal; } + +/* Semantic markup for function libraries. */ + +.Lb { } +code.In { font-style: normal; + font-weight: bold; + font-family: inherit; } +a.In { } +.Fd { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ft { font-style: italic; + font-weight: normal; } +.Fn { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Fa { font-style: italic; + font-weight: normal; } +.Vt { font-style: italic; + font-weight: normal; } +.Va { font-style: italic; + font-weight: normal; } +.Dv { font-style: normal; + font-weight: normal; + font-family: monospace; } +.Er { font-style: normal; + font-weight: normal; + font-family: monospace; } + +/* Various semantic markup. */ + +.An { } +.Lk { } +.Mt { } +.Cd { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ad { font-style: italic; + font-weight: normal; } +.Ms { font-style: normal; + font-weight: bold; } +.St { } +.Ux { } + +/* Physical markup. */ + +.Bf { display: inline flow; } +.No { font-style: normal; + font-weight: normal; } +.Em { font-style: italic; + font-weight: normal; } +.Sy { font-style: normal; + font-weight: bold; } +.Li { font-style: normal; + font-weight: normal; + font-family: monospace; } + +/* Tooltip support. */ + +h2.Sh, h3.Ss { position: relative; } +.An, .Ar, .Cd, .Cm, .Dv, .Em, .Er, .Ev, .Fa, .Fd, .Fl, .Fn, .Ft, +.Ic, code.In, .Lb, .Lk, .Ms, .Mt, .Nd, code.Nm, .Pa, .Rs, +.St, .Sx, .Sy, .Va, .Vt, .Xr { + display: inline flow; + position: relative; } + +.An::before { content: "An"; } +.Ar::before { content: "Ar"; } +.Cd::before { content: "Cd"; } +.Cm::before { content: "Cm"; } +.Dv::before { content: "Dv"; } +.Em::before { content: "Em"; } +.Er::before { content: "Er"; } +.Ev::before { content: "Ev"; } +.Fa::before { content: "Fa"; } +.Fd::before { content: "Fd"; } +.Fl::before { content: "Fl"; } +.Fn::before { content: "Fn"; } +.Ft::before { content: "Ft"; } +.Ic::before { content: "Ic"; } +code.In::before { content: "In"; } +.Lb::before { content: "Lb"; } +.Lk::before { content: "Lk"; } +.Ms::before { content: "Ms"; } +.Mt::before { content: "Mt"; } +.Nd::before { content: "Nd"; } +code.Nm::before { content: "Nm"; } +.Pa::before { content: "Pa"; } +.Rs::before { content: "Rs"; } +h2.Sh::before { content: "Sh"; } +h3.Ss::before { content: "Ss"; } +.St::before { content: "St"; } +.Sx::before { content: "Sx"; } +.Sy::before { content: "Sy"; } +.Va::before { content: "Va"; } +.Vt::before { content: "Vt"; } +.Xr::before { content: "Xr"; } + +.An::before, .Ar::before, .Cd::before, .Cm::before, +.Dv::before, .Em::before, .Er::before, .Ev::before, +.Fa::before, .Fd::before, .Fl::before, .Fn::before, .Ft::before, +.Ic::before, code.In::before, .Lb::before, .Lk::before, +.Ms::before, .Mt::before, .Nd::before, code.Nm::before, +.Pa::before, .Rs::before, +h2.Sh::before, h3.Ss::before, .St::before, .Sx::before, .Sy::before, +.Va::before, .Vt::before, .Xr::before { + opacity: 0; + transition: .15s ease opacity; + pointer-events: none; + position: absolute; + bottom: 100%; + box-shadow: 0 0 .35em var(--fg); + padding: .15em .25em; + white-space: nowrap; + font-family: Helvetica,Arial,sans-serif; + font-style: normal; + font-weight: bold; + background: var(--bg); + color: var(--fg); } +.An:hover::before, .Ar:hover::before, .Cd:hover::before, .Cm:hover::before, +.Dv:hover::before, .Em:hover::before, .Er:hover::before, .Ev:hover::before, +.Fa:hover::before, .Fd:hover::before, .Fl:hover::before, .Fn:hover::before, +.Ft:hover::before, .Ic:hover::before, code.In:hover::before, +.Lb:hover::before, .Lk:hover::before, .Ms:hover::before, .Mt:hover::before, +.Nd:hover::before, code.Nm:hover::before, .Pa:hover::before, +.Rs:hover::before, h2.Sh:hover::before, h3.Ss:hover::before, .St:hover::before, +.Sx:hover::before, .Sy:hover::before, .Va:hover::before, .Vt:hover::before, +.Xr:hover::before { + opacity: 1; + pointer-events: inherit; } + +/* Overrides to avoid excessive margins on small devices. */ + +@media (max-width: 37.5em) { +main { margin-left: 0.5em; } +h2.Sh, h3.Ss { margin-left: 0em; } +.Bd-indent { margin-left: 2em; } +.Bl-hang > dd { + margin-left: 2em; } +.Bl-tag { margin-left: 2em; } +.Bl-tag > dt { + margin-left: -2em; } +.HP { margin-left: 2em; + text-indent: -2em; } +} + +/* Overrides for a dark color scheme for accessibility. */ + +@media (prefers-color-scheme: dark) { +html { --bg: #1E1F21; + --fg: #EEEFF1; } +:link { color: #BAD7FF; } +:visited { color: #F6BAFF; } +} diff --git a/templates/article.html b/templates/article.html new file mode 100644 index 0000000..220af04 --- /dev/null +++ b/templates/article.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} + +{% block title %}{{ data["a:title"] }}{% endblock %} +{% block stylesheets %} + +{% endblock %} + +{% block body %} + +
+ +
+ DOKK / + articles / + {{ data["a:title"] }} +
+ +

{{ data["a:title"] }}

+ + {{ data["a:html"]|safe }} + +
+ +{% endblock %} diff --git a/templates/articles.html b/templates/articles.html new file mode 100644 index 0000000..7d2e94d --- /dev/null +++ b/templates/articles.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} + +{% block title %}Articles{% endblock %} + +{% block body %} + +
+ +
+ DOKK / + articles +
+ + {% for article in data["results"]["bindings"] %} +

+ {{ article['title']['value'] }} +

+ {% endfor %} +
+ +{% endblock %} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..84dc0eb --- /dev/null +++ b/templates/base.html @@ -0,0 +1,12 @@ + + + + + + {% block title %}{% endblock %} · DOKK + + + {% block stylesheets %}{% endblock %} + + {% block body %}{% endblock %} + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..fad87a0 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,33 @@ +{% extends "base.html" %} + +{% block title %}{% endblock %} + +{% block body %} + +
+

DOKK

+ +

- Articles

+

- Library

+

- Licenses

+

- Man pages

+

- Mimi & Eunice comic strips

+ +



+ +

The DOKK is a free/libre database.

+

If the data is useful to you, please download it, use it in your projects, share it, improve it!

+ +

+ data repository + · + website repository + · + freepost + · + + #peers (irc.libera.chat) +

+
+ +{% endblock %} diff --git a/templates/library.html b/templates/library.html new file mode 100644 index 0000000..5041e9e --- /dev/null +++ b/templates/library.html @@ -0,0 +1,32 @@ +{% extends "base.html" %} + +{% block title %}Library{% endblock %} + +{% block body %} + +
+{% for item in data["@graph"]|sort(attribute="library:title") %} +

+

+ +
+ Authors: + {% for author in item["library:author"]|sort() %} + {{ author }} + {% endfor%} +
+ +
+ License: + {% for license in item["library:license"]|sort(attribute="license:id") %} + {{ license['license:id'] }} + {% endfor%} +
+

+

+{% endfor %} +
+ +{% endblock %} diff --git a/templates/library_item.html b/templates/library_item.html new file mode 100644 index 0000000..6e83ed6 --- /dev/null +++ b/templates/library_item.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} + +{% block title %}{{ data['library:title'] }}{% endblock %} + +{% block body %} + +
+ + +
+ +
{{ plaintext }}
+
+
+ +
+

{{ data["library:title"] }}

+ +

+ Authors + {% for author in data["library:author"]|sort() %} + {{ author }} + {% endfor%} +

+ +

+ License + {% for license in data["library:license"]|sort(attribute="license:id") %} + {{ license['license:id'] }} + {% endfor%} +

+
+
+ +{% endblock %} diff --git a/templates/license.html b/templates/license.html new file mode 100644 index 0000000..915978d --- /dev/null +++ b/templates/license.html @@ -0,0 +1,22 @@ +{% extends "base.html" %} + +{% block title %}{{ data['license:name'] }}{% endblock %} + +{% block body %} + +
+

+ {{ data['license:name'] }} +

+

+ {{ data['license:id'] }} +

+

+ {{ data['license:header'] }} +

+

+

{{ data['license:text'] }}
+

+
+ +{% endblock %} diff --git a/templates/licenses.html b/templates/licenses.html new file mode 100644 index 0000000..d0f8ec3 --- /dev/null +++ b/templates/licenses.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} + +{% block title %}Licenses{% endblock %} + +{% block body %} + +
+{% for license in data["results"]["bindings"] %} +

+

+

+{% endfor %} +
+ +{% endblock %} diff --git a/templates/manpage.html b/templates/manpage.html new file mode 100644 index 0000000..3545d06 --- /dev/null +++ b/templates/manpage.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} + +{% block title %}{{ data['mp:name'] }}({{ data['mp:section'] }}){% endblock %} +{% block stylesheets %} + +{% endblock %} + +{% block body %} + +
+ +
+ DOKK / + manpages / + {{ distribution }} {{ version }} / + {{ package }} / + {{ data["mp:source"]["mp:filename"] }} +
+ +
{{ data["mp:html"]|safe }}
+ +
+ +{% endblock %} diff --git a/templates/manpage_disambiguation.html b/templates/manpage_disambiguation.html new file mode 100644 index 0000000..5dfde0b --- /dev/null +++ b/templates/manpage_disambiguation.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} + +{% block title %}Man pages named {{ name }} in section {{ section }}{% endblock %} + +{% block body %} + +
+ +
+ DOKK / + manpages +
+ +

+ Man pages matching name {{ name }} in section {{ section }}: +

+ +

+ + {% for page in data["@graph"] %} + + + + + {% endfor %} +
+ + {{ page['mp:source']['mp:filename'] }} + + + {{ page['mp:source']['mp:distribution_name'] }} + {{ page['mp:source']['mp:distribution_version'] }} + / + {{ page['mp:source']['mp:package'] }} +
+

+ +
+ +{% endblock %} diff --git a/templates/manpages.html b/templates/manpages.html new file mode 100644 index 0000000..f5c5fe6 --- /dev/null +++ b/templates/manpages.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} + +{% block title %}man pages{% endblock %} + +{% block body %} + +
+ +
+ DOKK / + manpages +
+ +

+ Distributions: +

+ + {% for result in data["results"]["bindings"] %} + + {% endfor %} + +
+ +{% endblock %} diff --git a/templates/manpages_distribution.html b/templates/manpages_distribution.html new file mode 100644 index 0000000..61bd30e --- /dev/null +++ b/templates/manpages_distribution.html @@ -0,0 +1,27 @@ +{% extends "base.html" %} + +{% block title %}{{ distribution }} {{ version }} man pages{% endblock %} + +{% block body %} + +
+ +
+ DOKK / + manpages / + {{ distribution }} {{ version }} +
+ +

+ Packages: +

+ + {% for page in data['results']['bindings'] %} + + {% endfor %} + +
+ +{% endblock %} diff --git a/templates/manpages_package.html b/templates/manpages_package.html new file mode 100644 index 0000000..1dc761d --- /dev/null +++ b/templates/manpages_package.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} + +{% block title %}{{ package }} ({{ distribution }} {{ version }}) man pages{% endblock %} + +{% block body %} + +
+ +
+ DOKK / + manpages / + {{ distribution }} {{ version }} / + {{ package }} +
+ +

+ Pages: +

+ + {% for page in data['results']['bindings'] %} + + {% endfor %} + +
+ +{% endblock %} diff --git a/templates/mimi_and_eunice.html b/templates/mimi_and_eunice.html new file mode 100644 index 0000000..04144e8 --- /dev/null +++ b/templates/mimi_and_eunice.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block title %}Mimi & Eunice{% endblock %} + +{% block body %} + +
+{% for comic_strip in data["results"]["bindings"] %} +

+ {{ comic_strip['number']['value'] }} - + {{ comic_strip['title']['value'] }} +

+{% endfor %} +
+ +{% endblock %} diff --git a/templates/mimi_and_eunice_strip.html b/templates/mimi_and_eunice_strip.html new file mode 100644 index 0000000..7aeccd0 --- /dev/null +++ b/templates/mimi_and_eunice_strip.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} + +{% block title %}Mimi&Eunice {{ data['@id'][12:] }}: {{ data['mimi_eunice:title'] }}{% endblock %} + +{% block body %} + +
+

{{ data['mimi_eunice:title'] }}

+ +

+ Published: {{ data['mimi_eunice:published'] }} +

+

+ Liense: + {{ data['mimi_eunice:license']['license:id'] }} +

+

+ Tags: + {% for tag in data['mimi_eunice:tag']|sort %} + {{ tag }} + {% endfor %} +

+ + + +

+ Transcript + + {% for line in data['mimi_eunice:transcript']|sort(attribute='mimi_eunice:order.@value') %} +

+ {{ line['mimi_eunice:character'] }}: {{ line['mimi_eunice:text'] }} +
+ {% endfor %} +

+
+ +{% endblock %}