From c1f11855e31e3975ef74c7d19304bee4e1b64e71 Mon Sep 17 00:00:00 2001 From: William Langford Date: Wed, 20 Feb 2019 20:50:08 -0500 Subject: Remove ruby dependency from website build --- Makefile.am | 18 +- configure.ac | 20 +- docs/.gitignore | 3 - docs/Pipfile | 11 + docs/Pipfile.lock | 85 + docs/README.md | 25 +- docs/build_manpage.py | 2 + docs/build_website.py | 62 + docs/content/1.tutorial/default.yml | 327 ---- docs/content/2.download/default.yml | 193 -- docs/content/3.manual/manual.yml | 3303 -------------------------------- docs/content/3.manual/v1.3/manual.yml | 1270 ------------- docs/content/3.manual/v1.4/manual.yml | 1672 ----------------- docs/content/3.manual/v1.5/manual.yml | 2878 ---------------------------- docs/content/3.manual/v1.6/manual.yml | 3287 -------------------------------- docs/content/download/default.yml | 192 ++ docs/content/index.yml | 73 + docs/content/index/index.yml | 73 - docs/content/manual/manual.yml | 3304 +++++++++++++++++++++++++++++++++ docs/content/manual/v1.3/manual.yml | 1270 +++++++++++++ docs/content/manual/v1.4/manual.yml | 1672 +++++++++++++++++ docs/content/manual/v1.5/manual.yml | 2878 ++++++++++++++++++++++++++++ docs/content/manual/v1.6/manual.yml | 3287 ++++++++++++++++++++++++++++++++ docs/content/tutorial/default.yml | 327 ++++ docs/public/css/base.css | 173 ++ docs/templates/default.html.j2 | 34 + docs/templates/default.liquid | 34 - docs/templates/index.html.j2 | 73 + docs/templates/index.liquid | 73 - docs/templates/manual.html.j2 | 99 + docs/templates/manual.liquid | 99 - docs/templates/shared/_footer.html.j2 | 10 + docs/templates/shared/_footer.liquid | 10 - docs/templates/shared/_head.html.j2 | 17 + docs/templates/shared/_head.liquid | 17 - docs/templates/shared/_navbar.html.j2 | 27 + docs/templates/shared/_navbar.liquid | 27 - scripts/update-website | 2 +- 38 files changed, 13626 insertions(+), 13301 deletions(-) create mode 100644 docs/Pipfile create mode 100644 docs/Pipfile.lock create mode 100644 docs/build_manpage.py create mode 100755 docs/build_website.py delete mode 100644 docs/content/1.tutorial/default.yml delete mode 100644 docs/content/2.download/default.yml delete mode 100644 docs/content/3.manual/manual.yml delete mode 100644 docs/content/3.manual/v1.3/manual.yml delete mode 100644 docs/content/3.manual/v1.4/manual.yml delete mode 100644 docs/content/3.manual/v1.5/manual.yml delete mode 100644 docs/content/3.manual/v1.6/manual.yml create mode 100644 docs/content/download/default.yml create mode 100644 docs/content/index.yml delete mode 100644 docs/content/index/index.yml create mode 100644 docs/content/manual/manual.yml create mode 100644 docs/content/manual/v1.3/manual.yml create mode 100644 docs/content/manual/v1.4/manual.yml create mode 100644 docs/content/manual/v1.5/manual.yml create mode 100644 docs/content/manual/v1.6/manual.yml create mode 100644 docs/content/tutorial/default.yml create mode 100644 docs/public/css/base.css create mode 100644 docs/templates/default.html.j2 delete mode 100644 docs/templates/default.liquid create mode 100644 docs/templates/index.html.j2 delete mode 100644 docs/templates/index.liquid create mode 100644 docs/templates/manual.html.j2 delete mode 100644 docs/templates/manual.liquid create mode 100644 docs/templates/shared/_footer.html.j2 delete mode 100644 docs/templates/shared/_footer.liquid create mode 100644 docs/templates/shared/_head.html.j2 delete mode 100644 docs/templates/shared/_head.liquid create mode 100644 docs/templates/shared/_navbar.html.j2 delete mode 100644 docs/templates/shared/_navbar.liquid diff --git a/Makefile.am b/Makefile.am index e1083fe7..9f2de435 100644 --- a/Makefile.am +++ b/Makefile.am @@ -136,8 +136,8 @@ TESTS_ENVIRONMENT = NO_VALGRIND=$(NO_VALGRIND) man_MANS = jq.1 if ENABLE_DOCS -jq.1: $(srcdir)/docs/content/3.manual/manual.yml - $(AM_V_GEN) ( cd ${abs_srcdir}/docs; '$(BUNDLER)' exec rake manpage ) > $@ || { rm -f $@; false; } +jq.1: $(srcdir)/docs/content/manual/manual.yml + $(AM_V_GEN) ( cd ${abs_srcdir}/docs; pipenv run python build_manpage.py ) > $@ || { rm -f $@; false; } jq.1.prebuilt: jq.1 $(AM_V_GEN) cp jq.1 $@ || { rm -f $@; false; } else @@ -165,8 +165,8 @@ install-binaries: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec DOC_FILES = docs/content docs/public docs/templates docs/site.yml \ - docs/Gemfile docs/Gemfile.lock docs/Rakefile docs/README.md \ - jq.1.prebuilt + docs/Pipfile docs/Pipfile.lock docs/build_website.py \ + docs/README.md jq.1.prebuilt EXTRA_DIST = $(DOC_FILES) $(man_MANS) $(TESTS) $(TEST_LOG_COMPILER) \ jq.1.prebuilt jq.spec src/lexer.c src/lexer.h src/parser.c \ @@ -180,11 +180,11 @@ EXTRA_DIST = $(DOC_FILES) $(man_MANS) $(TESTS) $(TEST_LOG_COMPILER) \ tests/modules/test_bind_order0.jq \ tests/modules/test_bind_order1.jq \ tests/modules/test_bind_order2.jq tests/onig.supp \ - tests/onig.test tests/setup tests/torture/input0.json \ - tests/optional.test tests/optionaltest \ - tests/utf8-truncate.jq tests/utf8test \ - tests/base64.test tests/base64test \ - tests/jq-f-test.sh tests/shtest + tests/onig.test tests/setup tests/torture/input0.json \ + tests/optional.test tests/optionaltest \ + tests/utf8-truncate.jq tests/utf8test \ + tests/base64.test tests/base64test \ + tests/jq-f-test.sh tests/shtest diff --git a/configure.ac b/configure.ac index 97f4eab4..e8c6a71e 100644 --- a/configure.ac +++ b/configure.ac @@ -74,7 +74,7 @@ dnl Code coverage AC_ARG_ENABLE([gcov], AC_HELP_STRING([--enable-gcov], [enable gcov code coverage tool])) -dnl Don't attempt to build docs if there's no Ruby lying around +dnl Don't attempt to build docs if python deps aren't installed AC_ARG_ENABLE([docs], AC_HELP_STRING([--disable-docs], [don't build docs])) @@ -87,25 +87,25 @@ AC_ARG_ENABLE([all-static], AC_HELP_STRING([--enable-all-static], [link jq with static libraries only])) AS_IF([test "x$enable_docs" != "xno"],[ - AC_CHECK_PROGS(bundle_cmd, bundle) + AC_CHECK_PROGS(pipenv_cmd, pipenv) - AC_CACHE_CHECK([for Ruby dependencies], [jq_cv_ruby_deps], - [jq_cv_ruby_deps=yes; - AS_IF([test "x$bundle_cmd" = "x" || \ - ! bmsg="`cd ${srcdir}/docs; "$bundle_cmd" check 2>/dev/null`"],[ - AC_MSG_WARN([$bmsg]) + AC_CACHE_CHECK([for Python dependencies], [jq_cv_python_deps], + [jq_cv_python_deps=yes; + AS_IF([test "x$pipenv_cmd" = "x" || \ + ! bmsg="`cd ${srcdir}/docs; LC_ALL=$LANG "$pipenv_cmd" check`"],[ + AC_MSG_ERROR([$bmsg]) cat < for more info on RVM. +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 install` from the `docs` directory. -Once RVM is installed, you can install all the dependencies for jq's -documentation build by running this from the `docs` directory: +Once this is done, rerun `./configure` in the jq root directory and then +the Makefile will be able to generate the jq manpage. - bundle install - -When bundle manages to install the dependencies, rerun `./configure` -in the jq root directory and then the Makefile will be able to -generate the jq manpage. +To build the website, run `pipenv run ./build_website.py` from inside +the `docs` directory. diff --git a/docs/build_manpage.py b/docs/build_manpage.py new file mode 100644 index 00000000..ab730481 --- /dev/null +++ b/docs/build_manpage.py @@ -0,0 +1,2 @@ +#!/usr/bin/env python3 +print("Manpage build not yet supported") diff --git a/docs/build_website.py b/docs/build_website.py new file mode 100755 index 00000000..2dd27036 --- /dev/null +++ b/docs/build_website.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +import glob +import itertools +from jinja2 import Environment, FileSystemLoader, Markup, select_autoescape, contextfunction +from markdown import markdown +import os +import os.path +import re +import shutil +import yaml + +env = Environment( + loader=FileSystemLoader('templates'), + autoescape=select_autoescape(['html.j2']), +) + +def load_yml_file(fn): + with open(fn) as f: + return yaml.load(f) + +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['markdownify'] = lambda input: Markup(markdown(input)) +env.filters['no_paragraph'] = lambda input: Markup(re.sub(r"", '', input)) + +env.globals['unique_id'] = contextfunction(lambda ctx: str(next(ctx['unique_ctr']))) + + +env.globals.update(load_yml_file('site.yml')) + + +env.globals['navigation'] = ['tutorial', 'download', 'manual'] + +def generate_file(env, fname='content/1.tutorial/default.yml'): + path, base = os.path.split(fname) + path = os.path.relpath(path, 'content') + 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) + + ctx = load_yml_file(fname) + ctx.update(unique_ctr=itertools.count(1), permalink=path) + os.makedirs(output_dir, exist_ok=True) + env.get_template(template_name).stream(ctx).dump(output_path, encoding='utf-8') + + +def copy_public_files(root=''): + for f in os.scandir(os.path.join('public', root)): + src = os.path.join(root, f.name) + dst = os.path.join('output', src) + if f.is_dir(): + os.makedirs(dst, exist_ok=True) + copy_public_files(src) + else: + shutil.copyfile(f.path, dst) + +copy_public_files() + +for fn in glob.glob('content/**/*.yml', recursive=True): + generate_file(env, fn) diff --git a/docs/content/1.tutorial/default.yml b/docs/content/1.tutorial/default.yml deleted file mode 100644 index 5a2dcb83..00000000 --- a/docs/content/1.tutorial/default.yml +++ /dev/null @@ -1,327 +0,0 @@ -headline: Tutorial -body: - - text: | - - GitHub has a JSON API, so let's play with that. This URL gets us the last - 5 commits from the jq repo. - - - command: "curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5'" - result: | - [ - { - "sha": "d25341478381063d1c76e81b3a52e0592a7c997f", - "commit": { - "author": { - "name": "Stephen Dolan", - "email": "mu@netsoc.tcd.ie", - "date": "2013-06-22T16:30:59Z" - }, - "committer": { - "name": "Stephen Dolan", - "email": "mu@netsoc.tcd.ie", - "date": "2013-06-22T16:30:59Z" - }, - "message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161", - "tree": { - "sha": "6ab697a8dfb5a96e124666bf6d6213822599fb40", - "url": "https://api.github.com/repos/stedolan/jq/git/trees/6ab697a8dfb5a96e124666bf6d6213822599fb40" - }, - "url": "https://api.github.com/repos/stedolan/jq/git/commits/d25341478381063d1c76e81b3a52e0592a7c997f", - "comment_count": 0 - }, - "url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f", - "html_url": "https://github.com/stedolan/jq/commit/d25341478381063d1c76e81b3a52e0592a7c997f", - "comments_url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f/comments", - "author": { - "login": "stedolan", - ... - - - text: | - - GitHub returns nicely formatted JSON. For servers that don't, it can be - helpful to pipe the response through jq to pretty-print it. The simplest - jq program is the expression `.`, which takes the input and produces it - unchanged as output. - - - command: "curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.'" - result: | - [ - { - "sha": "d25341478381063d1c76e81b3a52e0592a7c997f", - "commit": { - "author": { - "name": "Stephen Dolan", - "email": "mu@netsoc.tcd.ie", - "date": "2013-06-22T16:30:59Z" - }, - "committer": { - "name": "Stephen Dolan", - "email": "mu@netsoc.tcd.ie", - "date": "2013-06-22T16:30:59Z" - }, - "message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161", - "tree": { - "sha": "6ab697a8dfb5a96e124666bf6d6213822599fb40", - "url": "https://api.github.com/repos/stedolan/jq/git/trees/6ab697a8dfb5a96e124666bf6d6213822599fb40" - }, - "url": "https://api.github.com/repos/stedolan/jq/git/commits/d25341478381063d1c76e81b3a52e0592a7c997f", - "comment_count": 0 - }, - "url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f", - "html_url": "https://github.com/stedolan/jq/commit/d25341478381063d1c76e81b3a52e0592a7c997f", - "comments_url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f/comments", - "author": { - "login": "stedolan", - ... - - - text: | - - We can use jq to extract just the first commit. - - - command: "curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.[0]'" - result: | - { - "sha": "d25341478381063d1c76e81b3a52e0592a7c997f", - "commit": { - "author": { - "name": "Stephen Dolan", - "email": "mu@netsoc.tcd.ie", - "date": "2013-06-22T16:30:59Z" - }, - "committer": { - "name": "Stephen Dolan", - "email": "mu@netsoc.tcd.ie", - "date": "2013-06-22T16:30:59Z" - }, - "message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161", - "tree": { - "sha": "6ab697a8dfb5a96e124666bf6d6213822599fb40", - "url": "https://api.github.com/repos/stedolan/jq/git/trees/6ab697a8dfb5a96e124666bf6d6213822599fb40" - }, - "url": "https://api.github.com/repos/stedolan/jq/git/commits/d25341478381063d1c76e81b3a52e0592a7c997f", - "comment_count": 0 - }, - "url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f", - "html_url": "https://github.com/stedolan/jq/commit/d25341478381063d1c76e81b3a52e0592a7c997f", - "comments_url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f/comments", - "author": { - "login": "stedolan", - "id": 79765, - "avatar_url": "https://avatars.githubusercontent.com/u/79765?v=3", - "gravatar_id": "", - "url": "https://api.github.com/users/stedolan", - "html_url": "https://github.com/stedolan", - "followers_url": "https://api.github.com/users/stedolan/followers", - "following_url": "https://api.github.com/users/stedolan/following{/other_user}", - "gists_url": "https://api.github.com/users/stedolan/gists{/gist_id}", - "starred_url": "https://api.github.com/users/stedolan/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/stedolan/subscriptions", - "organizations_url": "https://api.github.com/users/stedolan/orgs", - "repos_url": "https://api.github.com/users/stedolan/repos", - "events_url": "https://api.github.com/users/stedolan/events{/privacy}", - "received_events_url": "https://api.github.com/users/stedolan/received_events", - "type": "User", - "site_admin": false - }, - "committer": { - "login": "stedolan", - "id": 79765, - "avatar_url": "https://avatars.githubusercontent.com/u/79765?v=3", - "gravatar_id": "", - "url": "https://api.github.com/users/stedolan", - "html_url": "https://github.com/stedolan", - "followers_url": "https://api.github.com/users/stedolan/followers", - "following_url": "https://api.github.com/users/stedolan/following{/other_user}", - "gists_url": "https://api.github.com/users/stedolan/gists{/gist_id}", - "starred_url": "https://api.github.com/users/stedolan/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/stedolan/subscriptions", - "organizations_url": "https://api.github.com/users/stedolan/orgs", - "repos_url": "https://api.github.com/users/stedolan/repos", - "events_url": "https://api.github.com/users/stedolan/events{/privacy}", - "received_events_url": "https://api.github.com/users/stedolan/received_events", - "type": "User", - "site_admin": false - }, - "parents": [ - { - "sha": "54b9c9bdb225af5d886466d72f47eafc51acb4f7", - "url": "https://api.github.com/repos/stedolan/jq/commits/54b9c9bdb225af5d886466d72f47eafc51acb4f7", - "html_url": "https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7" - }, - { - "sha": "8b1b503609c161fea4b003a7179b3fbb2dd4345a", - "url": "https://api.github.com/repos/stedolan/jq/commits/8b1b503609c161fea4b003a7179b3fbb2dd4345a", - "html_url": "https://github.com/stedolan/jq/commit/8b1b503609c161fea4b003a7179b3fbb2dd4345a" - } - ] - } - - - text: | - - For the rest of the examples, I'll leave out the `curl` command - it's not - going to change. - - There's a lot of info we don't care about there, so we'll restrict it down - to the most interesting fields. - - - command: "jq '.[0] | {message: .commit.message, name: .commit.committer.name}'" - result: | - { - "message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161", - "name": "Stephen Dolan" - } - - - text: | - - The `|` operator in jq feeds the output of one filter (`.[0]` which gets - the first element of the array in the response) into the input of another - (`{...}` which builds an object out of those fields). You can access - nested attributes, such as `.commit.message`. - - Now let's get the rest of the commits. - - - command: "jq '.[] | {message: .commit.message, name: .commit.committer.name}'" - result: | - { - "message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161", - "name": "Stephen Dolan" - } - { - "message": "Reject all overlong UTF8 sequences.", - "name": "Stephen Dolan" - } - { - "message": "Fix various UTF8 parsing bugs.\n\nIn particular, parse bad UTF8 by replacing the broken bits with U+FFFD\nand resychronise correctly after broken sequences.", - "name": "Stephen Dolan" - } - { - "message": "Fix example in manual for `floor`. See #155.", - "name": "Stephen Dolan" - } - { - "message": "Document floor", - "name": "Nicolas Williams" - } - - - text: | - - `.[]` returns each element of the array returned in the response, one at a - time, which are all fed into - `{message: .commit.message, name: .commit.committer.name}`. - - Data in jq is represented as streams of JSON values - every jq - expression runs for each value in its input stream, and can - produce any number of values to its output stream. - - Streams are serialised by just separating JSON values with - whitespace. This is a `cat`-friendly format - you can just join - two JSON streams together and get a valid JSON stream. - - If you want to get the output as a single array, you can tell jq to - "collect" all of the answers by wrapping the filter in square - brackets: - - - command: "jq '[.[] | {message: .commit.message, name: .commit.committer.name}]'" - result: | - [ - { - "message": "Merge pull request #163 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161", - "name": "Stephen Dolan" - }, - { - "message": "Reject all overlong UTF8 sequences.", - "name": "Stephen Dolan" - }, - { - "message": "Fix various UTF8 parsing bugs.\n\nIn particular, parse bad UTF8 by replacing the broken bits with U+FFFD\nand resychronise correctly after broken sequences.", - "name": "Stephen Dolan" - }, - { - "message": "Fix example in manual for `floor`. See #155.", - "name": "Stephen Dolan" - }, - { - "message": "Document floor", - "name": "Nicolas Williams" - } - ] - - - text: | - - - - - - - Next, let's try getting the URLs of the parent commits out of the - API results as well. In each commit, the GitHub API includes information - about "parent" commits. There can be one or many. - - "parents": [ - { - "sha": "54b9c9bdb225af5d886466d72f47eafc51acb4f7", - "url": "https://api.github.com/repos/stedolan/jq/commits/54b9c9bdb225af5d886466d72f47eafc51acb4f7", - "html_url": "https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7" - }, - { - "sha": "8b1b503609c161fea4b003a7179b3fbb2dd4345a", - "url": "https://api.github.com/repos/stedolan/jq/commits/8b1b503609c161fea4b003a7179b3fbb2dd4345a", - "html_url": "https://github.com/stedolan/jq/commit/8b1b503609c161fea4b003a7179b3fbb2dd4345a" - } - ] - - We want to pull out all of the "html_url" fields inside that array of parent - commits and make a simple list of strings to go along with the - "message" and "author" fields we already have. - - - command: "jq '[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]'" - result: | - [ - { - "message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161", - "name": "Stephen Dolan", - "parents": [ - "https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7", - "https://github.com/stedolan/jq/commit/8b1b503609c161fea4b003a7179b3fbb2dd4345a" - ] - }, - { - "message": "Reject all overlong UTF8 sequences.", - "name": "Stephen Dolan", - "parents": [ - "https://github.com/stedolan/jq/commit/ff48bd6ec538b01d1057be8e93b94eef6914e9ef" - ] - }, - { - "message": "Fix various UTF8 parsing bugs.\n\nIn particular, parse bad UTF8 by replacing the broken bits with U+FFFD\nand resychronise correctly after broken sequences.", - "name": "Stephen Dolan", - "parents": [ - "https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7" - ] - }, - { - "message": "Fix example in manual for `floor`. See #155.", - "name": "Stephen Dolan", - "parents": [ - "https://github.com/stedolan/jq/commit/3dcdc582ea993afea3f5503a78a77675967ecdfa" - ] - }, - { - "message": "Document floor", - "name": "Nicolas Williams", - "parents": [ - "https://github.com/stedolan/jq/commit/7c4171d414f647ab08bcd20c76a4d8ed68d9c602" - ] - } - ] - - - text: | - - Here we're making an object as before, but this time the `parents` - field is being set to `[.parents[].html_url]`, which collects - all of the parent commit URLs defined in the parents object. - - - text: | - - - - - - - Here endeth the tutorial! There's lots more to play with. Go - read [the manual](../manual/) if you're interested, and [download - jq](../download/) if you haven't already. diff --git a/docs/content/2.download/default.yml b/docs/content/2.download/default.yml deleted file mode 100644 index 2cf7d125..00000000 --- a/docs/content/2.download/default.yml +++ /dev/null @@ -1,193 +0,0 @@ -headline: Download jq -body: - - - text: | - - jq is written in C and has no runtime dependencies, so it should be - possible to build it for nearly any platform. Prebuilt binaries are - available for Linux, OS X and Windows. - - The binaries should just run, but on OS X and Linux you may need - to make them executable first using `chmod +x jq`. - - jq is licensed under the MIT license. For all of the gory - details, read the file `COPYING` in the source distribution. - - - ### Linux - - * jq 1.5 is in the official [Debian](https://packages.debian.org/jq) and - [Ubuntu](http://packages.ubuntu.com/jq) repositories. Install using - `sudo apt-get install jq`. - - * jq 1.5 is in the official - [Fedora](http://pkgs.fedoraproject.org/cgit/jq.git/) repository. - Install using `sudo dnf install jq`. - - * jq 1.4 is in the official [openSUSE](https://software.opensuse.org/package/jq) - repository. Install using `sudo zypper install jq`. - - * jq 1.5 is in the official - [Arch](https://www.archlinux.org/packages/?sort=&q=jq&maintainer=&flagged=) - repository. Install using `sudo pacman -Sy jq`. - - * jq 1.6 binaries for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux32). - - * jq 1.5 binaries for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux32). - - * jq 1.4 binaries for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-linux-x86_64) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-linux-x86). - - * jq 1.3 binaries for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-linux-x86_64) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-linux-x86). - - ### OS X - - * Use [Homebrew](http://brew.sh/) to install jq 1.5 with - `brew install jq`. - - * jq 1.6 binary for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64). - - * jq 1.5 binary for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-osx-amd64). - - * jq 1.4 binaries for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-osx-x86_64) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-osx-x86). - - * jq 1.3 binaries for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-osx-x86_64) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-osx-x86). - - ### FreeBSD - - * `pkg install jq` as root installs a pre-built - [binary package](https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/pkgng-intro.html). - - * `make -C /usr/ports/textproc/jq install clean` as root installs the - [jq](https://www.freshports.org/textproc/jq/) - [port](https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/ports-using.html) - from source. - - ### Solaris - - * `pkgutil -i jq` in [OpenCSW](https://www.opencsw.org/p/jq) for Solaris - 10+, Sparc and x86. - - * jq 1.4 binaries for Solaris 11 - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-solaris11-64) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-solaris11-32). - - ### Windows - - * Use [Chocolatey NuGet](https://chocolatey.org/) to install jq 1.5 with - `chocolatey install jq`. - - * jq 1.6 executables for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.6/jq-win64.exe) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.6/jq-win32.exe). - - * jq 1.5 executables for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-win64.exe) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-win32.exe). - - * jq 1.4 executables for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-win64.exe) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-win32.exe). - - * jq 1.3 executables for - [64-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-win64.exe) - or - [32-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-win32.exe). - - ### Checksums and signatures - - SHA-256 checksums are provided for all release and pre-release binaries. - They can be found under - [sig/v1.x/sha256sum.txt](https://github.com/stedolan/jq/tree/master/sig). - The checksums for jq 1.6 are in - [sig/v1.6/sha256sum.txt](https://raw.githubusercontent.com/stedolan/jq/master/sig/v1.6/sha256sum.txt). - The checksums for jq 1.5 are in - [sig/v1.5/sha256sum.txt](https://raw.githubusercontent.com/stedolan/jq/master/sig/v1.5/sha256sum.txt). - - Additionally, all binaries are signed by the - [jq Package Signing Key](https://raw.githubusercontent.com/stedolan/jq/master/sig/jq-release.key). - The signatures can be found under - [sig/v1.x/\*.asc](https://github.com/stedolan/jq/tree/master/sig). - The signatures for jq 1.6 are in - [sig/v1.5/\*.asc](https://github.com/stedolan/jq/tree/master/sig/v1.6). - The signatures for jq 1.5 are in - [sig/v1.5/\*.asc](https://github.com/stedolan/jq/tree/master/sig/v1.5). - You can use [GnuPG](https://gnupg.org/) to verify a signature by downloading - the signature and running `gpg --verify signature.asc`. - - ### From source on Linux, OS X, Cygwin, and other POSIX-like operating systems - - * [Source tarball for jq 1.6](https://github.com/stedolan/jq/releases/download/jq-1.6/jq-1.6.tar.gz) - * [Source tarball for jq 1.5](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-1.5.tar.gz) - - You can build it using the usual `./configure && make && sudo - make install` rigmarole. - - If you're interested in using the lastest development version, try: - - git clone https://github.com/stedolan/jq.git - cd jq - autoreconf -i - ./configure --disable-maintainer-mode - make - sudo make install - - To build it from a git clone, you'll need to install a few - packages first: - - * [GCC](https://gcc.gnu.org) - * [Make](https://www.gnu.org/software/make/) - * [Autotools](https://www.gnu.org/software/automake/) - - For Linux systems, these will all be in your system's package - manager, and if you do development on the machine they're most - likely already installed. - - On OS X, these are all included in Apple's command line tools, which can - be installed from [Xcode](https://developer.apple.com/xcode/). However, - you may find that you need a newer version of Bison than the one provided - by Apple. This can be found in [Homebrew](http://brew.sh) or - [MacPorts](https://macports.org/). - - The `--disable-maintainer-mode` flag says to use the pre-generated lexer - and parser that come with the code. To compile the lexer and parser also - from source, leave out this flag. You will need to install - [Flex](http://flex.sourceforge.net/) and - [Bison](https://www.gnu.org/software/bison/). - - #### Building the documentation - - jq's documentation is compiled into static HTML using - [Bonsai](http://www.tinytree.info). To view the documentation - locally, run `rake serve` (or `bundle exec rake serve`) from the - docs/ subdirectory. To build the docs just `rake build` from the - docs subdirectory. You'll need a few Ruby 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 - the YAML docs, and you'll still need the Ruby dependencies to - build the manpage. - diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml deleted file mode 100644 index 150565b4..00000000 --- a/docs/content/3.manual/manual.yml +++ /dev/null @@ -1,3303 +0,0 @@ ---- -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).* - -body: | - - A jq program is a "filter": it takes an input, and produces an - output. There are a lot of builtin filters for extracting a - particular field of an object, or converting a number to a string, - or various other standard tasks. - - Filters can be combined in various ways - you can pipe the output of - one filter into another filter, or collect the output of a filter - into an array. - - Some filters produce multiple results, for instance there's one that - produces all the elements of its input array. Piping that filter - into a second runs the second filter for each element of the - array. Generally, things that would be done with loops and iteration - in other languages are just done by gluing filters together in jq. - - It's important to remember that every filter has an input and an - output. Even literals like "hello" or 42 are filters - they take an - input but always produce the same literal as output. Operations that - combine two filters, like addition, generally feed the same input to - both and combine the results. So, you can implement an averaging - filter as `add / length` - feeding the input array both to the `add` - filter and the `length` filter and then performing the division. - - But that's getting ahead of ourselves. :) Let's start with something - simpler: - -manpage_intro: | - jq(1) -- Command-line JSON processor - ==================================== - - ## SYNOPSIS - - `jq` [...] [...] - - `jq` can transform JSON in various ways, by selecting, iterating, - reducing and otherwise mangling JSON documents. For instance, - running the command `jq 'map(.price) | add'` will take an array of - JSON objects as input and return the sum of their "price" fields. - - `jq` can accept text input as well, but by default, `jq` reads a - stream of JSON entities (including numbers and other literals) from - `stdin`. Whitespace is only needed to separate entities such as 1 - and 2, and true and false. One or more may be specified, in - which case `jq` will read input from those instead. - - The are described in the [INVOKING JQ] section; they - mostly concern input and output formatting. The is written - in the jq language and specifies how to transform the input - file or document. - - ## FILTERS - -manpage_epilogue: | - ## BUGS - - Presumably. Report them or discuss them at: - - https://github.com/stedolan/jq/issues - - ## AUTHOR - - Stephen Dolan `` - -sections: - - title: Invoking jq - body: | - - jq filters run on a stream of JSON data. The input to jq is - parsed as a sequence of whitespace-separated JSON values which - are passed through the provided filter one at a time. The - output(s) of the filter are written to standard out, again as a - sequence of whitespace-separated JSON data. - - Note: it is important to mind the shell's quoting rules. As a - general rule it's best to always quote (with single-quote - characters) the jq program, as too many characters with special - meaning to jq are also shell meta-characters. For example, `jq - "foo"` will fail on most Unix shells because that will be the same - as `jq foo`, which will generally fail because `foo is not - defined`. When using the Windows command shell (cmd.exe) it's - best to use double quotes around your jq program when given on the - command-line (instead of the `-f program-file` option), but then - double-quotes in the jq program need backslash escaping. - - You can affect how jq reads and writes its input and output - using some command-line options: - - * `--version`: - - Output the jq version and exit with zero. - - * `--seq`: - - Use the `application/json-seq` MIME type scheme for separating - JSON texts in jq's input and output. This means that an ASCII - RS (record separator) character is printed before each value on - output and an ASCII LF (line feed) is printed after every - output. Input JSON texts that fail to parse are ignored (but - warned about), discarding all subsequent input until the next - RS. This mode also parses the output of jq without the `--seq` - option. - - * `--stream`: - - Parse the input in streaming fashion, outputing arrays of path - and leaf values (scalars and empty arrays or empty objects). - For example, `"a"` becomes `[[],"a"]`, and `[[],"a",["b"]]` - becomes `[[0],[]]`, `[[1],"a"]`, and `[[1,0],"b"]`. - - This is useful for processing very large inputs. Use this in - conjunction with filtering and the `reduce` and `foreach` syntax - to reduce large inputs incrementally. - - * `--slurp`/`-s`: - - Instead of running the filter for each JSON object in the - input, read the entire input stream into a large array and run - the filter just once. - - * `--raw-input`/`-R`: - - Don't parse the input as JSON. Instead, each line of text is - passed to the filter as a string. If combined with `--slurp`, - then the entire input is passed to the filter as a single long - string. - - * `--null-input`/`-n`: - - Don't read any input at all! Instead, the filter is run once - using `null` as the input. This is useful when using jq as a - simple calculator or to construct JSON data from scratch. - - * `--compact-output` / `-c`: - - By default, jq pretty-prints JSON output. Using this option - will result in more compact output by instead putting each - JSON object on a single line. - - * `--tab`: - - Use a tab for each indentation level instead of two spaces. - - * `--indent n`: - - Use the given number of spaces (no more than 8) for indentation. - - * `--color-output` / `-C` and `--monochrome-output` / `-M`: - - By default, jq outputs colored JSON if writing to a - terminal. You can force it to produce color even if writing to - a pipe or a file using `-C`, and disable color with `-M`. - - Colors can be configured with the `JQ_COLORS` environment - variable (see below). - - * `--ascii-output` / `-a`: - - jq usually outputs non-ASCII Unicode codepoints as UTF-8, even - if the input specified them as escape sequences (like - "\u03bc"). Using this option, you can force jq to produce pure - ASCII output with every non-ASCII character replaced with the - equivalent escape sequence. - - * `--unbuffered` - - Flush the output after each JSON object is printed (useful if - you're piping a slow data source into jq and piping jq's - output elsewhere). - - * `--sort-keys` / `-S`: - - Output the fields of each object with the keys in sorted order. - - * `--raw-output` / `-r`: - - With this option, if the filter's result is a string then it - will be written directly to standard output rather than being - formatted as a JSON string with quotes. This can be useful for - making jq filters talk to non-JSON-based systems. - - * `--join-output` / `-j`: - - Like `-r` but jq won't print a newline after each output. - - * `-f filename` / `--from-file filename`: - - Read filter from the file rather than from a command line, like - awk's -f option. You can also use '#' to make comments. - - * `-Ldirectory` / `-L directory`: - - Prepend `directory` to the search list for modules. If this - option is used then no builtin search list is used. See the - section on modules below. - - * `-e` / `--exit-status`: - - Sets the exit status of jq to 0 if the last output values was - neither `false` nor `null`, 1 if the last output value was - either `false` or `null`, or 4 if no valid result was ever - produced. Normally jq exits with 2 if there was any usage - problem or system error, 3 if there was a jq program compile - error, or 0 if the jq program ran. - - Another way to set the exit status is with the `halt_error` - builtin function. - - * `--arg name value`: - - This option passes a value to the jq program as a predefined - variable. If you run jq with `--arg foo bar`, then `$foo` is - available in the program and has the value `"bar"`. Note that - `value` will be treated as a string, so `--arg foo 123` will - bind `$foo` to `"123"`. - - Named arguments are also available to the jq program as - `$ARGS.named`. - - * `--argjson name JSON-text`: - - This option passes a JSON-encoded value to the jq program as a - predefined variable. If you run jq with `--argjson foo 123`, then - `$foo` is available in the program and has the value `123`. - - * `--slurpfile variable-name filename`: - - This option reads all the JSON texts in the named file and binds - an array of the parsed JSON values to the given global variable. - If you run jq with `--slurpfile foo bar`, then `$foo` is available - in the program and has an array whose elements correspond to the - texts in the file named `bar`. - - * `--rawfile variable-name filename`: - - This option reads in the named file and binds its contents to the given - global variable. If you run jq with `--rawfile foo bar`, then `$foo` is - available in the program and has a string whose contents are to the texs - in the file named `bar`. - - * `--argfile variable-name filename`: - - Do not use. Use `--slurpfile` instead. - - (This option is like `--slurpfile`, but when the file has just - one text, then that is used, else an array of texts is used as - in `--slurpfile`.) - - * `--args`: - - Remaining arguments are positional string arguments. These are - available to the jq program as `$ARGS.positional[]`. - - * `--jsonargs`: - - Remaining arguments are positional JSON text arguments. These - are available to the jq program as `$ARGS.positional[]`. - - * `--run-tests [filename]`: - - Runs the tests in the given file or standard input. This must - be the last option given and does not honor all preceding - options. The input consists of comment lines, empty lines, and - program lines followed by one input line, as many lines of - output as are expected (one per output), and a terminating empty - line. Compilation failure tests start with a line containing - only "%%FAIL", then a line containing the program to compile, - then a line containing an error message to compare to the - actual. - - Be warned that this option can change backwards-incompatibly. - - - title: Basic filters - entries: - - title: "Identity: `.`" - body: | - - The absolute simplest filter is `.` . This is a filter that - takes its input and produces it unchanged as output. That is, - this is the identity operator. - - Since jq by default pretty-prints all output, this trivial - program can be a useful way of formatting JSON output from, - say, `curl`. - - examples: - - program: '.' - input: '"Hello, world!"' - output: ['"Hello, world!"'] - - - title: "Object Identifier-Index: `.foo`, `.foo.bar`" - body: | - - The simplest *useful* filter is `.foo`. When given a - JSON object (aka dictionary or hash) as input, it produces - the value at the key "foo", or null if there's none present. - - A filter of the form `.foo.bar` is equivalent to `.foo|.bar`. - - This syntax only works for simple, identifier-like keys, that - is, keys that are all made of alphanumeric characters and - underscore, and which do not start with a digit. - - If the key contains special characters, you need to surround - it with double quotes like this: `."foo$"`, or else `.["foo$"]`. - - For example `.["foo::bar"]` and `.["foo.bar"]` work while - `.foo::bar` does not, and `.foo.bar` means `.["foo"].["bar"]`. - - examples: - - program: '.foo' - input: '{"foo": 42, "bar": "less interesting data"}' - output: [42] - - program: '.foo' - input: '{"notfoo": true, "alsonotfoo": false}' - output: ['null'] - - program: '.["foo"]' - input: '{"foo": 42}' - output: [42] - - - title: "Optional Object Identifier-Index: `.foo?`" - body: | - - Just like `.foo`, but does not output even an error when `.` - is not an array or an object. - - examples: - - program: '.foo?' - input: '{"foo": 42, "bar": "less interesting data"}' - output: [42] - - program: '.foo?' - input: '{"notfoo": true, "alsonotfoo": false}' - output: ['null'] - - program: '.["foo"]?' - input: '{"foo": 42}' - output: [42] - - program: '[.foo?]' - input: '[1,2]' - output: ['[]'] - - - title: "Generic Object Index: `.[]`" - body: | - - You can also look up fields of an object using syntax like - `.["foo"]` (.foo above is a shorthand version of this, but - only for identifier-like strings). - - - title: "Array Index: `.[2]`" - body: | - - When the index value is an integer, `.[]` can index - arrays. Arrays are zero-based, so `.[2]` returns the third - element. - - Negative indices are allowed, with -1 referring to the last - element, -2 referring to the next to last element, and so on. - - examples: - - program: '.[0]' - input: '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' - output: ['{"name":"JSON", "good":true}'] - - - program: '.[2]' - input: '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' - output: ['null'] - - - program: '.[-2]' - input: '[1,2,3]' - output: ['2'] - - - title: "Array/String Slice: `.[10:15]`" - body: | - - The `.[10:15]` syntax can be used to return a subarray of an - array or substring of a string. The array returned by - `.[10:15]` will be of length 5, containing the elements from - index 10 (inclusive) to index 15 (exclusive). Either index may - be negative (in which case it counts backwards from the end of - the array), or omitted (in which case it refers to the start - or end of the array). - - examples: - - program: '.[2:4]' - input: '["a","b","c","d","e"]' - output: ['["c", "d"]'] - - - program: '.[2:4]' - input: '"abcdefghi"' - output: ['"cd"'] - - - program: '.[:3]' - input: '["a","b","c","d","e"]' - output: ['["a", "b", "c"]'] - - - program: '.[-2:]' - input: '["a","b","c","d","e"]' - output: ['["d", "e"]'] - - - title: "Array/Object Value Iterator: `.[]`" - body: | - - If you use the `.[index]` syntax, but omit the index - entirely, it will return *all* of the elements of an - array. Running `.[]` with the input `[1,2,3]` will produce the - numbers as three separate results, rather than as a single - array. - - You can also use this on an object, and it will return all - the values of the object. - - examples: - - program: '.[]' - input: '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' - output: - - '{"name":"JSON", "good":true}' - - '{"name":"XML", "good":false}' - - - program: '.[]' - input: '[]' - output: [] - - - program: '.[]' - input: '{"a": 1, "b": 1}' - output: ['1', '1'] - - - title: "`.[]?`" - body: | - - Like `.[]`, but no errors will be output if . is not an array - or object. - - - title: "Comma: `,`" - body: | - - If two filters are separated by a comma, then the - same input will be fed into both and the two filters' output - value streams will be concatenated in order: first, all of the - outputs produced by the left expression, and then all of the - outputs produced by the right. For instance, filter `.foo, - .bar`, produces both the "foo" fields and "bar" fields as - separate outputs. - - examples: - - program: '.foo, .bar' - input: '{"foo": 42, "bar": "something else", "baz": true}' - output: ['42', '"something else"'] - - - program: ".user, .projects[]" - input: '{"user":"stedolan", "projects": ["jq", "wikiflow"]}' - output: ['"stedolan"', '"jq"', '"wikiflow"'] - - - program: '.[4,2]' - input: '["a","b","c","d","e"]' - output: ['"e"', '"c"'] - - - title: "Pipe: `|`" - body: | - - The | operator combines two filters by feeding the output(s) of - the one on the left into the input of the one on the right. It's - pretty much the same as the Unix shell's pipe, if you're used to - that. - - If the one on the left produces multiple results, the one on - the right will be run for each of those results. So, the - expression `.[] | .foo` retrieves the "foo" field of each - element of the input array. - - Note that `.a.b.c` is the same as `.a | .b | .c`. - - Note too that `.` is the input value at the particular stage - in a "pipeline", specifically: where the `.` expression appears. - Thus `.a | . | .b` is the same as `.a.b`, as the `.` in the - middle refers to whatever value `.a` produced. - - examples: - - program: '.[] | .name' - input: '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' - output: ['"JSON"', '"XML"'] - - - title: "Parenthesis" - body: | - - Parenthesis work as a grouping operator just as in any typical - programming language. - - examples: - - program: '(. + 2) * 5' - input: '1' - output: [15] - - - title: Types and Values - body: | - - jq supports the same set of datatypes as JSON - numbers, - strings, booleans, arrays, objects (which in JSON-speak are - hashes with only string keys), and "null". - - Booleans, null, strings and numbers are written the same way as - in javascript. Just like everything else in jq, these simple - values take an input and produce an output - `42` is a valid jq - expression that takes an input, ignores it, and returns 42 - instead. - - entries: - - title: "Array construction: `[]`" - body: | - - As in JSON, `[]` is used to construct arrays, as in - `[1,2,3]`. The elements of the arrays can be any jq - expression, including a pipeline. All of the results produced - by all of the expressions are collected into one big array. - You can use it to construct an array out of a known quantity - of values (as in `[.foo, .bar, .baz]`) or to "collect" all the - results of a filter into an array (as in `[.items[].name]`) - - Once you understand the "," operator, you can look at jq's array - syntax in a different light: the expression `[1,2,3]` is not using a - built-in syntax for comma-separated arrays, but is instead applying - the `[]` operator (collect results) to the expression 1,2,3 (which - produces three different results). - - If you have a filter `X` that produces four results, - then the expression `[X]` will produce a single result, an - array of four elements. - - examples: - - program: "[.user, .projects[]]" - input: '{"user":"stedolan", "projects": ["jq", "wikiflow"]}' - output: ['["stedolan", "jq", "wikiflow"]'] - - program: "[ .[] | . * 2]" - input: '[1, 2, 3]' - output: ['[2, 4, 6]'] - - - title: "Object Construction: `{}`" - body: | - - Like JSON, `{}` is for constructing objects (aka - dictionaries or hashes), as in: `{"a": 42, "b": 17}`. - - If the keys are "identifier-like", then the quotes can be left - off, as in `{a:42, b:17}`. Variable references as key - expressions use the value of the variable as the key. Key - expressions other than constant literals, identifiers, or - variable references, need to be parenthesized, e.g., - `{("a"+"b"):59}`. - - The value can be any expression (although you may need to wrap - it in parentheses if, for example, it contains colons), which - gets applied to the {} expression's input (remember, all - filters have an input and an output). - - {foo: .bar} - - will produce the JSON object `{"foo": 42}` if given the JSON - object `{"bar":42, "baz":43}` as its input. You can use this - to select particular fields of an object: if the input is an - object with "user", "title", "id", and "content" fields and - you just want "user" and "title", you can write - - {user: .user, title: .title} - - Because that is so common, there's a shortcut syntax for it: - `{user, title}`. - - If one of the expressions produces multiple results, - multiple dictionaries will be produced. If the input's - - {"user":"stedolan","titles":["JQ Primer", "More JQ"]} - - then the expression - - {user, title: .titles[]} - - will produce two outputs: - - {"user":"stedolan", "title": "JQ Primer"} - {"user":"stedolan", "title": "More JQ"} - - Putting parentheses around the key means it will be evaluated as an - expression. With the same input as above, - - {(.user): .titles} - - produces - - {"stedolan": ["JQ Primer", "More JQ"]} - - Variable references as keys use the value of the variable as - the key. Without a value then the variable's name becomes the - key and its value becomes the value, - - "f o o" as $foo | "b a r" as $bar | {$foo, $bar:$foo} - - produces - - {"f o o":"f o o","b a r":"f o o"} - - examples: - - program: '{user, title: .titles[]}' - input: '{"user":"stedolan","titles":["JQ Primer", "More JQ"]}' - output: - - '{"user":"stedolan", "title": "JQ Primer"}' - - '{"user":"stedolan", "title": "More JQ"}' - - program: '{(.user): .titles}' - input: '{"user":"stedolan","titles":["JQ Primer", "More JQ"]}' - output: ['{"stedolan": ["JQ Primer", "More JQ"]}'] - - - title: "Recursive Descent: `..`" - body: | - - Recursively descends `.`, producing every value. This is the - same as the zero-argument `recurse` builtin (see below). This - is intended to resemble the XPath `//` operator. Note that - `..a` does not work; use `..|.a` instead. In the example - below we use `..|.a?` to find all the values of object keys - "a" in any object found "below" `.`. - - This is particularly useful in conjunction with `path(EXP)` - (also see below) and the `?` operator. - -