summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/website.yml2
-rw-r--r--Makefile.am6
-rw-r--r--docs/README.md14
-rwxr-xr-xdocs/build_website.py37
-rw-r--r--docs/content/download/default.yml6
-rw-r--r--docs/content/index.yml8
-rw-r--r--docs/content/manual/manual.yml5
-rw-r--r--docs/content/manual/v1.3/manual.yml2
-rw-r--r--docs/content/manual/v1.4/manual.yml2
-rw-r--r--docs/content/manual/v1.5/manual.yml2
-rw-r--r--docs/content/manual/v1.6/manual.yml2
-rw-r--r--docs/public/css/base.css173
-rw-r--r--docs/public/css/base.scss181
-rw-r--r--docs/public/css/style.css99
-rw-r--r--docs/public/icon.pngbin0 -> 4963 bytes
-rw-r--r--docs/public/icon.svg1
-rw-r--r--docs/public/jq.pngbin8195 -> 0 bytes
-rw-r--r--docs/public/jq.svg1
-rw-r--r--docs/public/js/manual-search.js80
-rw-r--r--docs/site.yml9
-rw-r--r--docs/templates/default.html.j241
-rw-r--r--docs/templates/index.html.j291
-rw-r--r--docs/templates/manual.html.j2179
-rw-r--r--docs/templates/shared/_footer.html.j220
-rw-r--r--docs/templates/shared/_head.html.j232
-rw-r--r--docs/templates/shared/_navbar.html.j263
26 files changed, 401 insertions, 655 deletions
diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml
index 9de1aa62..6fc8b809 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 e3b3e5a2..00133f6d 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 52fdd59b..3ea88160 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 5867f8c0..2b3afc77 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 re
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"</?p>", '', input))
+env.filters['no_paragraph'] = lambda input: Markup(re.sub(r'</?p>', '', 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 4f39c612..970f1c85 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 02ecafe5..82dcde98 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 89252ac2..e4c8c64b 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 c018e314..8cab6204 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 6cc1c591..cbfb8263 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 be2f1c56..14f70532 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 be62cab6..0a3d6002 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 e9bb818d..00000000
--- 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 ffef3de4..00000000
--- 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 00000000..d63e8282
--- /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 00000000..cfdc8ecd
--- /dev/null
+++ b/docs/public/icon.png
Binary files differ
diff --git a/docs/public/icon.svg b/docs/public/icon.svg
new file mode 100644
index 00000000..1f518f04
--- /dev/null
+++ b/docs/public/icon.svg
@@ -0,0 +1 @@
+<svg width="48" height="48" version="1.0" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><style>@media(prefers-color-scheme:dark){g[fill]{filter:invert(1)}}</style><g transform="matrix(.011 0 0 .011 1.94 12)"><g fill="#444"><circle cx="220" cy="1570" r="190"/><path d="m1330 312c-30 41-698 1492-710 1528s25 66 100 101c77 36 102 34 124 3s701-1477 716-1525c15-47-20-73-84-104s-116-44-146-3z"/></g><g fill="#111"><circle cx="2410" cy="200" r="190"/><path d="m1830 655c0 129 0 130 70 130h360v423c0 246-5 474-10 506-19 112-88 176-190 176-59 0-120-27-147-66-51-73-65-84-99-84-31 0-40 8-104 93-84 111-86 129-32 189 227 252 692 187 836-118 53-112 56-153 56-795v-514c0-64-30-100-100-100h-490c-149 0-150 0-150 160zM2867 1233c30 302 250 499 438 527 144 19 244 0 375-90v410c0 81 0 100 150 100 136 0 150-20 150-150v-1420c0-99-19-100-150-100s-139 15-139 82c-103-89-351-149-523-49s-342 278-301 690zm803-107c0 292-105 356-237 356-178 0-249-147-273-296-27-168 25-420 262-420 171 0 248 89 248 360z"/></g></g></svg>
diff --git a/docs/public/jq.png b/docs/public/jq.png
deleted file mode 100644
index 41d6d391..00000000
--- a/docs/public/jq.png
+++ /dev/null
Binary files differ
diff --git a/docs/public/jq.svg b/docs/public/jq.svg
new file mode 100644
index 00000000..1f9e2ddf
--- /dev/null
+++ b/docs/public/jq.svg
@@ -0,0 +1 @@
+<svg width="400" height="220" version="1.0" viewBox="0 0 400 220" xmlns="http://www.w3.org/2000/svg"><style>@media (prefers-color-scheme:dark){g[fill]{filter:invert(1);stroke:none}}</style><g transform="scale(.1)" stroke="#fff" stroke-width="10"><g fill="#444"><circle cx="220" cy="1570" r="190"/><path d="m1330 312c-30 41-698 1492-710 1528s25 66 100 101c77 36 102 34 124 3s701-1477 716-1525c15-47-20-73-84-104s-116-44-146-3z"/></g><g fill="#111"><circle cx="2410" cy="200" r="190"/><path d="m1830 655c0 129 0 130 70 130h360v423c0 246-5 474-10 506-19 112-88 176-190 176-59 0-120-27-147-66-51-73-65-84-99-84-31 0-40 8-104 93-84 111-86 129-32 189 227 252 692 187 836-118 53-112 56-153 56-795v-514c0-64-30-100-100-100h-490c-149 0-150 0-150 160zM2867 1233c30 302 250 499 438 527 144 19 244 0 375-90v410c0 81 0 100 150 100 136 0 150-20 150-150v-1420c0-99-19-100-150-100s-139 15-139 82c-103-89-351-149-523-49s-342 278-301 690zm803-107c0 292-105 356-237 356-178 0-249-147-273-296-27-168 25-420 262-420 171 0 248 89 248 360z"/></g></g></svg>
diff --git a/docs/public/js/manual-search.js b/docs/public/js/manual-search.js
index e5d6ee53..6c7c72d5 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('<', '&lt;').replaceAll('>', '&gt;');
+ 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)) +
+ `<mark>${sanitize(value.substring(index, index + query.length))}</mark>` +
+ 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('<tr class="jqplay-btn"><th><a href="' + url + '" class="btn btn-primary btn-sm">Run</a></th><th></th></tr><tr><th></th><th></th></tr>');
+ 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 e4990aeb..00000000
--- 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 7830eb37..67030e05 100644
--- a/docs/templates/default.html.j2
+++ b/docs/templates/default.html.j2
@@ -2,32 +2,29 @@
<html lang="en">
{% include "shared/_head.html.j2" %}
- <body id="{{slug}}">
+ <body>
{% include "shared/_navbar.html.j2" %}
- <div class="container">
- <div class="row">
- <h1>{{headline}}</h1>
- {% for item in body %}
- {% if item.text %}
- {{ item.text | replace('$JQ_VERSION', jq_version) | markdownify }}
- {% endif %}
+ <main id="main" class="container-lg">
+ <h1>{{ headline }}</h1>
+ {%- for item in body %}
+ {%- if item.text %}
+ {{ item.text | markdownify }}
+ {%- endif %}
- {% if item.command %}
- {% set resultID = unique_id() %}
- <div class="tutorial-example">
- <div class="accordion-heading">
- <pre>{{item.command}}</pre>
- <a data-toggle="collapse" href="#result{{resultID}}">Show result</a>
- </div>
- <div id="result{{resultID}}" class="accordion-body collapse">
- <pre>{{item.result}}</pre>
- </div>
- </div>
- {% endif %}
- {% endfor %}
+ {%- if item.command %}
+ {%- set resultID = unique_id() %}
+ <div class="tutorial-example mb-3">
+ <div class="d-flex accordion-heading me-2">
+ <pre class="flex-grow-1 me-0 mb-0" tabindex="0">{{ item.command }}</pre>
+ <button type="button" class="btn btn-sm btn-secondary text-body-secondary bg-secondary-subtle link-body-emphasis flex-shrink-0 d-flex align-items-center border border-start-0 d-print-none"
+ data-bs-toggle="collapse" data-bs-target="#result{{ resultID }}" aria-expanded="false" aria-controls="result{{ resultID }}">Show result</button>
+ </div>