]> granicus.if.org Git - jq/commitdiff
Remove ruby dependency from website build
authorWilliam Langford <wlangfor@gmail.com>
Thu, 21 Feb 2019 01:50:08 +0000 (20:50 -0500)
committerWilliam Langford <wlangfor@gmail.com>
Sat, 23 Feb 2019 00:32:31 +0000 (19:32 -0500)
24 files changed:
Makefile.am
configure.ac
docs/.gitignore
docs/Pipfile [new file with mode: 0644]
docs/Pipfile.lock [new file with mode: 0644]
docs/README.md
docs/build_manpage.py [new file with mode: 0644]
docs/build_website.py [new file with mode: 0755]
docs/content/download/default.yml [moved from docs/content/2.download/default.yml with 94% similarity]
docs/content/index.yml [moved from docs/content/index/index.yml with 100% similarity]
docs/content/manual/manual.yml [moved from docs/content/3.manual/manual.yml with 99% similarity]
docs/content/manual/v1.3/manual.yml [moved from docs/content/3.manual/v1.3/manual.yml with 98% similarity]
docs/content/manual/v1.4/manual.yml [moved from docs/content/3.manual/v1.4/manual.yml with 100% similarity]
docs/content/manual/v1.5/manual.yml [moved from docs/content/3.manual/v1.5/manual.yml with 100% similarity]
docs/content/manual/v1.6/manual.yml [moved from docs/content/3.manual/v1.6/manual.yml with 100% similarity]
docs/content/tutorial/default.yml [moved from docs/content/1.tutorial/default.yml with 100% similarity]
docs/public/css/base.css [new file with mode: 0644]
docs/templates/default.html.j2 [moved from docs/templates/default.liquid with 60% similarity]
docs/templates/index.html.j2 [moved from docs/templates/index.liquid with 90% similarity]
docs/templates/manual.html.j2 [moved from docs/templates/manual.liquid with 75% similarity]
docs/templates/shared/_footer.html.j2 [moved from docs/templates/shared/_footer.liquid with 77% similarity]
docs/templates/shared/_head.html.j2 [moved from docs/templates/shared/_head.liquid with 84% similarity]
docs/templates/shared/_navbar.html.j2 [moved from docs/templates/shared/_navbar.liquid with 87% similarity]
scripts/update-website

index e1083fe765aa5336c935d5f7f3e9aa1e643854a6..9f2de43566cd331d05be94418e35ed0078dec45f 100644 (file)
@@ -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
 
 
 
index 97f4eab47ce147ae29a4be2b5afe0b9906fc73a9..e8c6a71e8318ba832481d8e4f492e2d51ce6109c 100644 (file)
@@ -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 <<EOF
 *****************************************************************
-*  Ruby dependencies for building jq documentation not found.   *
+*  Python dependencies for building jq documentation not found. *
 *  You can still build, install and hack on jq, but the manpage *
 *  will not be rebuilt and some of the tests will not run.      *
 *  See docs/README.md for how to install the docs dependencies. *
 *****************************************************************
 EOF
-           jq_cv_ruby_deps=no
+           jq_cv_python_deps=no
      ])])
 
-   if test "x$jq_cv_ruby_deps" != "xyes"; then
+   if test "x$jq_cv_python_deps" != "xyes"; then
      enable_docs=no
    fi
 ])
