summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/Gemfile5
-rw-r--r--docs/Gemfile.lock53
-rw-r--r--docs/Rakefile55
-rw-r--r--docs/content/2.download/default.yml78
-rwxr-xr-xdocs/content/2.download/linux_x86_64/jqbin385542 -> 0 bytes
-rwxr-xr-xdocs/content/2.download/osx_64/jqbin190556 -> 0 bytes
-rw-r--r--docs/content/3.manual/manual.yml407
-rw-r--r--docs/site.yml4
-rw-r--r--docs/templates/index.liquid4
9 files changed, 501 insertions, 105 deletions
diff --git a/docs/Gemfile b/docs/Gemfile
new file mode 100644
index 00000000..f06950f6
--- /dev/null
+++ b/docs/Gemfile
@@ -0,0 +1,5 @@
+source :rubygems
+
+gem "bonsai"
+gem "maruku"
+gem "ronn"
diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock
new file mode 100644
index 00000000..ccbc84fe
--- /dev/null
+++ b/docs/Gemfile.lock
@@ -0,0 +1,53 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ activesupport (3.2.9)
+ i18n (~> 0.6)
+ multi_json (~> 1.0)
+ addressable (2.3.2)
+ bonsai (1.4.7)
+ activesupport (>= 3.0.3)
+ builder (>= 3.0.0)
+ i18n (>= 0.5.0)
+ launchy (>= 0.3.7)
+ liquid (>= 2.2.2)
+ maruku (>= 0.6.0)
+ rack
+ sass
+ sinatra (>= 1.0)
+ tilt (>= 1.3)
+ watch (>= 0.1.0)
+ builder (3.1.4)
+ hpricot (0.8.6)
+ i18n (0.6.1)
+ launchy (2.1.2)
+ addressable (~> 2.3)
+ liquid (2.4.1)
+ maruku (0.6.1)
+ syntax (>= 1.0.0)
+ multi_json (1.5.0)
+ mustache (0.99.4)
+ rack (1.4.1)
+ rack-protection (1.3.2)
+ rack
+ rdiscount (1.6.8)
+ ronn (0.7.3)
+ hpricot (>= 0.8.2)
+ mustache (>= 0.7.0)
+ rdiscount (>= 1.5.8)
+ sass (3.2.3)
+ sinatra (1.3.3)
+ rack (~> 1.3, >= 1.3.6)
+ rack-protection (~> 1.2)
+ tilt (~> 1.3, >= 1.3.3)
+ syntax (1.0.0)
+ tilt (1.3.3)
+ watch (0.1.0)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ bonsai
+ maruku
+ ronn
diff --git a/docs/Rakefile b/docs/Rakefile
index 62b0139e..a95c97fa 100644
--- a/docs/Rakefile
+++ b/docs/Rakefile
@@ -2,6 +2,8 @@ require 'bonsai'
require 'liquid'
require 'maruku'
require 'json'
+require 'ronn'
+require 'tempfile'
module ExtraFilters
def markdownify(input)
@@ -38,11 +40,13 @@ task :serve do
server = fork {
app = Rack::Builder.app {
- use Bonsai::StaticPassThrough, :root => Bonsai.root_dir + "/output", :urls => ["/"]
+ map "/jq" do
+ use Bonsai::StaticPassThrough, :root => Bonsai.root_dir + "/output", :urls => ["/"]
+ end
run Bonsai::DevelopmentServer
}
Rack::Handler.default.run(app, :Port => 5000) do
- Launchy.open("http://localhost:5000/")
+ Launchy.open("http://localhost:5000/jq")
end
}
Watch.new("{content,templates,public}/**/*") { Bonsai::Exporter.process! }
@@ -57,3 +61,50 @@ task :build do
Bonsai.root_dir = Dir.pwd
Bonsai::Exporter.publish!
end
+
+def load_manual
+ YAML::ENGINE.yamler = 'syck'
+ YAML::load(File.open("content/3.manual/manual.yml"))
+end
+
+task :manpage do
+ Tempfile.open "manpage" do |f|
+ manual = load_manual
+ f.puts manual['manpage_intro']
+ f.puts manual['body']
+ manual['sections'].each do |section|
+
+ f.puts "## #{section['title'].upcase}\n"
+ f.puts section['body']
+ f.puts ""
+ (section['entries'] || []).each do |entry|
+ f.puts "### #{entry['title']}\n"
+ f.puts entry['body']
+ f.puts ""
+ (entry['examples'] || []).each do |example|
+ f.puts " jq '#{example['program']}'"
+ f.puts " #{example['input']}"
+ f.puts " => #{example['output'].join(", ")}"
+ f.puts
+ end
+ end
+ f.puts ""
+ end
+ f.puts manual['manpage_epilogue']
+ f.close
+ puts Ronn::Document.new(f.path).convert('roff').gsub(/<\/?code>/,"")
+ end
+end
+
+task :mantests do
+ load_manual['sections'].each do |section|
+ (section['entries'] || []).each do |entry|
+ (entry['examples'] || []).each do |example|
+ puts example['program'].gsub("\n", " ")
+ puts example['input']
+ example['output'].each do |s| puts s end
+ puts
+ end
+ end
+ end
+end
diff --git a/docs/content/2.download/default.yml b/docs/content/2.download/default.yml
index 7834ce72..502ef0b4 100644
--- a/docs/content/2.download/default.yml
+++ b/docs/content/2.download/default.yml
@@ -5,39 +5,46 @@ body:
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 (64-bit x86) and OS X.
-
- * [Download binary for 64-bit Linux](linux_x86_64/jq)
- * [Download binary for OS X](osx_64/jq)
- (or use [homebrew](http://mxcl.github.com/homebrew/): `brew install jq`)
- * [Download source](source/jq.tgz)
-
- The binaries should just run, but you may need to make them
- executable first using:
-
- chmod +x jq
-
+ 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.
- Arch Linux
- ----------
- A PKGBUILD for jq-1.1 is in the
- [AUR](https://aur.archlinux.org/packages.php?ID=63849), as well as a
- PKGBUILD for the HEAD of master
- ([jq-git](https://aur.archlinux.org/packages.php?ID=63850)).
+ ### Linux
+
+ * Binaries for [64-bit](linux64/jq) or [32-bit](linux32/jq) systems.
+
+ * For Arch users, a PKGBUILD for jq-1.1 is in the
+ [AUR](https://aur.archlinux.org/packages.php?ID=63849), as
+ well as a PKGBUILD for the HEAD of master
+ ([jq-git](https://aur.archlinux.org/packages.php?ID=63850)).
+ You can install them using
+ [Yaourt](https://wiki.archlinux.org/index.php/Yaourt) or
+ manually by following instructions on [Arch Linux's
+ Wiki](https://wiki.archlinux.org/index.php/Arch_UseRepository).
+
+ * Debian/Ubuntu packages are coming Real Soon Now.
+
+ ### OS X
+
+ * `brew install jq` using [homebrew](http://mxcl.github.com/homebrew/)
- You can install jq using [Yaourt](https://wiki.archlinux.org/index.php/Yaourt)
- or manually by following instructions on
- [Arch Linux's Wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository).
+ * Or, grab prebuilt [64-bit binaries](osx64/jq) or [32-bit
+ binaries](osx32/jq)
- Hacking on jq
- =============
+ ### Windows
- If you want to work on jq, grab the source from
- [https://github.com/stedolan/jq](https://github.com/stedolan/jq).
-
+ * Executables for [64-bit](win64/jq.exe) or [32-bit](win32/jq.exe)
+
+ ### From source on Linux or OS X
+
+ git clone https://github.com/stedolan/jq.git
+ cd jq
+ make && sudo make install
To build it from a git clone, you'll need to install a few
packages first:
@@ -48,23 +55,24 @@ body:
* [GCC](http://gcc.gnu.org)
* [Make](http://www.gnu.org/software/make)
- Most of these aren't necessary if you're just trying to compile
- jq from the released tarball - that version has the
- non-platform-specific build steps already done, so you'll only
- need a C compiler and `make` to finish it off.
-
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. I have no idea how to get these
- installed on OS X, you're on your own there.
+ likely already installed.
+
+ On OS X, these are all included in Apple's command line tools, which
+ can be installed from [Xcode](http://developer.apple.com/technologies/tools/).
+ 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://mxcl.github.com/homebrew/)
+ or [MacPorts](http://macports.org/).
`flex` and `bison` are used to generate the lexer and parser for
jq, and some python scripts generate the UTF8 encoding tables
needed for JSON parsing.
- Building the documentation
- --
+ #### 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` from the docs/ subdirectory.
+
+
diff --git a/docs/content/2.download/linux_x86_64/jq b/docs/content/2.download/linux_x86_64/jq
deleted file mode 100755
index 4395acc1..00000000
--- a/docs/content/2.download/linux_x86_64/jq
+++ /dev/null
Binary files differ
diff --git a/docs/content/2.download/osx_64/jq b/docs/content/2.download/osx_64/jq
deleted file mode 100755
index c7b521ec..00000000
--- a/docs/content/2.download/osx_64/jq
+++ /dev/null
Binary files differ
diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml
index 437afdff..de608210 100644
--- a/docs/content/3.manual/manual.yml
+++ b/docs/content/3.manual/manual.yml
@@ -26,6 +26,41 @@ body: |
But that's getting ahead of ourselves. :) Let's start with something
simpler:
+
+manpage_intro: |
+ jq(1) -- Command-line JSON processor
+ ====================================
+
+ ## SYNOPSIS
+
+ `jq` [<options>...] <filter> [<files>...]
+
+ `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.
+
+ By default, `jq` reads a stream of JSON objects (whitespace
+ separated) from `stdin`. One or more <files> may be specified, in
+ which case `jq` will read input from those instead.
+
+ The <options> are described in the [INVOKING JQ] section, they
+ mostly concern input and output formatting. The <filter> is written
+ in the jq language and specifies how to transform the input
+ document.
+
+ ## FILTERS
+
+manpage_epilogue: |
+ ## BUGS
+
+ Presumably. Report them or discuss them at:
+
+ https://github.com/stedolan/jq/issues
+
+ ## AUTHOR
+
+ Stephen Dolan `<mu@netsoc.tcd.ie>`
sections:
- title: Invoking jq
@@ -40,41 +75,47 @@ sections:
You can affect how jq reads and writes its input and output
using some command-line options:
- * `--slurp`/`-s`
-
+ * `--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`
+ * `--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`
-
+
+ * `--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`
-
+
+ * `--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.
-
- * `--ascii-output` / `-a`
-
+
+ * `--colour-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`.
+
+ * `--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.
-
- * `--raw-output` / `-r`
-
+
+ * `--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
@@ -142,7 +183,7 @@ sections:
examples:
- program: '.[]'
- input: '[{name":"JSON", "good":true}, {"name":"XML", "good":false}]'
+ input: '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]'
output:
- '{"name":"JSON", "good":true}'
- '{"name":"XML", "good":false}'
@@ -172,7 +213,7 @@ sections:
- program: '.[4,2]'
input: '["a","b","c","d","e"]'
- output: ['"d"', '"c"']
+ output: ['"e"', '"c"']
- title: "`|`"
body: |
@@ -188,7 +229,7 @@ sections:
examples:
- program: '.[] | .name'
- input: '[{name":"JSON", "good":true}, {"name":"XML", "good":false}]'
+ input: '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]'
output: ['"JSON"', '"XML"']
- title: Types and Values
@@ -315,14 +356,23 @@ sections:
the key-value pairs from both objects into a single
combined object. If both objects contain a value for the
same key, the object on the right of the `+` wins.
+
+ `null` can be added to any value, and returns the other
+ value unchanged.
examples:
- program: '.a + 1'
input: '{"a": 7}'
- output: '{"a": 8}'
+ output: ['8']
- program: '.a + .b'
input: '{"a": [1,2], "b": [3,4]}'
output: ['[1,2,3,4]']
+ - program: '.a + null'
+ input: '{"a": 1}'
+ output: ['1']
+ - program: '.a + 1'
+ input: '{}'
+ output: ['1']
- program: '{a: 1} + {b: 2} + {c: 3} + {a: 42}'
input: 'null'
output: ['{"a": 42, "b": 2, "c": 3}']
@@ -403,11 +453,11 @@ sections:
`foo` returns true for that input, and produces no output
otherwise.
- It's useful for filtering lists: `[1,2,3] | select(. >= 2)`
+ It's useful for filtering lists: `[1,2,3] | map(select(. >= 2))`
will give you `[3]`.
examples:
- - program: 'select(. >= 2)'
+ - program: 'map(select(. >= 2))'
input: '[1,5,3,0,7]'
output: ['[5,3,7]']
@@ -421,7 +471,7 @@ sections:
examples:
- program: '1, empty, 2'
input: 'null'
- output: [1,2]
+ output: [1, 2]
- program: '[1,2,empty,3]'
input: 'null'
output: ['[1,2,3]']
@@ -455,7 +505,7 @@ sections:
examples:
- program: add
input: '["a","b","c"]'
- output: ["abc"]
+ output: ['"abc"']
- program: add
input: '[1, 2, 3]'
output: [6]
@@ -473,7 +523,7 @@ sections:
examples:
- program: '.[] | tonumber'
input: '[1, "1"]'
- output: [1,1]
+ output: [1, 1]
- title: `tostring`
body: |
@@ -487,6 +537,144 @@ sections:
input: '[1, "1", [1]]'
output: ['"1"', '"1"', '"[1]"']
+ - title: `sort, sort_by`
+ body: |
+
+ The `sort` functions sorts its input, which must be an
+ array. Values are sorted in the following order:
+
+ * `null`
+ * `false`
+ * `true`
+ * numbers
+ * strings, in alphabetical order (by unicode codepoint value)
+ * arrays, in lexical order
+ * objects
+
+ The ordering for objects is a little complex: first they're
+ compared by comparing their sets of keys (as arrays in
+ sorted order), and if their keys are equal then the values
+ are compared key by key.
+
+ `sort_by` may be used to sort by a particular field of an
+ object, or by applying any jq filter. `sort_by(foo)`
+ compares two elements by comparing the result of `foo` on
+ each element.
+
+ examples:
+ - program: 'sort'
+ input: '[8,3,null,6]'
+ output: ['[null,3,6,8]']
+ - program: 'sort_by(.foo)'
+ input: '[{"foo":4, "bar":10}, {"foo":3, "bar":100}, {"foo":2, "bar":1}]'
+ output: ['[{"foo":2, "bar":1}, {"foo":3, "bar":100}, {"foo":4, "bar":10}]']
+
+ - title: `group_by`
+ body: |
+
+ `group_by(.foo)` takes as input an array, groups the
+ elements having the same `.foo` field into separate arrays,
+ and produces all of these arrays as elements of a larger
+ array, sorted by the value of the `.foo` field.
+
+ Any jq expression, not just a field access, may be used in
+ place of `.foo`. The sorting order is the same as described
+ in the `sort` function above.
+
+ examples:
+ - program: 'group_by(.foo)'
+ input: '[{"foo":1, "bar":10}, {"foo":3, "bar":100}, {"foo":1, "bar":1}]'
+ output: ['[[{"foo":1, "bar":10}, {"foo":1, "bar":1}], [{"foo":3, "bar":100}]]']
+
+ - title: `min`, `max`, `min_by`, `max_by`
+ body: |
+
+ Find the minimum or maximum element of the input array. The
+ `_by` versions allow you to specify a particular field or
+ property to examine, e.g. `min_by(.foo)` finds the object
+ with the smallest `foo` field.
+
+ examples:
+ - program: 'min'
+ input: '[5,4,2,7]'
+ output: ['2']
+ - program: 'max_by(.foo)'
+ input: '[{"foo":1, "bar":14}, {"foo":2, "bar":3}]'
+ output: ['{"foo":2, "bar":3}']
+
+ - title: `unique`
+ body: |
+
+ The `unique` function takes as input an array and produces
+ an array of the same elements, in sorted order, with
+ duplicates removed.
+
+ examples:
+ - program: 'unique'
+ input: '[1,2,5,3,5,3,1,3]'
+ output: ['[1,2,3,5]']
+
+ - title: `contains`
+ body: |
+
+ The filter `contains(b)` will produce true if b is
+ completely contained within the input. A string B is
+ contained in a string A if B is a substring of A. An array B
+ is contained in an array A is all elements in B are
+ contained in any element in A. An object B is contained in
+ object A if all of the values in B are contained in the
+ value in A with the same key. All other types are assumed to
+ be contained in each other if they are equal.
+
+ examples:
+ - program: 'contains("bar")'
+ input: '"foobar"'
+ output: ['true']
+ - program: 'contains(["baz", "bar"])'
+ input: '["foobar", "foobaz", "blarp"]'
+ output: ['true']
+ - program: 'contains(["bazzzzz", "bar"])'
+ input: '["foobar", "foobaz", "blarp"]'
+ output: ['false']
+ - program: 'contains({foo: 12, bar: [{barp: 12}]})'
+ input: '{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}'
+ output: ['true']
+ - program: 'contains({foo: 12, bar: [{barp: 15}]})'
+ input: '{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}'
+ output: ['false']
+
+ - title: `recurse`
+ body: |
+
+ The `recurse` function allows you to search through a
+ recursive structure, and extract interesting data from all
+ levels. Suppose your input represents a filesystem:
+
+ {"name": "/", "children": [
+ {"name": "/bin", "children": [
+ {"name": "/bin/ls", "children": []},
+ {"name": "/bin/sh", "children": []}]},
+ {"name": "/home", "children": [
+ {"name": "/home/stephen", "children": [
+ {"name": "/home/stephen/jq", "children": []}]}]}]}
+
+ Now suppose you want to extract all of the filenames
+ present. You need to retrieve `.name`, `.children[].name`,
+ `.children[].children[].name`, and so on. You can do this
+ with:
+
+ recurse(.children[]) | .name
+
+ examples:
+ - program: 'recurse(.foo[])'
+ input: '{"foo":[{"foo": []}, {"foo":[{"foo":[]}]}]}'
+ output:
+ - '{"foo":[{"foo":[]},{"foo":[{"foo":[]}]}]}'
+ - '{"foo":[]}'
+ - '{"foo":[{"foo":[]}]}'
+ - '{"foo":[]}'
+
+
- title: "String interpolation - `\(foo)`"
body: |
@@ -499,10 +687,77 @@ sections:
input: '42'
output: ['"The input was 42, which is one less than 43"']
-
+ - title: "Format strings and escaping"
+ body: |
-
+ The `@foo` syntax is used to format and escape strings,
+ which is useful for building URLs, documents in a language
+ like HTML or XML, and so forth. `@foo` can be used as a
+ filter on its own, the possible escapings are:
+
+ * `@text`:
+
+ Calls `tostring`, see that function for details.
+
+ * `@json`:
+
+ Serialises the input as JSON.
+
+ * `@html`:
+
+ Applies HTML/XML escaping, by mapping the characters
+ `<>&'"` to their entity equivalents `&lt;`, `&gt;`,
+ `&amp;`, `&apos;`, `&quot;`.
+
+ * `@uri`:
+
+ Applies percent-encoding, by mapping all reserved URI
+ characters to a `%xx` sequence.
+
+ * `@csv`:
+
+ The input must be an array, and it is rendered as CSV
+ with double quotes for strings, and quotes escaped by
+ repetition.
+
+ * `@sh`:
+
+ The input is escaped suitable for use in a command-line
+ for a POSIX shell. If the input is an array, the output
+ will be a series of space-separated strings.
+
+ * `@base64`:
+
+ The input is converted to base64 as specified by RFC 4648.
+
+ This syntax can be combined with string interpolation in a
+ useful way. You can follow a `@foo` token with a string
+ literal. The contents of the string literal will *not* be
+ escaped. However, all interpolations made inside that string
+ literal will be escaped. For instance,
+ @uri "http://www.google.com/search?q=\(.search)"
+
+ will produce the following output for the input
+ `{"search":"jq!"}`:
+
+ http://www.google.com/search?q=jq%21
+
+ Note that the slashes, question mark, etc. in the URL are
+ not escaped, as they were part of the string literal.
+
+ examples:
+ - program: '@html'
+ input: '"This works if x < y"'
+ output: ['"This works if x &lt; y"']
+
+# - program: '@html "<span>Anonymous said: \(.)</span>"'
+# input: '"<script>alert(\"lol hax\");</script>"'
+# output: ["<span>Anonymous said: &lt;script&gt;alert(&quot;lol hax&quot;);&lt;/script&gt;</span>"]
+
+ - program: '@sh "echo \(.)"'
+ input: "\"O'Hara's Ale\""
+ output: ["\"echo 'O'\\''Hara'\\''s Ale\""]
- title: Conditionals and Comparisons
entries:
@@ -521,34 +776,7 @@ sections:
examples:
- program: '.[] == 1'
input: '[1, 1.0, "1", "banana"]'
- output: ['[true, true, false, false]']
- - title: `contains`
- body: |
-
- The expression 'a contains b' will produce true if b is completely
- contained within a. A string B is contained in a string A if B is a
- substring of A. An array B is contained in an array A is all elements
- in B are contained in any element in A. An object B is contained in
- object A if all of the values in B are contained in the value in A with
- the same key. All other types are assumed to be contained in each other
- if they are equal.
-
- examples:
- - program: '. == contains "bar"'
- input: '"foobar"'
- output: ['true']
- - program: '. contains ["baz", "bar"]'
- input: '["foobar", "foobaz", "blarp"]'
- output: ['true']
- - program: '. contains ["bazzzzz", "bar"]'
- input: '["foobar", "foobaz", "blarp"]'
- output: ['false']
- - program: '. contains {foo: 12, bar: [{barp: 12}]}'
- input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}'
- output: ['true']
- - program: '. contains {foo: 12, bar: [{barp: 15}]}'
- input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}'
- output: ['false']
+ output: ['true', 'true', 'false', 'false']
- title: if-then-else
body: |
@@ -561,8 +789,8 @@ sections:
means that you'll sometimes have to be more explicit about
the condition you want: you can't test whether, e.g. a
string is empty using `if .name then A else B end`, you'll
- need something more like 'if (.name | count) > 0 then A else
- B end' instead.
+ need something more like `if (.name | count) > 0 then A else
+ B end` instead.
If the condition A produces multiple results, it is
considered "true" if any of those results is not false or
@@ -581,6 +809,21 @@ sections:
end
input: 2
output: ['"many"']
+
+ - title: `>, >=, <=, <`
+ body: |
+
+ The comparison operators `>`, `>=`, `<=`, `<` return whether
+ their left argument is greater than, greater than or equal
+ to, less than or equal to or less than their right argument
+ (respectively).
+
+ The ordering is the same as that described for `sort`, above.
+
+ examples:
+ - program: '. < 5'
+ input: 2
+ output: ['true']
- title: and/or/not
body: |
@@ -639,7 +882,7 @@ sections:
input: '{}'
output: [42]
- - title: Variables and Functions
+ - title: Advanced features
body: |
Variables are an absolute necessity in most programming languages, but
they're relegated to an "advanced feature" in jq.
@@ -656,6 +899,10 @@ sections:
(many jq functions such as `map` and `find` are in fact written
in jq).
+ Finally, jq has a `fold` operation, which is very powerful but a
+ bit tricky. Again, it's mostly used internally, to define some
+ useful bits of jq's standard library.
+
entries:
- title: Variables
body: |
@@ -670,8 +917,8 @@ sections:
For instance, calculating the average value of an array of numbers
requires a few variables in most languages - at least one to hold the
array, perhaps one for each element or for a loop counter. In jq, it's
- simply `add / length` - the `sum` expression is given the array and
- produces its sum, and the `count` expression is given the array and
+ simply `add / length` - the `add` expression is given the array and
+ produces its sum, and the `length` expression is given the array and
produces its length.
So, there's generally a cleaner way to solve most problems in jq that
@@ -754,12 +1001,45 @@ sections:
input's `.foo` field to each element of the array.
examples:
- - program: 'def addvalue(f): map(. + [$value]); addvalue(.[0])'
+ - program: 'def addvalue(f): . + [f]; map(addvalue(.[0]))'
input: '[[1,2],[10,20]]'
output: ['[[1,2,1], [10,20,10]]']
- - program: 'def addvalue(f): f as $x | map (. + $x); addvalue(.[0])'
+ - program: 'def addvalue(f): f as $x | map(. + $x); addvalue(.[0])'
input: '[[1,2],[10,20]]'
- output: ['[[1,2,[1,2]], [10,20,[1,2]]]']
+ output: ['[[1,2,1,2], [10,20,1,2]]']
+
+ - title: Fold
+ body: |
+
+ The `fold` syntax in jq allows you to combine all of the
+ results of an expression by accumulating them into a single
+ answer. As an example, we'll pass `[3,2,1]` to this expression:
+
+ fold 0 as $sum (.[] | $sum + .)
+
+ The variable `$sum` is first given the value `0`. The body
+ of the fold (i.e. `.[] | $sum + .`) is evaluated. `.[]`
+ produces three results, `3`, `2`, and `1`. For the first
+ one, `$sum + .` gives `3`.
+
+ Having produced this answer, jq backtracks to find the next
+ result as per usual. However, this time, `$sum` is set to
+ the previous value of the body, so `$sum + .` gives
+ `5`. After the final backtracking, `$sum + .` gives
+ `6`. This final value is used as the value of the entire
+ `fold` expression, so the above filter returns `6`.
+
+ More formally, in order to evaluate `fold INIT as $VAR
+ (BODY)`, jq first sets `$VAR` to the value of `INIT`. It
+ then runs through `BODY`. Each time `BODY` produces a value,
+ `$VAR` is set to that value and jq backtracks to find the
+ next one. When `BODY` stops producing values, the final
+ value of `$VAR` is the result of the entire expression.
+
+ examples:
+ - program: 'fold 0 as $sum (.[] | $sum + .)'
+ input: '[10,2,5,3]'
+ output: ['20']
- title: Assignment
@@ -871,4 +1151,5 @@ sections:
"stedolan" wrote, and we can comment on each of them in the same way
that we did before:
- (.posts[] | select(.author == "stedolan") | .comments) |= . + ["terrible."]
+ (.posts[] | select(.author == "stedolan") | .comments) |=
+ . + ["terrible."]
diff --git a/docs/site.yml b/docs/site.yml
index 92a690d1..863d578d 100644
--- a/docs/site.yml
+++ b/docs/site.yml
@@ -1,10 +1,8 @@
# The key value pairs found below are available within the templates.
-jq_version: 1.1
-# Next line is needed for publishing to github pages
+jq_version: 1.2
root: '/jq'
-# root: ''
footer: |
This website is made with [Bonsai](http://www.tinytree.info) and
diff --git a/docs/templates/index.liquid b/docs/templates/index.liquid
index aaff1c9f..7785526c 100644
--- a/docs/templates/index.liquid
+++ b/docs/templates/index.liquid
@@ -16,8 +16,8 @@
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
- <li><a href="{{root}}/download/linux_x86_64/jq">Linux (x86_64)</a></li>
- <li><a href="{{root}}/download/osx_64/jq">OS X (64-bit)</a></li>
+ <li><a href="{{root}}/download/linux64/jq">Linux (64-bit)</a></li>
+ <li><a href="{{root}}/download/osx64/jq">OS X (64-bit)</a></li>
<li><a href="{{root}}/download">Other platforms and source</a></li>
</ul>
</div>