diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index 9de1aa6259..6fc8b8095a 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -20,7 +20,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: '3.11' cache: pipenv - name: Install pipenv run: pip install pipenv diff --git a/Makefile.am b/Makefile.am index e3b3e5a244..00133f6d87 100644 --- a/Makefile.am +++ b/Makefile.am @@ -197,14 +197,10 @@ endif ### Packaging -docs/site.yml: configure.ac - sed 's/^jq_version: .*/jq_version: "$(VERSION)"/' $@ > $@.new - mv $@.new $@ - install-binaries: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec -DOC_FILES = docs/content docs/public docs/templates docs/site.yml \ +DOC_FILES = docs/content docs/public docs/templates \ docs/Pipfile docs/Pipfile.lock docs/build_manpage.py \ docs/build_mantests.py docs/build_website.py docs/README.md \ docs/validate_manual_schema.py docs/manual_schema.yml diff --git a/docs/README.md b/docs/README.md index 52fdd59b82..3ea88160cc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,16 +11,16 @@ need `python3` and `pipenv`. You can install `pipenv` like so: Though, you may need to say `pip3` instead, depending on your system. Once you have `pipenv` installed, you can install the dependencies by running -`pipenv sync` from the `docs` directory. +`pipenv sync` from the `docs/` directory. Also, you may need to run `virtualenv -p /usr/bin/python3 venv/` and then `source venv/bin/activate`, and only then `pipenv sync`. Once this is done, rerun `./configure` in the jq root directory and then -the Makefile will be able to generate the jq manpage. You can also just -run `pipenv run build_manpage.py` in the `docs` directory to build the -`jq.1` page manually, and `pipenv run build_mantests.py` to build the -contents of `tests/man.test` and `tests/manonig.test`. +the `Makefile` will be able to generate the jq manpage. You can just run +`make jq.1` to build the manpage manually, and `make tests/man.test` to +update the manual tests. -To build the website, run `pipenv run ./build_website.py` from inside -the `docs` directory. +To build the website, run `pipenv run python3 build_website.py --root /output` +in the `docs/` directory. To serve them locally, you can run +`python3 -m http.server`. diff --git a/docs/build_website.py b/docs/build_website.py index 5867f8c0a6..2b3afc77e2 100755 --- a/docs/build_website.py +++ b/docs/build_website.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import argparse import glob import itertools from jinja2 import Environment, FileSystemLoader, select_autoescape, pass_context @@ -10,6 +11,10 @@ import shutil import yaml +parser = argparse.ArgumentParser() +parser.add_argument('--root', default='/jq') +args = parser.parse_args() + env = Environment( loader=FileSystemLoader('templates'), autoescape=select_autoescape(['html.j2']), @@ -21,40 +26,51 @@ def load_yml_file(fn): return yaml.safe_load(f) +env.globals['url'] = 'https://jqlang.github.io/jq' +env.globals['root'] = args.root + env.filters['search_id'] = lambda input: input.replace(r'`', '') -env.filters['section_id'] = lambda input: re.sub(r"[^a-zA-Z0-9_]", '', input) -env.filters['entry_id'] = lambda input: re.sub(r"[ `]", '', input) +env.filters['section_id'] = lambda input: re.sub( + r'[^-a-zA-Z0-9_]', '', input.replace(' ', '-')).lower() +env.filters['entry_id'] = lambda input: re.sub( + r'^(split|first-last-nth)$', + r'\1' + ('-1' if ';' not in input else '-2'), # avoid id conflict + re.sub( + r'\b([^-]+)(?:-\1)+\b', + r'\1', # e.g. range-range-range -> range + re.sub(r' ?/ ?|,? ', '-', + re.sub(r'[`;]|: .*|\(.*?\)| \[.+\]', '', input)))).lower() env.filters['markdownify'] = lambda input: Markup(markdown(input)) -env.filters['no_paragraph'] = lambda input: Markup(re.sub(r"", '', input)) +env.filters['no_paragraph'] = lambda input: Markup(re.sub(r'', '', input)) env.globals['unique_id'] = pass_context( lambda ctx: str(next(ctx['unique_ctr']))) -env.globals.update(load_yml_file('site.yml')) -env.globals['navigation'] = ['tutorial', 'download', 'manual'] +def raise_handler(message): + raise Exception(message) + + +env.globals['raise'] = raise_handler -def generate_file(env, fname='content/1.tutorial/default.yml'): +def generate_file(env, fname): path, base = os.path.split(fname) path = os.path.relpath(path, 'content') if path == '.': path = '' - slug = 'index' permalink = '' else: - slug = os.path.basename(path) permalink = path + '/' output_dir = os.path.join('output', path) output_path = os.path.join(output_dir, 'index.html') - template_name = re.sub(r".yml$", '.html.j2', base) + template_name = re.sub(r'.yml$', '.html.j2', base) ctx = load_yml_file(fname) ctx.update(unique_ctr=itertools.count(1), permalink=permalink, - slug=slug, navitem=path) os.makedirs(output_dir, exist_ok=True) env.get_template(template_name).stream(ctx).dump(output_path, @@ -72,6 +88,7 @@ def copy_public_files(root=''): shutil.copyfile(f.path, dst) +os.makedirs('output', exist_ok=True) copy_public_files() for fn in glob.glob('content/**/*.yml', recursive=True): diff --git a/docs/content/download/default.yml b/docs/content/download/default.yml index 4f39c6128c..970f1c85a7 100644 --- a/docs/content/download/default.yml +++ b/docs/content/download/default.yml @@ -196,9 +196,9 @@ body: #### Building the documentation jq's documentation is compiled into static HTML using Python. - To build the docs, run `pipenv run python3 build_website.py` from - the docs/ subdirectory. To serve them locally, you can run - `python3 -m SimpleHTTPServer`. You'll need a few Python dependencies, + To build the docs, run `pipenv run python3 build_website.py --root /output` + in the `docs/` directory. To serve them locally, you can run + `python3 -m http.server`. You'll need a few Python dependencies, which can be installed by following the instructions in `docs/README.md`. The man page is built by `make jq.1`, or just `make`, also from diff --git a/docs/content/index.yml b/docs/content/index.yml index 02ecafe5e7..82dcde9845 100644 --- a/docs/content/index.yml +++ b/docs/content/index.yml @@ -24,7 +24,7 @@ body3: | tail: | - Go read the [tutorial](/jq/tutorial/) for more, or the [manual](/jq/manual/) + Go read the [tutorial](./tutorial/) for more, or the [manual](./manual/) for *way* more. Have a question related to jq? You can seek answers on [Stack Overflow](https://stackoverflow.com/) @@ -34,7 +34,7 @@ tail: | news: - date: 1 November 2018 body: | - jq 1.6 released. See installation options on the [download](/jq/download/) + jq 1.6 released. See installation options on the [download](./download/) page, and the [release notes](https://github.com/jqlang/jq/releases/tag/jq-1.6) for details. @@ -44,7 +44,7 @@ news: jq 1.5 released, including new datetime, math, and regexp functions, try/catch syntax, array and object destructuring, a streaming parser, and a module system. See installation options on the - [download](/jq/download/) page, and the + [download](./download/) page, and the [release notes](https://github.com/jqlang/jq/releases/tag/jq-1.5) for details. @@ -63,7 +63,7 @@ news: - date: 09 June 2014 body: | - jq 1.4 (finally) released! Get it on the [download](/jq/download/) page. + jq 1.4 (finally) released! Get it on the [download](./download/) page. - date: 19 May 2013 body: | diff --git a/docs/content/manual/manual.yml b/docs/content/manual/manual.yml index 89252ac243..e4c8c64bca 100644 --- a/docs/content/manual/manual.yml +++ b/docs/content/manual/manual.yml @@ -3,9 +3,8 @@ headline: jq Manual (development version) history: | - *For released versions, see [jq 1.6](/jq/manual/v1.6), - [jq 1.5](/jq/manual/v1.5), [jq 1.4](/jq/manual/v1.4) - or [jq 1.3](/jq/manual/v1.3).* + *For released versions, see [jq 1.6](./v1.6/), [jq 1.5](./v1.5/), + [jq 1.4](./v1.4/) or [jq 1.3](./v1.3/).* body: | diff --git a/docs/content/manual/v1.3/manual.yml b/docs/content/manual/v1.3/manual.yml index c018e3142c..8cab6204bf 100644 --- a/docs/content/manual/v1.3/manual.yml +++ b/docs/content/manual/v1.3/manual.yml @@ -4,7 +4,7 @@ headline: jq 1.3 Manual history: | *The manual for the development version of jq can be found - [here](/jq/manual).* + [here](../).* body: | diff --git a/docs/content/manual/v1.4/manual.yml b/docs/content/manual/v1.4/manual.yml index 6cc1c5913b..cbfb82631e 100644 --- a/docs/content/manual/v1.4/manual.yml +++ b/docs/content/manual/v1.4/manual.yml @@ -4,7 +4,7 @@ headline: jq 1.4 Manual history: | *The manual for the development version of jq can be found - [here](/jq/manual).* + [here](../).* body: | diff --git a/docs/content/manual/v1.5/manual.yml b/docs/content/manual/v1.5/manual.yml index be2f1c562a..14f70532f4 100644 --- a/docs/content/manual/v1.5/manual.yml +++ b/docs/content/manual/v1.5/manual.yml @@ -4,7 +4,7 @@ headline: jq 1.5 Manual history: | *The manual for the development version of jq can be found - [here](/jq/manual).* + [here](../).* body: | diff --git a/docs/content/manual/v1.6/manual.yml b/docs/content/manual/v1.6/manual.yml index be62cab6cd..0a3d6002a2 100644 --- a/docs/content/manual/v1.6/manual.yml +++ b/docs/content/manual/v1.6/manual.yml @@ -4,7 +4,7 @@ headline: jq 1.6 Manual history: | *The manual for the development version of jq can be found - [here](/jq/manual).* + [here](../).* body: | diff --git a/docs/public/css/base.css b/docs/public/css/base.css deleted file mode 100644 index e9bb818dc6..0000000000 --- a/docs/public/css/base.css +++ /dev/null @@ -1,173 +0,0 @@ -body { - padding-top: 80px; -} - -.container { - max-width: 970px; -} - -/* index.liquid *******************************************/ -#blurb { - padding-top: 40px; -} -#blurb p { - font-size: 1.9em; -} -#blurb .btn-group { - margin: 4px; -} - -#multiblurb { - line-height: 1.7; - text-align: center; - font-size: 12pt; -} -#multiblurb code { - border: 0; - font-size: 12pt; -} - -#news { - font-size: 12pt; -} -#news .date { - font-style: italic; -} - -/* default.liquid *****************************************/ -.tutorial-example { - position: relative; - margin-bottom: 10px; -} -.tutorial-example pre { - margin-bottom: 0px; -} -.tutorial-example a { - position: absolute; - top: 0px; - right: 0px; - padding: 15px 8px; - color: #777777; - font-weight: bold; - line-height: 10px; - font-size: 12px; - border-left: 1px solid #DDDDDD; - display: block; -} -.tutorial-example .accordion-body pre { - margin: 0 4px; - border-top: 0; - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -@media print { - .tutorial-example a { - display: none; - } -} -/* manual.liquid ******************************************/ -section { - padding-top: 24px; -} - -h3 code { - border: 0; - font-size: 20px; -} - -@media (max-width: 991px) { - #navcolumn { - /* Put nav column above manual content */ - position: relative !important; - margin-bottom: 60px; - } -} -@media (min-width: 992px) { - #manualcontent { - /* Put nav column left of manual content */ - padding-left: 280px; - } -} -.nav-pills { - margin-bottom: 20px; -} - .nav-pills li a { - padding: 8px 12px; -} - -.manual-example table { - border-top: 1px solid #E5E5E5; -} -.manual-example table td { - white-space: pre-wrap; - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; -} -.manual-example table td.jqprogram { - font-weight: bold; -} -.manual-example table th { - text-align: right; - padding-right: 10px; -} - -@media print { - #navcolumn { - display: none !important; - } - - .manual-example { - display: block !important; - height: auto !important; - } - - .jqplay-btn { - display: none !important; - } -} -/* shared/_footer.liquid **********************************/ -footer { - background-color: #F5F5F5; - padding: 20px 0; - margin-top: 40px; - color: #999999; - text-align: center; -} -footer p { - margin: 8px 0; -} - -/* typeahead **********************************************/ -.twitter-typeahead { - width: 100%; -} - -.tt-menu { - width: 100%; - background-color: #fff; - padding: 8px 0; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-border-radius: 8px; - -moz-border-radius: 8px; - border-radius: 8px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -} - -.tt-suggestion { - padding: 3px 20px; -} -.tt-suggestion:hover { - cursor: pointer; - color: #fff; - background-color: #446e9b; -} -.tt-suggestion.tt-cursor { - color: #fff; - background-color: #446e9b; -} -.tt-suggestion p { - margin: 0; -} diff --git a/docs/public/css/base.scss b/docs/public/css/base.scss deleted file mode 100644 index ffef3de440..0000000000 --- a/docs/public/css/base.scss +++ /dev/null @@ -1,181 +0,0 @@ -@charset "utf-8"; -body { - padding-top: 80px; -} - -.container { - max-width: 970px; -} - -/* index.liquid *******************************************/ - -#blurb { - padding-top: 40px; - p { - font-size: 1.9em; - } - .btn-group { - margin: 4px; - } -} - -#multiblurb { - line-height: 1.7; - text-align: center; - font-size: 12pt; - code { - border: 0; - font-size: 12pt; - } -} - -#news { - font-size: 12pt; - .date { - font-style: italic; - } -} - -/* default.liquid *****************************************/ - -.tutorial-example { - position: relative; - margin-bottom: 10px; - pre { - margin-bottom: 0px; - } - a { - position: absolute; - top: 0px; - right: 0px; - padding: 15px 8px; - color: #777777; - font-weight: bold; - line-height: 10px; - font-size: 12px; - border-left: 1px solid #DDDDDD; - display: block; - } - .accordion-body pre { - margin: 0 4px; - border-top: 0; - border-top-left-radius: 0; - border-top-right-radius: 0; - } -} - -@media print { - .tutorial-example a { - display: none; - } -} - -/* manual.liquid ******************************************/ - -section { - padding-top: 24px; -} - -h3 code { - border: 0; - font-size: 20px; -} - -@media(max-width: 991px){ - #navcolumn { - /* Put nav column above manual content */ - position: relative !important; - margin-bottom: 60px; - } -} - -@media(min-width: 992px) { - #manualcontent { - /* Put nav column left of manual content */ - padding-left: 280px; - } -} - -.nav-pills { - li a { - padding: 8px 12px; - } - margin-bottom: 20px; -} - -.manual-example table { - border-top: 1px solid #E5E5E5; - td { - white-space: pre-wrap; - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; - } - td.jqprogram { - font-weight: bold; - } - th { - text-align: right; - padding-right: 10px; - } -} - -@media print { - #navcolumn { - display: none !important; - } - .manual-example { - display: block !important; - height: auto !important; - } - .jqplay-btn { - display: none !important; - } -} - -/* shared/_footer.liquid **********************************/ - -footer { - background-color: #F5F5F5; - padding: 20px 0; - margin-top: 40px; - color: #999999; - text-align: center; - p { - margin: 8px 0; - } -} - -/* typeahead **********************************************/ - -.twitter-typeahead { - width: 100%; -} - -.tt-menu { - width: 100%; - background-color: #fff; - padding: 8px 0; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-border-radius: 8px; - -moz-border-radius: 8px; - border-radius: 8px; - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); - -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); - box-shadow: 0 5px 10px rgba(0,0,0,.2); -} - -.tt-suggestion { - padding: 3px 20px; - &:hover { - cursor: pointer; - color: #fff; - background-color: #446e9b; - } - &.tt-cursor { - color: #fff; - background-color: #446e9b; - } - p { - margin: 0; - } -} diff --git a/docs/public/css/style.css b/docs/public/css/style.css new file mode 100644 index 0000000000..d63e828275 --- /dev/null +++ b/docs/public/css/style.css @@ -0,0 +1,99 @@ +main { + padding: 1rem; + + & * { + scroll-margin-top: 4rem; + } + + @media print { + width: 100%!important; + --bs-code-color: --bs-body-color; + } +} + +header { + z-index: 1050!important; /* higher than #contents */ +} + +section[id] { + display: flow-root; + + > :first-child { + .icon-link { + opacity: 0; + + &:focus { + opacity: .8; + } + } + + &:hover .icon-link { + opacity: 1; + } + } +} + +.offcanvas[aria-modal=true] .nav-link { + padding: .7rem; +} +.offcanvas-md { + --bs-offcanvas-width: auto; +} + +ul { + list-style: none; + padding-left: 1rem; +} + +pre { + margin: 0 .5rem 1rem; + padding: .5rem 1rem; + background-color: var(--bs-secondary-bg-subtle); + border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color); +} + +button{ + &[aria-expanded=false] .bi-chevron-down { + display: none; + } + + &[aria-expanded=true] .bi-chevron-right { + display: none; + } +} + +mark { + padding: 0; +} + +.container-searchbox { + position: relative; + + & input:focus ~ kbd { + display: none; + } + + & ul { + position: absolute; + width: 100%; + top: 100%; + padding: 0; + background-color: var(--bs-body-bg); + border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color); + } + + & li { + padding: .3em .6em; + white-space: nowrap; + overflow-x: hidden; + + &[aria-selected=true] { + background-color: var(--bs-secondary-bg); + } + + &:hover { + cursor: pointer; + background-color: var(--bs-secondary-bg-subtle); + } + } +} diff --git a/docs/public/icon.png b/docs/public/icon.png new file mode 100644 index 0000000000..cfdc8ecda9 Binary files /dev/null and b/docs/public/icon.png differ diff --git a/docs/public/icon.svg b/docs/public/icon.svg new file mode 100644 index 0000000000..1f518f047f --- /dev/null +++ b/docs/public/icon.svg @@ -0,0 +1 @@ + diff --git a/docs/public/jq.png b/docs/public/jq.png deleted file mode 100644 index 41d6d391db..0000000000 Binary files a/docs/public/jq.png and /dev/null differ diff --git a/docs/public/jq.svg b/docs/public/jq.svg new file mode 100644 index 0000000000..1f9e2ddf6d --- /dev/null +++ b/docs/public/jq.svg @@ -0,0 +1 @@ + diff --git a/docs/public/js/manual-search.js b/docs/public/js/manual-search.js index e5d6ee53ab..6c7c72d56e 100644 --- a/docs/public/js/manual-search.js +++ b/docs/public/js/manual-search.js @@ -1,52 +1,34 @@ -var section_names = function(q) { - if (!q) { - return []; - } - var matches = []; - q = q.toLowerCase(); - $.each(section_map, function(k, v) { - if (k.toLowerCase().indexOf(q) != -1) { - matches.push(k); - } - }); - matches.sort(function(a, b) { - // shortest to longest - return a.length - b.length; +(() => { + const searchInput = document.querySelector('input#searchbox'); + const sectionIDs = JSON.parse(document.querySelector('#section-ids').innerText); + const sanitize = (string) => string.replaceAll('<', '<').replaceAll('>', '>'); + new autoComplete({ + selector: `#${searchInput.id}`, + wrapper: false, + data: { + src: Object.keys(sectionIDs), + filter: (list) => list.sort((x, y) => + x.match.indexOf('<') - y.match.indexOf('<') || x.value.length - y.value.length), + }, + searchEngine: (query, value) => { + const index = value.toLowerCase().indexOf(query.toLowerCase()); + if (index >= 0) { + return sanitize(value.substring(0, index)) + + `${sanitize(value.substring(index, index + query.length))}` + + sanitize(value.substring(index + query.length)); + } + }, }); - return matches; -} -var section_names_cb = function(q, cb) { - cb(section_names(q)); -} -var go_to_section = function() { - query = $('#searchbox').val(); - results = section_names(query); - if (results.length == 0) { - return; - } - result = results[0]; - location.hash = '#' + section_map[result]; - if (result != query) { - $('#searchbox').val(result); - } -} -$(function(){ - $('#searchbox').typeahead( - {hint: false, highlight: true, minLength: 1}, - {name: "contents", source: section_names_cb, limit: 6} - ).on('typeahead:selected', function(e, data) { - go_to_section(); + searchInput.addEventListener('selection', (event) => { + event.target.value = event.detail.selection.value; + location.hash = `#${sectionIDs[event.detail.selection.value]}`; }); - $('#searchbox').change(go_to_section); -}); -// add "Run" button to execute examples on jqplay.org -$(function() { - $.each($('.manual-example table'), function(index, value) { - $value = $(value) - var j = $value.find('tr:nth-child(2) td:first').text(); - var q = $value.find('.jqprogram').text().replace(/^jq /, '').replace(/(\r\n|\n|\r)/gm," ").replace(/^'(.+)'$/, '$1'); - var url = 'https://jqplay.org/jq?q=' + encodeURIComponent(q) +'&j=' + encodeURIComponent(j) - var $last_tr = $value.find('tr:last'); - $last_tr.after('Run'); + document.addEventListener('keydown', (event) => { + if (event.code === 'Slash' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey && !/^(INPUT|TEXTAREA)$/.test(event.target.nodeName)) { + searchInput.focus(); + searchInput.select(); + event.preventDefault(); + } }); -}); +})(); diff --git a/docs/site.yml b/docs/site.yml deleted file mode 100644 index e4990aeb9e..0000000000 --- a/docs/site.yml +++ /dev/null @@ -1,9 +0,0 @@ -# The key value pairs found below are available within the templates. - -url: https://jqlang.github.io/jq - -# This line is modified by the Makefile. To change the version number, -# edit the Autoconf version number at the top of configure.ac -jq_version: "1.6-159-gcff5336-dirty" - -root: '/jq' diff --git a/docs/templates/default.html.j2 b/docs/templates/default.html.j2 index 7830eb3726..67030e0566 100644 --- a/docs/templates/default.html.j2 +++ b/docs/templates/default.html.j2 @@ -2,32 +2,29 @@ {% include "shared/_head.html.j2" %} - + {% include "shared/_navbar.html.j2" %} -
-
-