index 4e01195c428a54eeb021e5567f292c315fac0460..72c4f7cb6dc18e827b72cffff831f31229c9dacc 100644 (file)
@@ -1,6 +1,3 @@
 .DS_Store
 .sass-cache
 output/*
-
-# Autogenerated from public/css/base.scss
-public/css/base.css
\ No newline at end of file
diff --git a/docs/Pipfile b/docs/Pipfile
new file mode 100644 (file)
index 0000000..e68cfbb
--- /dev/null
@@ -0,0 +1,11 @@
+[[source]]
+name = "pypi"
+url = "https://pypi.org/simple"
+verify_ssl = true
+
+[dev-packages]
+
+[packages]
+jinja2 = "*"
+pyyaml = "*"
+markdown = "*"
\ No newline at end of file
diff --git a/docs/Pipfile.lock b/docs/Pipfile.lock
new file mode 100644 (file)
index 0000000..33ff75b
--- /dev/null
@@ -0,0 +1,85 @@
+{
+    "_meta": {
+        "hash": {
+            "sha256": "6cffc39e0d43a6d7c78f39636c7ed1b047f7b819b158213a96d7cbfefd6524d7"
+        },
+        "pipfile-spec": 6,
+        "requires": {},
+        "sources": [
+            {
+                "name": "pypi",
+                "url": "https://pypi.org/simple",
+                "verify_ssl": true
+            }
+        ]
+    },
+    "default": {
+        "jinja2": {
+            "hashes": [
+                "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
+                "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
+            ],
+            "index": "pypi",
+            "version": "==2.10"
+        },
+        "markdown": {
+            "hashes": [
+                "sha256:c00429bd503a47ec88d5e30a751e147dcb4c6889663cd3e2ba0afe858e009baa",
+                "sha256:d02e0f9b04c500cde6637c11ad7c72671f359b87b9fe924b2383649d8841db7c"
+            ],
+            "index": "pypi",
+            "version": "==3.0.1"
+        },
+        "markupsafe": {
+            "hashes": [
+                "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
+                "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
+                "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
+                "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
+                "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
+                "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
+                "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
+                "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
+                "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
+                "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
+                "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
+                "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
+                "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
+                "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
+                "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
+                "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
+                "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
+                "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
+                "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
+                "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
+                "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
+                "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
+                "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
+                "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
+                "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
+                "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
+                "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
+                "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
+            ],
+            "version": "==1.1.0"
+        },
+        "pyyaml": {
+            "hashes": [
+                "sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b",
+                "sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf",
+                "sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a",
+                "sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3",
+                "sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1",
+                "sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1",
+                "sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613",
+                "sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04",
+                "sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f",
+                "sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537",
+                "sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531"
+            ],
+            "index": "pypi",
+            "version": "==3.13"
+        }
+    },
+    "develop": {}
+}
index a09779b9842179de5de9ffc1f8340981a2c6a341..de6bf5a1e6fe25e373575995fcb1ff0647965490 100644 (file)
@@ -2,24 +2,19 @@ Documentation
 =============
 
 The jq website, manpages and some of the tests are generated from this
-directory. The directory holds a [Bonsai](http://tinytree.info)
-website, and the manual is a YAML file in `content/3.manual`.
+directory. The manual is a YAML file in `content/manual`.
 
 To build the documentation (including building the jq manpage), you'll
-need a working Ruby setup. The easiest way to get one is to install
-RVM and Ruby 1.9.3 like so:
+need python3 and pipenv. You can install pipenv like so:
 
-    \curl -L https://get.rvm.io | bash -s stable --ruby=1.9.3
+    pip install pipenv
 
-After that finishes installing, you'll need to make sure RVM is on
-your path by doing `source $HOME/.rvm/scripts/rvm`, or just opening a
-new shell. See <https://rvm.io> 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 (file)
index 0000000..ab73048
--- /dev/null
@@ -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 (executable)
index 0000000..2dd2703
--- /dev/null
@@ -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"</?p>", '', 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)
similarity index 94%
rename from docs/content/2.download/default.yml
rename to docs/content/download/default.yml
index 2cf7d1256ea6b67cfb60fe56348fe38e5dd317b7..cfea1f092ff77d222c1e7c4f2e4d6678981b6c71 100644 (file)
@@ -180,14 +180,13 @@ body:
 
       #### 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`.
+      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,
+      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
+      the YAML docs, and you'll still need the Python dependencies to
       build the manpage.
 
similarity index 99%
rename from docs/content/3.manual/manual.yml
rename to docs/content/manual/manual.yml
index 150565b45b1cb056ba53f071e225cf6891439d59..a9d2fcd258b68410a90528ac543f43e9dbb27ccf 100644 (file)
@@ -2230,6 +2230,7 @@ sections:
           STRING | FILTER( [REGEX, FLAGS] )
 
       where:
+
       * STRING, REGEX and FLAGS are jq strings and subject to jq string interpolation;
       * REGEX, after string interpolation, should be a valid PCRE regex;
       * FILTER is one of `test`, `match`, or `capture`, as described below.
similarity index 98%
rename from docs/content/3.manual/v1.3/manual.yml
rename to docs/content/manual/v1.3/manual.yml
index 08603207630a7be1fcf6d7a8452e4bbf53b27cb8..4153baec4be7bcc54110e592cfeb859bc90e9b52 100644 (file)
@@ -441,7 +441,7 @@ sections:
             input: 5
             output: [6]
 
-      - title: `length`
+      - title: '`length`'
         body: |
 
           The builtin function `length` gets the length of various
@@ -462,7 +462,7 @@ sections:
             input: '[[1,2], "string", {"a":2}, null]'
             output: [2, 6, 1, 0]
 
-      - title: `keys`
+      - title: '`keys`'
         body: |
 
           The builtin function `keys`, when given an object, returns
@@ -485,7 +485,7 @@ sections:
             input: '[42,3,35]'
             output: ['[0,1,2]']
 
-      - title: `has`
+      - title: '`has`'
         body: |
 
           The builtin function `has` returns whether the input object
@@ -504,7 +504,7 @@ sections:
             input: '[[0,1], ["a","b","c"]]'
             output: ['[false, true]']
 
-      - title: `to_entries`, `from_entries`, `with_entries`
+      - title: '`to_entries`, `from_entries`, `with_entries`'
         body: |
 
           These functions convert between an object and an array of
@@ -529,14 +529,14 @@ sections:
             output: ['{"KEY_a": 1, "KEY_b": 2}']
 
 
-      - title: `select`
+      - title: '`select`'
         body: |
 
           The function `select(foo)` produces its input unchanged if
           `foo` returns true for that input, and produces no output
           otherwise.
 
-          It's useful for filtering lists: `[1,2,3] | map(select(. >= 2))`
+          It's useful for filtering lists: '`[1,2,3] | map(select(. >= 2))`'
           will give you `[3]`.
 
         examples:
@@ -544,7 +544,7 @@ sections:
             input: '[1,5,3,0,7]'
             output: ['[5,3,7]']
 
-      - title: `empty`
+      - title: '`empty`'
         body: |
 
           `empty` returns no results. None at all. Not even `null`.
@@ -559,7 +559,7 @@ sections:
             input: 'null'
             output: ['[1,2,3]']
 
-      - title: `map(x)`
+      - title: '`map(x)`'
         body: |
 
           For any filter `x`, `map(x)` will run that filter for each
@@ -574,7 +574,7 @@ sections:
             input: '[1,2,3]'
             output: ['[2,3,4]']
 
-      - title: `add`
+      - title: '`add`'
         body: |
 
           The filter `add` takes as input an array, and produces as
@@ -596,7 +596,7 @@ sections:
             input: '[]'
             output: ["null"]
 
-      - title: `range`
+      - title: '`range`'
         body: |
 
           The `range` function produces a range of numbers. `range(4;10)`
@@ -612,7 +612,7 @@ sections:
             input: 'null'
             output: ['[2,3]']
 
-      - title: `tonumber`
+      - title: '`tonumber`'
         body: |
 
           The `tonumber` function parses its input as a number. It
@@ -624,7 +624,7 @@ sections:
             input: '[1, "1"]'
             output: [1, 1]
 
-      - title: `tostring`
+      - title: '`tostring`'
         body: |
 
           The `tostring` function prints its input as a
@@ -636,7 +636,7 @@ sections:
             input: '[1, "1", [1]]'
             output: ['"1"', '"1"', '"[1]"']
 
-      - title: `type`
+      - title: '`type`'
         body: |
 
           The `type` function returns the type of its argument as a
@@ -648,7 +648,7 @@ sections:
             input: '[0, false, [], {}, null, "hello"]'
             output: ['["number", "boolean", "array", "object", "null", "string"]']
 
-      - title: `sort, sort_by`
+      - title: '`sort, sort_by`'
         body: |
 
           The `sort` functions sorts its input, which must be an
@@ -680,7 +680,7 @@ sections:
             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`
+      - title: '`group_by`'
         body: |
 
           `group_by(.foo)` takes as input an array, groups the
@@ -697,7 +697,7 @@ sections:
             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`
+      - title: '`min`, `max`, `min_by`, `max_by`'
         body: |
 
           Find the minimum or maximum element of the input array. The
@@ -713,7 +713,7 @@ sections:
             input: '[{"foo":1, "bar":14}, {"foo":2, "bar":3}]'
             output: ['{"foo":2, "bar":3}']
 
-      - title: `unique`
+      - title: '`unique`'
         body: |
 
           The `unique` function takes as input an array and produces
@@ -725,7 +725,7 @@ sections:
             input: '[1,2,5,3,5,3,1,3]'
             output: ['[1,2,3,5]']
 
-      - title: `reverse`
+      - title: '`reverse`'
         body: |
 
           This function reverses an array.
@@ -735,7 +735,7 @@ sections:
             input: '[1,2,3,4]'
             output: ['[4,3,2,1]']
 
-      - title: `contains`
+      - title: '`contains`'
         body: |
 
           The filter `contains(b)` will produce true if b is
@@ -764,7 +764,7 @@ sections:
             input: '{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}'
             output: ['false']
 
-      - title: `recurse`
+      - title: '`recurse`'
         body: |
 
           The `recurse` function allows you to search through a
@@ -796,7 +796,7 @@ sections:
               - '{"foo":[]}'
 
 
-      - title: "String interpolation - `\(foo)`"
+      - title: String interpolation - `\(foo)`
         body: |
 
           Inside a string, you can put an expression inside parens
@@ -882,7 +882,7 @@ sections:
 
   - title: Conditionals and Comparisons
     entries:
-      - title: `==`, `!=`
+      - title: '`==`, `!=`'
         body: |
 
           The expression 'a == b' will produce 'true' if the result of a and b
@@ -931,7 +931,7 @@ sections:
             input: 2
             output: ['"many"']
 
-      - title: `>, >=, <=, <`
+      - title: '`>, >=, <=, <`'
         body: |
 
           The comparison operators `>`, `>=`, `<=`, `<` return whether
diff --git a/docs/public/css/base.css b/docs/public/css/base.css
new file mode 100644 (file)
index 0000000..e9bb818
--- /dev/null
@@ -0,0 +1,173 @@
+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;
+}
similarity index 60%
rename from docs/templates/default.liquid
rename to docs/templates/default.html.j2
index 16b42278c69e78ec8a7636362eb1df76a5f5d8d0..7830eb37268baaca8fb99cd76d4fa3009b2cf831 100644 (file)
@@ -1,26 +1,26 @@
 <!DOCTYPE html>
 <html lang="en">
-{% include "shared/head" %}
+{% include "shared/_head.html.j2" %}
 
   <body id="{{slug}}">
-{% include "shared/navbar" %}
+{% 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 }}
+            {{ item.text | replace('$JQ_VERSION', jq_version) | markdownify }}
           {% endif %}
 
           {% if item.command %}
-            {% capture resultID %}{{ "result" | unique}}{% endcapture %}
+            {% set resultID = unique_id() %}
             <div class="tutorial-example">
               <div class="accordion-heading">
                 <pre>{{item.command}}</pre>
-                <a data-toggle="collapse" href="#{{resultID}}">Show result</a>
+                <a data-toggle="collapse" href="#result{{resultID}}">Show result</a>
               </div>
-              <div id="{{resultID}}" class="accordion-body collapse">
+              <div id="result{{resultID}}" class="accordion-body collapse">
                 <pre>{{item.result}}</pre>
               </div>
             </div>
@@ -29,6 +29,6 @@
       </div>
     </div>
 
-{% include "shared/footer" %}
+{% include "shared/_footer.html.j2" %}
   </body>
 </html>
similarity index 90%
rename from docs/templates/index.liquid
rename to docs/templates/index.html.j2
index 35986d59b5139b01c4e5f7e65e798f91883e8f96..4567ef5538509f15d643af5b0f80f1741c609c62 100644 (file)
@@ -1,9 +1,9 @@
 <!DOCTYPE html>
 <html lang="en">
-{% include "shared/head" %}
+{% include "shared/_head.html.j2" %}
 
-  <body id="{{slug}}">
-{% include "shared/navbar" %}
+  <body id="{{ slug }}">
+{% include "shared/_navbar.html.j2" %}
 
     <div class="container">
       <div class="row">
@@ -27,7 +27,7 @@
                       <li><a href="https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64">Linux (64-bit)</a></li>
                       <li><a href="https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64">OS X (64-bit)</a></li>
                       <li><a href="https://github.com/stedolan/jq/releases/download/jq-1.6/jq-win64.exe">Windows (64-bit)</a></li>
-                      <li><a href="/jq/download/">Other platforms, older versions, and source</a></li>
+                      <li><a href="{{root}}/download/">Other platforms, older versions, and source</a></li>
                     </ul>
                   </div>
 
@@ -68,6 +68,6 @@
       </div>
     </div>
 
-{% include "shared/footer" %}
+{% include "shared/_footer.html.j2" %}
   </body>
 </html>
similarity index 75%
rename from docs/templates/manual.liquid
rename to docs/templates/manual.html.j2
index f1d7985a55c7f0767c6e21b055ca97d395da66c3..21f9ad28e2b1ed3d16de67b4e1d4b96501595cbf 100644 (file)
@@ -1,9 +1,9 @@
 <!DOCTYPE html>
 <html lang="en">
-{% include "shared/head" %}
+{% include "shared/_head.html.j2" %}
 
   <body id="{{slug}}" data-spy="scroll" data-target="#navcolumn" data-offset="100">
-{% include "shared/navbar" %}
+{% include "shared/_navbar.html.j2" %}
 
     <div class="container">
       <div class="row">
           {% for section in sections %}
             <section id="{{section.title | section_id}}">
               <h2>{{section.title}}</h2>
-              {{section.body | markdownify}}
+              {{ (section.body | markdownify) if section.body }}
               {% for entry in section.entries %}
                 <section id="{{entry.title | entry_id}}">
                   <h3>
-                    {{entry.title | markdownify | no_paragraph}}
+                    {{entry.title | markdownify | no_paragraph }}
                     {% if entry.subtitle %}<small>{{entry.subtitle}}</small>{% endif %}
                   </h3>
                   {{entry.body | markdownify}}
 
                   {% if entry.examples %}
                     <div>
-                      {% capture exampleID %}{{ "" | unique }}{% endcapture %}
+                      {% set exampleID = unique_id() %}
                       <a data-toggle="collapse" href="#example{{exampleID}}">
                         <i class="glyphicon glyphicon-chevron-right"></i>
-                        {% if entry.examples[1] %}Examples{%else%}Example{%endif%}
+                        {% if entry.examples | length > 1 %}Examples{%else%}Example{%endif%}
                       </a>
                       <div id="example{{exampleID}}" class="manual-example collapse">
                         {% for example in entry.examples %}
                           <table>
-                            <tr><th></th><td class="jqprogram">jq '{{example.program | escape}}'</td></tr>
-                            <tr><th>Input</th><td>{{example.input | escape}}</td></tr>
-                            {% unless example.output[0] %}
+                            <tr><th></th><td class="jqprogram">jq '{{ example.program }}'</td></tr>
+                            <tr><th>Input</th><td>{{ example.input }}</td></tr>
+                            {% if not example.output[0] %}
                               <tr>
                                 <th>Output</th>
                                 <td><i>none</i></td>
                               </tr>
-                            {% endunless %}
+                            {% endif %}
                             {% for output in example.output %}
                               <tr>
-                                {% if forloop.index == 1 %}
+                                {% if loop.first %}
                                   <th>Output</th>
                                 {% else %}
                                   <th></th>
                                 {% endif %}
-                                <td>{{output | escape}}</td>
+                                <td>{{ output }}</td>
                               </tr>
                             {% endfor %}
                           </table>
       </div>
     </div>
 
-{% include "shared/footer" %}
+{% include "shared/_footer.html.j2" %}
     <script>
       var section_map = {
         {% for section in sections %}
           {% for entry in section.entries %}
-            {{entry.title | search_id | json}} : {{entry.title | entry_id | json}},
+            {{entry.title | search_id | tojson }} : {{entry.title | entry_id | tojson }},
           {% endfor %}
-          {{section.title | search_id | json}} : {{section.title | section_id | json}}
-          {% unless forloop.last %},{% endunless %}
+          {{section.title | search_id | tojson }} : {{section.title | section_id | tojson }}
+          {% if not loop.last %},{% endif %}
         {% endfor %}
       };
     </script>
similarity index 77%
rename from docs/templates/shared/_footer.liquid
rename to docs/templates/shared/_footer.html.j2
index 41202da8d5ecd90119663a110b9cfb4cb911c7b9..511f0b1facebb3cde75d623692a21e211e12dc79 100644 (file)
@@ -1,6 +1,6 @@
     <footer>
       <div class="container">
-        <p>This website is made with <a href="http://www.tinytree.info">Bonsai</a> and <a href="http://getbootstrap.com">Bootstrap</a>, themed with <a href="https://bootswatch.com">Bootswatch</a>.</p>
+        <p>This website is made with <a href="http://getbootstrap.com">Bootstrap</a>, themed with <a href="https://bootswatch.com">Bootswatch</a>.</p>
         <p>jq is licensed under the MIT license (code) and the <a href="https://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a> license (docs).</p>
       </div>
     </footer>
similarity index 84%
rename from docs/templates/shared/_head.liquid
rename to docs/templates/shared/_head.html.j2
index b1457aa996c8164bc5b33bfe9a65343b94c333fc..b6fafd35253cdc8965864bbf20f514095415cdc0 100644 (file)
@@ -7,9 +7,9 @@
     <title>{{headline}}</title>
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
-    <link rel="canonical" href="{{url}}{{permalink | remove:'/index'}}" />
+    <link rel="canonical" href="{{ url }}{{ permalink | replace('/index','') }}" />
     <link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.5/spacelab/bootstrap.min.css" rel="stylesheet" integrity="sha256-j7Dtnd7ZjexEiPNbscbopFn9+Cs0b3TLipKsWAPHZIM= sha512-RFhfi6P8zWMAJrEGU+CPjuxPh3r/UUBGqQ+/o6WKPIVZmQqeOipGotH2ihRULuQ8wsMBoK15TSZqc/7VYWyuIw==" crossorigin="anonymous">
-    <link rel="stylesheet" href="{{root}}/css/base.css" type="text/css">
+    <link rel="stylesheet" href="{{ root }}/css/base.css" type="text/css">
     <!--[if lt IE 9]>
       <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
       <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
similarity index 87%
rename from docs/templates/shared/_navbar.liquid
rename to docs/templates/shared/_navbar.html.j2
index d68063b4c89a290035ffd3fa769682ab6943f642..3fa5f14cadce4b01c904dbc64d9987aaba2d1368 100644 (file)
@@ -13,8 +13,8 @@
         <div class="navbar-collapse collapse" id="nav-collapse">
           <ul class="nav navbar-nav">
             {% for item in navigation %}
-              <li {% if item.permalink == permalink %} class="active" {% endif %}>
-                <a href="{{root}}{{item.permalink}}">{{item.name}}</a>
+              <li {% if item == permalink %} class="active" {% endif %}>
+                <a href="{{root}}/{{item}}">{{item | capitalize}}</a>
               </li>
             {% endfor %}
             <li><a href="https://github.com/stedolan/jq/issues">Issues</a></li>
index c466ae7367327deb4634920a3e4326ce607b869e..cf9a0ec1ecf7f7d397e439e7dab3f4d97774c48e 100755 (executable)
@@ -11,7 +11,7 @@ set -o xtrace
 scriptdir=`dirname "$0"`
 cd "$scriptdir"/../docs
 rm -rf output
-rake build
+pipenv run python3 build_website.py
 cd ..
 
 # copy to /tmp