{{headline}}

- {% for item in body %} - {% if item.text %} - {{ item.text | replace('$JQ_VERSION', jq_version) | markdownify }} - {% endif %} +
+

{{ headline }}

+ {%- for item in body %} + {%- if item.text %} + {{ item.text | markdownify }} + {%- endif %} - {% if item.command %} - {% set resultID = unique_id() %} -
-
-
{{item.command}}
- Show result -
-
-
{{item.result}}
-
-
- {% endif %} - {% endfor %} + {%- if item.command %} + {%- set resultID = unique_id() %} +
+
+
{{ item.command }}
+ +
+
{{ item.result }}
-
+ {%- endif %} + {%- endfor %} + {% include "shared/_footer.html.j2" %} diff --git a/docs/templates/index.html.j2 b/docs/templates/index.html.j2 index 4ec30007fb..3fd1566ec4 100644 --- a/docs/templates/index.html.j2 +++ b/docs/templates/index.html.j2 @@ -2,71 +2,54 @@ {% include "shared/_head.html.j2" %} - + {% include "shared/_navbar.html.j2" %} -
+
-
- -
-
{{body1 | markdownify}}
-
{{body2 | markdownify}}
-
{{body3 | markdownify}}
+
+
{{ body1 | markdownify }}
+
{{ body2 | markdownify }}
+
{{ body3 | markdownify }}
-
- {{tail | markdownify}} +
+ {{ tail | markdownify }}
-
-

News

-
-
    - {% for item in news %} -
  • - {{item.date}} - {{item.body | markdownify}} -
  • - {% endfor %} -
-
-
-
+

News

+
    + {%- for item in news %} +
  • + {{ item.date }} + {{ item.body | markdownify }} +
  • + {%- endfor %} +
+
{% include "shared/_footer.html.j2" %} diff --git a/docs/templates/manual.html.j2 b/docs/templates/manual.html.j2 index 21f9ad28e2..9a2540c8b0 100644 --- a/docs/templates/manual.html.j2 +++ b/docs/templates/manual.html.j2 @@ -2,98 +2,109 @@ {% include "shared/_head.html.j2" %} - + {% include "shared/_navbar.html.j2" %} -
-
- {% include "shared/_footer.html.j2" %} - + - + diff --git a/docs/templates/shared/_footer.html.j2 b/docs/templates/shared/_footer.html.j2 index 511f0b1fac..dbed4f2759 100644 --- a/docs/templates/shared/_footer.html.j2 +++ b/docs/templates/shared/_footer.html.j2 @@ -1,10 +1,14 @@ -