[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: xwmx\ncustom: https://paypal.me/WilliamMelody\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  push:\n    tags:\n      - \"[0-9]+.[0-9]+.[0-9]+*\"\n\njobs:\n  release:\n    name: Release\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code # to upload release assets\n        uses: actions/checkout@v4\n      - id: major_version\n        run: >\n          echo major_version=$(\n            echo ${{ github.ref }} | cut -d'v' -f2 | cut -d'.' -f1\n          ) >> $GITHUB_OUTPUT\n      - id: is_release_candidate\n        run: >\n          echo is_release_candidate=$(\n            echo ${{ github.ref }} | grep -c 'rc'\n          ) >> $GITHUB_OUTPUT\n      - name: Create release\n        uses: softprops/action-gh-release@v2\n        with:\n          prerelease: ${{ steps.major_version.outputs.major_version == 0 || steps.is_release_candidate.outputs.is_release_candidate == 1 }}\n          generate_release_notes: true\n          files: nb\n"
  },
  {
    "path": ".github/workflows/tests.yml",
    "content": "###############################################################################\n# .github/workflows/tests.yml\n#\n# NOTE: GitHub Actions does not allocate a TTY, preventing `nb` from detecting\n# piped input using `[[ -t 0 ]]` in the `_interactive_input()` function.\n#\n# More information:\n#\n# https://github.com/actions/runner/issues/241\n#\n# faketty is a GitHub action that uses work-arounds to provide a tty:\n#\n# https://github.com/marketplace/actions/faketty\n#\n# Scripts used by faketty for each platform:\n#\n# linux: `faketty`\n#\n# ```bash\n# #!/bin/bash\n#\n# script -q -e -c \"$*\"\n# ```\n#\n# win32: `faketty.ps1`\n#\n# ```posh\n# Invoke-Expression \"$args\"\n# ```\n#\n# darwin: `faketty`\n#\n# requires: `brew install expect`\n#\n# ```bash\n# #!/bin/bash\n#\n# unbuffer $*\n# ```\n###############################################################################\n\nname: \"nb · Test Suite\"\n\non:\n  pull_request:\n    branches: [ master ]\n  # push:\n  #   branches: [ master ]\n  workflow_dispatch:\n\njobs:\n  # test-ubuntu-aarch64:\n  #   name: \"Test: Ubuntu AArch64\"\n  #   runs-on: ubuntu-20.04\n  #   steps:\n  #     - uses: actions/checkout@v2.1.0\n  #     - uses: uraimo/run-on-arch-action@v2\n  #       # https://github.com/marketplace/actions/run-on-architecture\n  #       name: Run commands\n  #       id: runcmd\n  #       with:\n  #         arch:   aarch64\n  #         distro: ubuntu20.04\n\n  #         # Not required, but speeds up builds by storing container images in\n  #         # a GitHub package registry.\n  #         # githubToken: ${{ github.token }}\n\n  #         # Set an output parameter `uname` for use in subsequent steps\n  #         run: |\n  #           uname -a\n  #           echo ::set-output name=uname::$(uname -a)\n  #     - name: \"Setup\"\n  #       run: |\n  #         sudo apt-get update\n  #         sudo apt-get install bats -y\n  #         sudo apt-get install ncat -y\n  #         sudo apt-get install python-pygments -y\n  #         sudo apt-get install w3m  -y\n  #         curl -LO https://github.com/jgm/pandoc/releases/download/2.17.0.1/pandoc-2.17.0.1-1-amd64.deb\n  #         sudo dpkg -i pandoc-2.17.0.1-1-amd64.deb\n  #         curl -LO https://github.com/sharkdp/bat/releases/download/v0.16.0/bat_0.16.0_amd64.deb\n  #         sudo dpkg -i bat_0.16.0_amd64.deb\n  #         git config --global user.name   \"Example Name\"\n  #         git config --global user.email  \"example@example.com\"\n  #     - name: \"Install bats-core\"\n  #       run: |\n  #         git clone https://github.com/bats-core/bats-core.git \"${HOME}/bats-core\" &&\n  #           cd \"${HOME}/bats-core\"\n  #         git checkout 2e2e5df6adf0b846b411b6b2f7bb654cbc3e2c4e\n  #         sudo ./install.sh /usr/local\n  #     - name: \"Set $TERM=xterm\"\n  #       run:  printf \"TERM=xterm\\\\n\" >> $GITHUB_ENV\n  #     - name: \"Run bats tests\"\n  #       run:  script -q -e -c \"bats test/bookmark.bats\"\n  #     # - name: \"Install Go\"\n  #     #   uses: actions/setup-go@v2\n  #     # - name: \"Run go test\"\n  #     #   run: cd nb.go && go test\n  #     # - name: \"Run nb.go bats tests\"\n  #     #   run:  script -q -e -c \"bats test\"\n\n  # test-ubuntu-armv7:\n  #   name: \"Test: Ubuntu armv7\"\n  #   runs-on: ubuntu-20.04\n  #   steps:\n  #     - uses: actions/checkout@v2.1.0\n  #     - uses: uraimo/run-on-arch-action@v2\n  #       # https://github.com/marketplace/actions/run-on-architecture\n  #       name: Run commands\n  #       id: runcmd\n  #       with:\n  #         arch:   armv7\n  #         distro: ubuntu20.04\n\n  #         # Not required, but speeds up builds by storing container images in\n  #         # a GitHub package registry.\n  #         # githubToken: ${{ github.token }}\n\n  #         # Set an output parameter `uname` for use in subsequent steps\n  #         run: |\n  #           uname -a\n  #           echo ::set-output name=uname::$(uname -a)\n  #     - name: \"Setup\"\n  #       run: |\n  #         sudo apt-get update\n  #         sudo apt-get install bats -y\n  #         sudo apt-get install ncat -y\n  #         sudo apt-get install python-pygments -y\n  #         sudo apt-get install w3m  -y\n  #         curl -LO https://github.com/jgm/pandoc/releases/download/2.17.0.1/pandoc-2.17.0.1-1-amd64.deb\n  #         sudo dpkg -i pandoc-2.17.0.1-1-amd64.deb\n  #         curl -LO https://github.com/sharkdp/bat/releases/download/v0.16.0/bat_0.16.0_amd64.deb\n  #         sudo dpkg -i bat_0.16.0_amd64.deb\n  #         git config --global user.name   \"Example Name\"\n  #         git config --global user.email  \"example@example.com\"\n  #     - name: \"Install bats-core\"\n  #       run: |\n  #         git clone https://github.com/bats-core/bats-core.git \"${HOME}/bats-core\" &&\n  #           cd \"${HOME}/bats-core\"\n  #         git checkout 2e2e5df6adf0b846b411b6b2f7bb654cbc3e2c4e\n  #         sudo ./install.sh /usr/local\n  #     - name: \"Set $TERM=xterm\"\n  #       run:  printf \"TERM=xterm\\\\n\" >> $GITHUB_ENV\n  #     - name: \"Run bats tests\"\n  #       run:  script -q -e -c \"bats test/bookmark.bats\"\n  #     # - name: \"Install Go\"\n  #     #   uses: actions/setup-go@v2\n  #     # - name: \"Run go test\"\n  #     #   run: cd nb.go && go test\n  #     # - name: \"Run nb.go bats tests\"\n  #     #   run:  script -q -e -c \"bats test\"\n\n  test-macos-14:\n    name: \"Test: macOS 14 Sonoma\"\n    runs-on: macos-14\n    steps:\n      - uses: actions/checkout@v4\n      - name: \"Setup\"\n        run: |\n          brew update\n          brew install bat\n          brew install bats-core\n          brew install expect\n          brew install gpg\n          brew install nmap\n          brew install pandoc\n          brew install ripgrep\n          brew install w3m\n          gem install asciidoctor\n          git config --global user.name   \"Example Name\"\n          git config --global user.email  \"example@example.com\"\n      - uses: browser-actions/setup-chrome@v1\n        id: setup-chrome\n      - run: |\n          ${{ steps.setup-chrome.outputs.chrome-path }} --version\n      - name: \"Set $TERM=xterm\"\n        run:  printf \"TERM=xterm\\\\n\" >> $GITHUB_ENV\n      - name: \"Run bats tests\"\n        run:  unbuffer bats test\n      # - name: \"Install Go\"\n      #   uses: actions/setup-go@v2\n      # - name: \"Run go test\"\n      #   run: cd nb.go && go test\n      # - name: \"Run nb.go bats test\"\n      #   run: unbuffer bats test\n  # test-macos-12:\n  #   name: \"Test: macOS 12 Monterey\"\n  #   runs-on: macos-12\n  #   steps:\n  #     - uses: actions/checkout@v3\n  #     - name: \"Setup\"\n  #       run: |\n  #         brew update\n  #         brew install bat\n  #         brew install bats-core\n  #         brew install expect\n  #         brew install gpg\n  #         brew install nmap\n  #         brew install pandoc\n  #         brew install ripgrep\n  #         brew install w3m\n  #         gem install asciidoctor\n  #         git config --global user.name   \"Example Name\"\n  #         git config --global user.email  \"example@example.com\"\n  #     - uses: browser-actions/setup-chrome@v1\n  #       id: setup-chrome\n  #     - run: |\n  #         ${{ steps.setup-chrome.outputs.chrome-path }} --version\n  #     - name: \"Set $TERM=xterm\"\n  #       run:  printf \"TERM=xterm\\\\n\" >> $GITHUB_ENV\n  #     - name: \"Run bats tests\"\n  #       run:  unbuffer bats test\n  #     # - name: \"Install Go\"\n  #     #   uses: actions/setup-go@v2\n  #     # - name: \"Run go test\"\n  #     #   run: cd nb.go && go test\n  #     # - name: \"Run nb.go bats test\"\n  #     #   run: unbuffer bats test\n  # test-macos-11:\n  #   name: \"Test: macOS Big Sur 11.0\"\n  #   runs-on: macos-11.0\n  #   steps:\n  #     - uses: actions/checkout@v3\n  #     - name: \"Setup\"\n  #       run: |\n  #         brew update\n  #         brew install bat\n  #         brew install bats-core\n  #         brew install expect\n  #         brew install gpg\n  #         brew install nmap\n  #         brew install pandoc\n  #         brew install ripgrep\n  #         brew install w3m\n  #         gem install asciidoctor\n  #         git config --global user.name   \"Example Name\"\n  #         git config --global user.email  \"example@example.com\"\n  #     - name: \"Set $TERM=xterm\"\n  #       run:  printf \"TERM=xterm\\\\n\" >> $GITHUB_ENV\n  #     - name: \"Run bats tests\"\n  #       run:  unbuffer bats test\n  #     # - name: \"Install Go\"\n  #     #   uses: actions/setup-go@v2\n  #     # - name: \"Run go test\"\n  #     #   run: cd nb.go && go test\n  #     # - name: \"Run nb.go bats test\"\n  #     #   run: unbuffer bats test\n  # test-macos-10-15:\n  #   name: \"Test: macOS Catalina 10.15\"\n  #   runs-on: macos-10.15\n  #   steps:\n  #     - uses: actions/checkout@v1\n  #     - name: \"Setup\"\n  #       run: |\n  #         brew update\n  #         brew install bat\n  #         brew unlink  bats\n  #         brew install bats-core\n  #         brew install expect\n  #         brew install gpg\n  #         brew install nmap\n  #         brew install pandoc\n  #         brew install w3m\n  #         git config --global user.name   \"Example Name\"\n  #         git config --global user.email  \"example@example.com\"\n  #     - name: \"Set $TERM=xterm\"\n  #       run:  printf \"TERM=xterm\\\\n\" >> $GITHUB_ENV\n  #     - name: \"Run bats tests\"\n  #       run:  unbuffer bats test\n  #     # - name: \"Install Go\"\n  #     #   uses: actions/setup-go@v2\n  #     # - name: \"Run go test\"\n  #     #   run: cd nb.go && go test\n  #     # - name: \"Run nb.go bats test\"\n  #     #   run: unbuffer bats test\n  test-ubuntu-2404:\n    name: \"Test: Ubuntu 24.04\"\n    runs-on: ubuntu-24.04\n    env:\n      LANG: C.UTF-8\n      LC_ALL: C.UTF-8\n      LC_TYPE: C.UTF-8\n    steps:\n      - uses: actions/checkout@v1\n      - name: \"Setup\"\n        run: |\n          sudo apt-get update\n          sudo apt-get install bats -y\n          sudo apt-get install ncat -y\n          sudo apt-get install python3-pygments -y\n          sudo apt-get install ripgrep -y\n          sudo apt-get install w3m -y\n          curl -LO https://github.com/jgm/pandoc/releases/download/3.2/pandoc-3.2-1-amd64.deb\n          sudo dpkg -i pandoc-3.2-1-amd64.deb\n          curl -LO https://github.com/sharkdp/bat/releases/download/v0.24.0/bat_0.24.0_amd64.deb\n          sudo dpkg -i bat_0.24.0_amd64.deb\n          sudo gem install asciidoctor\n          git config --global user.name   \"Example Name\"\n          git config --global user.email  \"example@example.com\"\n      - uses: browser-actions/setup-chrome@v1\n        id: setup-chrome\n      - run: |\n          ${{ steps.setup-chrome.outputs.chrome-path }} --version\n      - name: \"Set $TERM=xterm\"\n        run:  printf \"TERM=xterm\\\\n\" >> $GITHUB_ENV\n      - name: \"Print encoding variables\"\n        run: |\n          echo \"'$LANG'\"\n          echo \"'$LC_ALL'\"\n          echo \"'$LC_TYPE'\"\n      - name: \"Run bats tests\"\n        run:  script -q -e -c \"bats test\"\n      # - name: \"Install Go\"\n      #   uses: actions/setup-go@v2\n      # - name: \"Run go test\"\n      #   run: cd nb.go && go test\n      # - name: \"Run nb.go bats tests\"\n      #   run:  script -q -e -c \"bats test\"\n"
  },
  {
    "path": ".gitignore",
    "content": ".vagrant\nnb.*\n!nb.go\n!nb.ksh\n!nb.zsh\ntmp\n"
  },
  {
    "path": ".shellcheckrc",
    "content": "###############################################################################\n# .shellcheckrc\n#\n# https://github.com/koalaman/shellcheck\n# https://github.com/koalaman/shellcheck/wiki/Ignore\n###############################################################################\n\n# Disable SC1090\n#\n# > Shellcheck can't follow non-constant source.\n#\n# Sourced paths are dependent on the environment in this program.\n#\n# https://github.com/koalaman/shellcheck/wiki/SC1090\ndisable=SC1090\n\n# Disable SC2002\n#\n# I like cats 😸. Redirection is also used in this project.\n#\n# https://github.com/koalaman/shellcheck/wiki/SC2002\ndisable=SC2002\n\n# Disable SC2015\n#\n# This is used in some places as intended.\n#\n# https://github.com/koalaman/shellcheck/wiki/SC2015\ndisable=SC2015\n\n# Disable SC2088\n#\n# \"${HOME}\" is preferred in this project, so tildes in quotes are intended as\n# tildes and are not expected to expand.\n#\n# https://github.com/koalaman/shellcheck/wiki/SC2088\ndisable=SC2088\n\n# Disable SC2120\n#\n# This is being triggered on `_ls`, which is passed arguments in `_main()`.\n# This is likely being triggered because `_ls` is called separately explicitly\n# without arguments.\n#\n# https://github.com/koalaman/shellcheck/wiki/SC2120\n# disable=SC2120\n\n# Disable SC2206 and SC2207\n#\n# `IFS` and `noglob` are set.\n#\n# https://github.com/koalaman/shellcheck/wiki/SC2206\n# https://github.com/koalaman/shellcheck/wiki/SC2207\ndisable=SC2206,SC2207\n\n# Disable SC2317\n#\n# Many commands are invoked indirectly.\n#\n# https://www.shellcheck.net/wiki/SC2317\ndisable=SC2317\n\n# Disable SC2317 and SC2329\n#\n# Many commands are invoked indirectly.\n#\n# https://www.shellcheck.net/wiki/SC2317\n# https://www.shellcheck.net/wiki/SC2329\ndisable=SC2317,SC2329\n"
  },
  {
    "path": "Baskfile",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# Baskfile\n#\n# Run With Bask: https://github.com/xwmx/bask\n###############################################################################\n\nexport LANG=en_us.UTF-8\nexport LC_ALL=en_us.UTF-8\n\n###############################################################################\n# Helpers\n###############################################################################\n\n# _sed_i()\n#\n# `sed -i` takes an extension on macOS, but that extension can cause errors in\n# GNU `sed`.\n#\n# https://stackoverflow.com/q/43171648\n# https://stackoverflow.com/a/16746032\n_sed_i() {\n  if sed --help >/dev/null 2>&1\n  then # GNU\n    sed -i \"${@}\"\n  else # BSD\n    sed -i '' \"${@}\"\n  fi\n}\n\n###############################################################################\n# Tasks\n###############################################################################\n\n# g:web ################################################################# g:web\n\ndesc \"g:web\" <<HEREDOC\nUsage:\n  bask g:web\n\nDescription:\n  Regenerate index.markdown from README.md combined with existing front matter.\nHEREDOC\ng:web() {\n  local _front_matter_lines=()\n  local _in_front_matter=0\n  local _target_file=\"./docs/index.markdown\"\n\n  [[ ! -f \"${_target_file:?}\" ]] &&\n    _exit_1 printf \"./docs/index.markdown not found.\\\\n\"\n\n  while IFS= read -r __line || [[ -n \"${__line}\" ]]\n  do\n    if [[ \"${__line}\" =~ ^---$ ]]\n    then\n      if ((_in_front_matter))\n      then\n        _in_front_matter=0\n      else\n        _in_front_matter=1\n      fi\n    elif ((_in_front_matter))\n    then\n      _front_matter_lines+=(\"${__line}\")\n    elif [[ -n \"${_front_matter_lines[*]:-}\" ]]\n    then\n      break\n    fi\n  done < \"${_target_file:?}\"\n\n  if [[ -z \"${_front_matter_lines[*]:?}\" ]]\n  then\n    _exit_1 printf \"Front matter not found.\\\\n\"\n  fi\n\n  {\n    cat ./README.md\n  } | {\n    # remove last 6 lines\n    sed -n -e ':a' -e \"1,6\"'!{P;N;D;};N;ba'\n  } | {\n    cat << HEREDOC > \"${_target_file:?}\"\n---\n${_front_matter_lines[*]}\n---\n\n$(cat)\nHEREDOC\n  }\n\n  printf \"Rebuilt: %s\\\\n\" \"${_target_file:?}\"\n}\n\n# npm:publish ##################################################### npm:publish\n\ndesc \"npm:publish\" <<HEREDOC\nUsage:\n  bask npm:publish\n\nDescription\"\n  npm mangles HTML h1 elements, so convert to a normal markdown h1, publish\n  to npm, then revert the heading back to the HTML h1.\nHEREDOC\nnpm:publish() {\n  local _h1=\"<h1 align=\\\"center\\\" id=\\\"nb\\\"><code>nb<\\/code><\\/h1>\"\n\n  printf \"Publishing to npm.\\\\n\"\n  while true\n  do\n    read -r -p \"Proceed? [y/N] \" __yn\n    case ${__yn} in\n      [Yy]*)\n        break\n        ;;\n      *)\n        printf \"Exiting...\\\\n\"\n        exit 0\n        ;;\n    esac\n  done\n\n  _sed_i -e \"s/^${_h1}$/# \\`nb\\`/g\" \"README.md\"\n\n  npm publish\n\n  _sed_i -e \"s/^# \\`nb\\`$/${_h1}/g\" \"./README.md\"\n}\n\n# v ######################################################################### v\n\ndesc \"v\" <<HEREDOC\nUsage:\n  bask v\n  bask v down\n  bask v halt\n  bask v ssh\n  bask v up\n\nDescription:\n  Shortcuts for Vagrant that can be called from any subdirectory.\nHEREDOC\nv() {\n  local _baskfile_path=\"${BASH_SOURCE[0]}\"\n  local _root_dir=\"${_baskfile_path%/Baskfile}\"\n  local _vagrant_dir=\"${_root_dir}/etc\"\n\n  case \"${1:-}\" in\n    d*) # destroy / down\n      (cd \"${_vagrant_dir}\" && vagrant destroy)\n      ;;\n    h*) # halt\n      (cd \"${_vagrant_dir}\" && vagrant halt)\n      ;;\n    s*) # ssh\n      (cd \"${_vagrant_dir}\" && vagrant ssh)\n      ;;\n    u*) # up\n      (cd \"${_vagrant_dir}\" && vagrant up)\n      ;;\n    *)\n      (\n        cd \"${_vagrant_dir}\" && {\n          vagrant ssh        || {\n            vagrant up && vagrant ssh\n          }\n        }\n      )\n      ;;\n  esac\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU Affero General Public License is a free, copyleft license for\nsoftware and other kinds of works, specifically designed to ensure\ncooperation with the community in the case of network server software.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nour General Public Licenses are intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  Developers that use our General Public Licenses protect your rights\nwith two steps: (1) assert copyright on the software, and (2) offer\nyou this License which gives you legal permission to copy, distribute\nand/or modify the software.\n\n  A secondary benefit of defending all users' freedom is that\nimprovements made in alternate versions of the program, if they\nreceive widespread use, become available for other developers to\nincorporate.  Many developers of free software are heartened and\nencouraged by the resulting cooperation.  However, in the case of\nsoftware used on network servers, this result may fail to come about.\nThe GNU General Public License permits making a modified version and\nletting the public access it on a server without ever releasing its\nsource code to the public.\n\n  The GNU Affero General Public License is designed specifically to\nensure that, in such cases, the modified source code becomes available\nto the community.  It requires the operator of a network server to\nprovide the source code of the modified version running there to the\nusers of that server.  Therefore, public use of a modified version, on\na publicly accessible server, gives the public access to the source\ncode of the modified version.\n\n  An older license, called the Affero General Public License and\npublished by Affero, was designed to accomplish similar goals.  This is\na different license, not a version of the Affero GPL, but Affero has\nreleased a new version of the Affero GPL which permits relicensing under\nthis license.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU Affero General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Remote Network Interaction; Use with the GNU General Public License.\n\n  Notwithstanding any other provision of this License, if you modify the\nProgram, your modified version must prominently offer all users\ninteracting with it remotely through a computer network (if your version\nsupports such interaction) an opportunity to receive the Corresponding\nSource of your version by providing access to the Corresponding Source\nfrom a network server at no charge, through some standard or customary\nmeans of facilitating copying of software.  This Corresponding Source\nshall include the Corresponding Source for any work covered by version 3\nof the GNU General Public License that is incorporated pursuant to the\nfollowing paragraph.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the work with which it is combined will remain governed by version\n3 of the GNU General Public License.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU Affero General Public License from time to time.  Such new versions\nwill be similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU Affero General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU Affero General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU Affero General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Affero General Public License as published\n    by the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU Affero General Public License for more details.\n\n    You should have received a copy of the GNU Affero General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If your software can interact with users remotely through a computer\nnetwork, you should also make sure that it provides a way for users to\nget its source.  For example, if your program is a web application, its\ninterface could display a \"Source\" link that leads users to an archive\nof the code.  There are many ways you could offer source, and different\nsolutions will be better for different programs; see section 13 for the\nspecific requirements.\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU AGPL, see\n<https://www.gnu.org/licenses/>.\n"
  },
  {
    "path": "Makefile",
    "content": "BIN ?= nb\nBIN_BOOKMARK ?= bookmark\nPREFIX ?= /usr/local\n\ninstall:\n\tinstall $(BIN) $(PREFIX)/bin\n\tinstall bin/$(BIN_BOOKMARK) $(PREFIX)/bin\n\t./$(BIN) env install\n\nuninstall:\n\trm -f $(PREFIX)/bin/$(BIN)\n\trm -f $(PREFIX)/bin/$(BIN_BOOKMARK)\n\t./$(BIN) env uninstall\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <img  src=\"https://raw.githubusercontent.com/xwmx/nb/master/docs/assets/images/nb.png\"\n        alt=\"nb\"\n        width=\"200\">\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"https://github.com/xwmx/nb/actions\" rel=\"nofollow\">\n    <img  src=\"https://img.shields.io/github/actions/workflow/status/xwmx/nb/tests.yml?branch=master\"\n          alt=\"Build Status\"\n          style=\"max-width:100%;\">\n  </a>\n</div>\n\n<div align=\"center\">&nbsp;</div><!-- spacer -->\n<br/>\n\n`nb` is a command line and local web\nnote‑taking, bookmarking, archiving,\nand knowledge base application\nwith:\n\n- plain text data storage,\n- [encryption](#password-protected-encrypted-notes-and-bookmarks),\n- [filtering](#listing--filtering), [pinning](#-pinning), [#tagging](#-tagging), and [search](#-search),\n- [Git](https://git-scm.com/)-backed [versioning](#-revision-history) and [syncing](#-git-sync),\n- [Pandoc](https://pandoc.org/)-backed [conversion](#%EF%B8%8F-import--export),\n- <a href=\"#-linking\">[[wiki-style linking]]</a>,\n- terminal and GUI web [browsing](#-browsing),\n- inline [images](#-images),\n- [todos](#-todos) with [tasks](#%EF%B8%8F-tasks),\n- global and local [notebooks](#-notebooks),\n- organization with [folders](#-folders),\n- customizable [color themes](#-color-themes),\n- extensibility through [plugins](#-plugins),\n\nand more, in a single portable script.\n\n`nb` creates notes in text-based formats like\n[Markdown](https://en.wikipedia.org/wiki/Markdown),\n[Org](https://orgmode.org/),\n[LaTeX](https://www.latex-project.org/),\nand [AsciiDoc](https://asciidoc.org/),\ncan work with files in any format,\ncan import and export notes to many document formats,\nand can create private, password-protected encrypted notes and bookmarks.\nWith `nb`, you can write notes using\nVim,\nEmacs,\nVS Code,\nSublime Text,\nand any other text editor you like,\nas well as terminal and GUI web browsers.\n`nb` works in any standard Linux / Unix environment,\nincluding macOS and Windows via WSL, MSYS, and Cygwin.\n[Optional dependencies](#optional) can be installed to enhance functionality,\nbut `nb` works great without them.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-theme-nb-home.png\"\n        alt=\"home\"\n        width=\"450\">\n</div>\n\n`nb` is also a powerful [bookmarking](#-bookmarks) system featuring:\n\n- locally-served, text-centric, distraction-free bookmark [browsing](#-browsing)\n  in terminal and GUI web browsers,\n- local full-text search of cached page content with regular expression support,\n- convenient filtering and listing,\n- [Internet Archive Wayback Machine](https://archive.org/web/) snapshot lookup\n  for broken links,\n- tagging, pinning, linking, and full integration with other `nb` features.\n\nPage information is\ndownloaded,\ncleaned up,\nstructured,\nand saved\ninto normal Markdown documents made for humans,\nso bookmarks are easy to view and edit just like any other note.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/gui-terminal-browse.png\"\n        alt=\"nb browse\"\n        width=\"500\">\n</div>\n\n`nb` uses [Git](https://git-scm.com/) in the background to\nautomatically record changes and sync notebooks with remote repositories.\n`nb` can also be configured to\nsync notebooks using a general purpose syncing utility like Dropbox\nso notes can be edited in other apps on any device.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/terminal-empty.png\"\n        alt=\"nb list empty\"\n        width=\"450\">\n</div>\n\n`nb` is designed to be portable, future-focused, and vendor independent,\nproviding a full-featured and intuitive experience within\na highly composable multimodal user-centric text interface.\nThe entire program is contained within\na single [well-tested](#tests) shell script\nthat can be\ninstalled, copied, or `curl`ed almost anywhere and just work,\nusing a strategy inspired by\n[progressive enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement)\nfor various experience improvements in more capable environments.\n`nb` works great whether you have one notebook with just a few notes\nor dozens of notebooks containing thousands of notes, bookmarks, and other items.\n`nb` makes it easy to incorporate other tools, writing apps, and workflows.\n`nb` can be used a little, a lot, once in a while, or for just a subset of features.\n`nb` is flexible.\n\n<div align=\"center\">&nbsp;</div><!-- spacer -->\n\n<div align=\"center\">\n  <sub>\n  📝\n  🔖\n  🔍\n  🌍\n  🔒\n  ✅\n  🔄\n  🎨\n  📚\n  📌\n  📂\n  🌄\n  </sub>\n</div>\n\n<p align=\"center\">&nbsp;</p><!-- spacer -->\n\n<div align=\"center\">\n  <h1 align=\"center\" id=\"nb\"><code>nb</code></h1>\n</div>\n\n<div align=\"center\">\n  <a href=\"#installation\">Installation</a>&nbsp;·\n  <a href=\"#overview\">Overview</a>&nbsp;&nbsp;\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#-help\">Help</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#top\">&nbsp;↑&nbsp;</a>\n</div>\n\n### Installation\n\n#### Dependencies\n\n##### Required\n\n- [Bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell))\n  - `nb` works perfectly with Zsh, fish, and any other shell\n    set as your primary login shell,\n    the system just needs to have Bash available on it.\n- [Git](https://git-scm.com/)\n- A text editor with command line support, such as:\n  - [Vim](https://en.wikipedia.org/wiki/Vim_\\(text_editor\\)),\n  - [Emacs](https://en.wikipedia.org/wiki/Emacs),\n  - [Visual Studio Code](https://code.visualstudio.com/),\n  - [Sublime Text](https://www.sublimetext.com/),\n  - [Helix](https://helix-editor.com/),\n  - [micro](https://github.com/zyedidia/micro),\n  - [nano](https://en.wikipedia.org/wiki/GNU_nano),\n  - [Atom](https://atom.io/),\n  - [TextMate](https://macromates.com/),\n  - [MacDown](https://macdown.uranusjr.com/),\n  - [some of these](https://github.com/topics/text-editor),\n  - [and many of these.](https://en.wikipedia.org/wiki/List_of_text_editors)\n\n##### Optional\n\n`nb` leverages standard command line tools\nand works in standard Linux / Unix environments.\n`nb` also checks the environment for some additional optional tools and\nuses them to enhance the experience whenever they are available.\n\nRecommended:\n\n- [`bat`](https://github.com/sharkdp/bat)\n- [`ncat`](https://nmap.org/ncat/) or [`socat`](https://www.kali.org/tools/socat/)\n- [`pandoc`](https://pandoc.org/)\n- [`rg`](https://github.com/BurntSushi/ripgrep)\n- [`tig`](https://github.com/jonas/tig)\n- [`w3m`](https://en.wikipedia.org/wiki/W3m)\n\nAlso supported for various enhancements:\n\n[Ack](https://beyondgrep.com/),\n[`afplay`](https://ss64.com/osx/afplay.html),\n[`asciidoctor`](https://asciidoctor.org/),\n[The Silver Searcher (`ag`)](https://github.com/ggreer/the_silver_searcher),\n[`catimg`](https://github.com/posva/catimg),\n[Chafa](https://github.com/hpjansson/chafa),\n[Chromium](https://www.chromium.org) / [Chrome](https://www.google.com/chrome/),\n[`eza`](https://github.com/eza-community/eza),\n[`ffplay`](https://ffmpeg.org/ffplay.html),\n[ImageMagick](https://imagemagick.org/),\n[`glow`](https://github.com/charmbracelet/glow),\n[GnuPG](https://en.wikipedia.org/wiki/GNU_Privacy_Guard),\n[`highlight`](http://www.andre-simon.de/doku/highlight/en/highlight.php),\n[`imgcat`](https://www.iterm2.com/documentation-images.html),\n[`joshuto`](https://github.com/kamiyaa/joshuto),\n[kitty's `icat` kitten](https://sw.kovidgoyal.net/kitty/kittens/icat.html),\n[`lowdown`](https://kristaps.bsd.lv/lowdown),\n[`lsd`](https://github.com/lsd-rs/lsd),\n[Links](https://en.wikipedia.org/wiki/Links_(web_browser)),\n[Lynx](https://en.wikipedia.org/wiki/Lynx_(web_browser)),\n[`mdcat`](https://github.com/swsnr/mdcat),\n[`mdless`](https://github.com/ttscoff/mdless),\n[`mdv`](https://github.com/axiros/terminal_markdown_viewer),\n[Midnight Commander (`mc`)](https://en.wikipedia.org/wiki/Midnight_Commander),\n[`mpg123`](https://en.wikipedia.org/wiki/Mpg123),\n[MPlayer](https://en.wikipedia.org/wiki/MPlayer),\n[`ncat`](https://nmap.org/ncat/),\n[`netcat`](https://netcat.sourceforge.net/),\n[note-link-janitor](https://github.com/andymatuschak/note-link-janitor)\n(via [plugin](https://github.com/xwmx/nb/blob/master/plugins/backlink.nb-plugin)),\n[`pdftotext`](https://en.wikipedia.org/wiki/Pdftotext),\n[Pygments](https://pygments.org/),\n[Ranger](https://ranger.github.io/),\n[readability-cli](https://gitlab.com/gardenappl/readability-cli),\n[`rga` / ripgrep-all](https://github.com/phiresky/ripgrep-all),\n[`sc-im`](https://github.com/andmarti1424/sc-im),\n[`socat`](https://www.kali.org/tools/socat/),\n[`termvisage`](https://github.com/AnonymouX47/termvisage),\n[`termpdf.py`](https://github.com/dsanson/termpdf.py),\n[Tidy-Viewer (`tv`)](https://github.com/alexhallam/tv),\n[`timg`](https://github.com/hzeller/timg),\n[vifm](https://vifm.info/),\n[`viu`](https://github.com/atanunq/viu),\n[VisiData](https://www.visidata.org/)\n\n#### macOS / Homebrew\n\n```bash\nbrew install xwmx/taps/nb\n```\n\nInstalling `nb` with Homebrew also installs\nthe recommended dependencies above\nand completion scripts for Bash, Zsh, and Fish.\n\nInstall the latest development version from the repository with:\n\n```bash\nbrew install xwmx/taps/nb --head\n```\n\n`nb` is also available in\n[homebrew-core](https://github.com/Homebrew/homebrew-core).\nInstalling it together with the `bash` formula is recommended:\n\n```bash\nbrew install nb bash\n```\n\n#### Ubuntu, Windows, and others\n\n##### npm\n\n```bash\nnpm install -g nb.sh\n```\n\nAfter `npm` installation completes, run\n`sudo \"$(which nb)\" completions install`\nto install Bash and Zsh completion scripts (recommended).\n\nOn Ubuntu and WSL, you can\nrun [`sudo \"$(which nb)\" env install`](#env)\nto install the optional dependencies.\n\nWhen `nb` is installed on Windows,\n`socat` ([MSYS](https://packages.msys2.org/package/socat),\n[Cygwin](https://cygwin.com/packages/summary/socat.html)) is recommended.\n\n*`nb` is also available under its original package name,\n[notes.sh](https://www.npmjs.com/package/notes.sh),\nwhich comes with an extra `notes` executable wrapping `nb`.*\n\n##### Download and Install\n\nTo install as an administrator,\ncopy and paste one of the following multi-line commands:\n\n```bash\n# install using wget\nsudo wget https://raw.github.com/xwmx/nb/master/nb -O /usr/local/bin/nb &&\n  sudo chmod +x /usr/local/bin/nb &&\n  sudo nb completions install --download\n\n# install using curl\nsudo curl -L https://raw.github.com/xwmx/nb/master/nb -o /usr/local/bin/nb &&\n  sudo chmod +x /usr/local/bin/nb &&\n  sudo nb completions install --download\n```\n\nOn Ubuntu and WSL, you can\nrun [`sudo nb env install`](#env) to install the optional dependencies.\n\n###### User-only Installation\n\nTo install with just user permissions, simply\nadd the `nb` script to your `$PATH`.\nIf you already have a `~/bin` directory, for example, you can\nuse one of the following commands:\n\n```bash\n# download with wget\nwget https://raw.github.com/xwmx/nb/master/nb -O ~/bin/nb && chmod +x ~/bin/nb\n\n# download with curl\ncurl -L https://raw.github.com/xwmx/nb/master/nb -o ~/bin/nb && chmod +x ~/bin/nb\n```\n\nInstalling with just user permissions doesn't include\nthe optional dependencies or completions,\nbut `nb` core functionality works without them.\nIf you have `sudo` access and want\nto install the completion scripts and dependencies, run the following command:\n\n```bash\nsudo nb env install\n```\n\n##### Make\n\nTo install with [Make](https://en.wikipedia.org/wiki/Make_(software)),\nclone this repository, navigate to the clone's root directory, and run:\n\n```bash\nsudo make install\n```\n\nThis will also install the completion scripts on all systems and\nthe recommended dependencies on Ubuntu and WSL.\n\n##### bpkg\n\nTo install with [bpkg](https://github.com/bpkg/bpkg):\n\n```bash\nbpkg install xwmx/nb\n```\n\n##### basher\n\nTo install with [basher](https://www.basher.it/):\n\n```bash\nbasher install xwmx/nb\n```\n\n#### Tab Completion\n\nBash, Fish, and Zsh tab completion should be enabled\nwhen `nb` is installed using the methods above,\nassuming you have the appropriate system permissions or installed with `sudo`.\nIf completion isn't working after installing `nb`, see the\n[completion installation instructions](https://github.com/xwmx/nb/tree/master/etc).\n\n#### Updating\n\nWhen `nb` is installed using a package manager like npm or Homebrew,\nuse the package manager's upgrade functionality to update `nb` to\nthe latest version.\nWhen installed via other methods,\n`nb` can be updated to the latest version using\nthe [`nb update`](#update) subcommand.\n\n## Overview\n\n<div align=\"center\">\n  <a href=\"#-notes\"><code>📝</code>&nbsp;Notes</a>&nbsp;·\n  <a href=\"#adding\">Adding</a>&nbsp;·\n  <a href=\"#listing--filtering\">Listing</a>&nbsp;·\n  <a href=\"#editing\">Editing</a>&nbsp;·\n  <a href=\"#viewing\">Viewing</a>&nbsp;·\n  <a href=\"#deleting\">Deleting</a>&nbsp;·\n  <a href=\"#-bookmarks\"><code>🔖</code>&nbsp;Bookmarks</a>&nbsp;·\n  <a href=\"#-todos\"><code>✅</code>&nbsp;Todos</a>&nbsp;·\n  <a href=\"#%EF%B8%8F-tasks\"><code>✔️</code>&nbsp;Tasks</a>&nbsp;·\n  <a href=\"#-tagging\"><code>🏷</code>&nbsp;Tagging</a>&nbsp;·\n  <a href=\"#-linking\"><code>🔗</code>&nbsp;Linking</a>&nbsp;·\n  <a href=\"#-browsing\"><code>🌍</code>&nbsp;Browsing</a>&nbsp;·\n  <a href=\"#-images\"><code>🌄</code>&nbsp;Images</a>&nbsp;·\n  <a href=\"#-zettelkasten\"><code>🗂</code>&nbsp;Zettelkasten</a>&nbsp;·\n  <a href=\"#-folders\"><code>📂</code>&nbsp;Folders</a>&nbsp;·\n  <a href=\"#-pinning\"><code>📌</code>&nbsp;Pinning</a>&nbsp;·\n  <a href=\"#-search\"><code>🔍</code>&nbsp;Search</a>&nbsp;·\n  <a href=\"#-moving--renaming\"><code>↔</code>&nbsp;Moving&nbsp;&&nbsp;Renaming</a>&nbsp;·\n  <a href=\"#-revision-history\"><code>🗒</code>&nbsp;History</a>&nbsp;·\n  <a href=\"#-notebooks\"><code>📚</code>&nbsp;Notebooks</a>&nbsp;·\n  <a href=\"#-git-sync\"><code>🔄</code>&nbsp;Git&nbsp;Sync</a>&nbsp;·\n  <a href=\"#%EF%B8%8F-import--export\"><code>↕️</code>&nbsp;Import&nbsp;/&nbsp;Export</a>&nbsp;·\n  <a href=\"#%EF%B8%8F-set--settings\"><code>⚙️</code><code>set</code>&<code>settings</code></a>&nbsp;·\n  <a href=\"#-color-themes\"><code>🎨</code>&nbsp;Color&nbsp;Themes</a>&nbsp;·\n  <a href=\"#-plugins\"><code>🔌</code>&nbsp;Plugins</a>&nbsp;·\n  <a href=\"#-selectors\"><code>:/</code>&nbsp;Selectors</a>&nbsp;·\n  <a href=\"#01-metadata\"><code>01</code>&nbsp;Metadata</a>&nbsp;·\n  <a href=\"#-interactive-shell\"><code>❯</code>&nbsp;Shell</a>&nbsp;·\n  <a href=\"#shortcut-aliases\">Shortcuts</a>&nbsp;·\n  <a href=\"#-help\"><code>?</code>&nbsp;Help</a>&nbsp;·\n  <a href=\"#-variables\"><code>$</code>&nbsp;Variables</a>&nbsp;·\n  <a href=\"#specifications\">Specifications</a>&nbsp;·\n  <a href=\"#tests\">Tests</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#nb\">&nbsp;↑&nbsp;</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\nTo get started, simply run:\n\n```bash\nnb\n```\n\n`nb` sets up your initial `home` notebook the first time it runs.\n\nBy default, notebooks and notes are global (at `~/.nb`),\nso they are always available to `nb`\nregardless of the current working directory.\n`nb` also supports [local notebooks](#global-and-local-notebooks).\n\n### 📝 Notes\n\n#### Adding\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#add\"><code>nb add</code></a>,\n    <a href=\"#browse\"><code>nb browse add</code></a>\n  </sup>\n</p>\n\nUse [`nb add`](#add) (shortcuts: [`nb a`](#add), [`nb +`](#add))\nto create new notes:\n\n```bash\n# create a new note in your text editor\nnb add\n\n# create a new note with the filename \"example.md\"\nnb add example.md\n\n# create a new note containing \"This is a note.\"\nnb add \"This is a note.\"\n\n# create a new note with piped content\necho \"Note content.\" | nb add\n\n# create a new password-protected, encrypted note titled \"Secret Document\"\nnb add --title \"Secret Document\" --encrypt\n\n# create a new note in the notebook named \"example\"\nnb example:add \"This is a note.\"\n\n# create a new note in the folder named \"sample\"\nnb add sample/\n```\n\n[`nb add`](#add) with no arguments or input will open the new, blank note\nin your environment's preferred text editor.\nYou can change your editor using\nthe `$EDITOR` environment variable\nor [`nb set editor`](#editor).\n\n`nb` files are [Markdown](https://daringfireball.net/projects/markdown/)\nfiles by default. The default file type can be changed to\nwhatever you like\nusing [`nb set default_extension`](#default_extension).\n\n[`nb add`](#add) has intelligent argument parsing\nand behaves differently depending on the types of arguments it receives.\nWhen a filename with extension is specified,\na new note with that filename is opened in the editor:\n\n```bash\nnb add example.md\n```\n\nWhen a string is specified, a new note is immediately created\nwith that string as the content and without opening the editor:\n\n```bash\n❯ nb add \"This is a note.\"\nAdded: [1] 20200101000000.md\n```\n\n[`nb add <string>`](#add) is useful for quickly jotting down notes directly\nvia the command line. Quoting content is optional, but recommended.\n\nWhen no filename is specified, [`nb add`](#add) uses the current datetime as\nthe filename.\n\n[`nb add`](#add) can also receive piped content, which behaves the same as\n[`nb add <string>`](#add):\n\n```bash\n# create a new note containing \"Note content.\"\n❯ echo \"Note content.\" | nb add\nAdded: [6] 20200101000100.md\n\n# create a new note containing the clipboard contents on macOS\n❯ pbpaste | nb add\nAdded: [7] 20200101000200.md\n\n# create a new note containing the clipboard contents using xclip\n❯ xclip -o | nb add\nAdded: [8] 20200101000300.md\n```\n\nContent can be passed with the [`--content <content>`](#add) option,\nwhich also creates a new note without opening the editor:\n\n```bash\nnb add --content \"Note content.\"\n```\n\nWhen content is piped,\nspecified with [`--content <content>`](#add),\nor passed as a string argument,\nuse the [`--edit`](#add) flag to open the file in the editor\nbefore the change is committed.\n\nThe title, filename, and content can also be specified with long and\nshort options:\n\n```bash\n❯ nb add --filename \"example.md\" -t \"Example Title\" -c \"Example content.\"\nAdded: [9] example.md \"Example Title\"\n```\n\nThe [`-t <title>`](#add) / [`--title <title>`](#add) option also\nsets the filename to the title,\nlowercased with spaces and non-filename characters replaced with underscores:\n\n```bash\n❯ nb add --title \"Example Title\" \"Example content.\"\nAdded: [10] example_title.md \"Example Title\"\n```\n\nTags can be added with the [`--tags <tag1>,<tag2>...`](#add) option, which\ntakes a comma separated list of tags,\nconverts them to [#hashtags](#-tagging),\nand inserts them between the title and content:\n\n```bash\n❯ nb add \"Example content.\" --title \"Tagged Example\" --tags tag1,tag2\nAdded: [11] tagged_example.md \"Tagged Example\"\n\n❯ nb show 11 --print\n# Tagged Example\n\n#tag1 #tag2\n\nExample content.\n```\n\n[Search](#-search) for tagged items with\n[`nb search`](#search) / [`nb q`](#search):\n\n```bash\n# search for items tagged with \"#tag1\"\nnb search --tag tag1\n\n# search for items tagged with \"#tag1\" AND \"#tag2\", short options\nnb q -t tag1 -t tag2\n\n# search for items tagged with \"#tag1\" OR \"#tag2\", arguments\nnb q \\#tag1 --or \\#tag2\n```\n\nFiles can be created with any file type by specifying the extension either\nin the filename (`example.md`),\nthe extension by itself (`.md`),\nor via the [`--type <type>`](#add) option (`--type md`):\n\n```bash\n# open a new Org file in the editor\nnb add example.org\n\n# open a new reStructuredText file in the editor\nnb add --type rst\n\n# open a new JavaScript file in the editor\nnb add .js\n```\n\nCombining a type argument with piped clipboard content provides\na very convenient way to save code snippets using a clipboard utility such as\n`pbpaste`,\n`xclip`,\nor [`pb`](https://github.com/xwmx/pb):\n\n```bash\n# save the clipboard contents as a JavaScript file in the current notebook\npb | nb add .js\n\n# save the clipboard contents as a Rust file in the \"rust\" notebook\n# using the shortcut alias `nb a`\npb | nb a rust: .rs\n\n# save the clipboard contents as a Haskell file named \"example.hs\" in the\n# \"snippets\" notebook using the shortcut alias `nb +`\npb | nb + snippets: example.hs\n```\n\nUse [`nb show`](#show) and [`nb browse`](#browse) to view code snippets\nwith automatic syntax highlighting and\nuse [`nb edit`](#edit) to open in your editor.\n\nThe [`clip` plugin](#clip) can also be used to\ncreate notes from clipboard content.\n\nPiping,\n[`--title <title>`](#add),\n[`--tags <tag-list>`](#add),\n[`--content <content>`](#add),\nand content passed in an argument\ncan be combined as needed\nto create notes with content from multiple input methods and sources\nusing a single command:\n\n```bash\n❯ pb | nb add \"Argument content.\" \\\n    --title   \"Sample Title\"      \\\n    --tags    tag1,tag2           \\\n    --content \"Option content.\"\nAdded: [12] sample_title.md \"Sample Title\"\n\n❯ nb show 12 --print\n# Sample Title\n\n#tag1 #tag2\n\nArgument content.\n\nOption content.\n\nClipboard content.\n```\n\nFor a full list of options available for [`nb add`](#add), run\n[`nb help add`](#add).\n\n##### Password-Protected Encrypted Notes and Bookmarks\n\nPassword-protected notes and [bookmarks](#-bookmarks) are\ncreated with the [`-e`](#add) / [`--encrypt`](#add) flag and\nencrypted with AES-256 using OpenSSL by default.\nGPG is also supported and can be configured with\n[`nb set encryption_tool`](#encryption_tool).\n\nEach protected note and bookmark is\nencrypted individually with its own password.\nWhen an encrypted item is viewed, edited, or opened,\n`nb` will simply prompt for the item's password before proceeding.\nAfter an item is edited,\n`nb` automatically re-encrypts it and saves the new version.\n\nEncrypted notes can be decrypted\nusing the OpenSSL and GPG command line tools directly, so\nyou aren't dependent on `nb` to decrypt your files.\n\n##### Templates\n\nCreate a note based on a template by assigning a template string\nor path to a template file with [`add --template <template>`](#add):\n\n<!-- {% raw %} -->\n```bash\n# create a new note based on a template specified by path\nnb add --template /path/to/example/template\n\n# create a new note based on a template defined as a string\nnb add --template \"{{title}} • {{content}}\"\n```\n<!-- {% endraw %} -->\n\n`nb` template tags are enclosed in double curly brackets.\nSupported tags include:\n\n<dl>\n  <dt><code>&#x007B;{title}}</code></dt>\n  <dd>The note title, as specified with\n  <a href=\"#add\"><code>add --title &#60;title></code></a></dd>\n  <dt><code>&#x007B;&#x007B;tags}}</code></dt>\n  <dd>A list of hashtags, as specified with\n  <a href=\"#add\"><code>add --tags &#60;tag1>,&#60;tag2></code></a></dd>\n  <dt><code>&#x007B;{content}}</code></dt>\n  <dd>The note content, as specified with\n  <a href=\"#add\"><code>add &#60;content></code></a>,\n  <a href=\"#add\"><code>add --content &#60;content></code></a>,\n  and piped content.</dd>\n  <dt><code>&#x007B;{date}}</code></dt>\n  <dd>The ouput of the system's <code>date</code> command. Use the\n  <a href=\"https://man7.org/linux/man-pages/man1/date.1.html\"><code>date</code>\n  command options</a> to control formatting, e.g.,\n  <code>&#x007B;{date +\"%Y-%m-%d\"}}</code>.\n </dd>\n</dl>\n\nAn example complete markdown template could look like the following:\n\n<!-- {% raw %} -->\n```\n# {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n{{tags}}\n\n{{content}}\n```\n<!-- {% endraw %} -->\n\nTemplates are Bash strings processed with `eval`, so you can use\ncommand substitution (`$(echo \"Example command\")`) to include\nthe output from command line tools and shell code.\n\nA default template can be configured by assigning a string or path\nto the [`$NB_DEFAULT_TEMPLATE`](#nb_default_template) variable\nin your `~/.nbrc` file:\n\n<!-- {% raw %} -->\n```bash\n# set the default template to a path\nexport NB_DEFAULT_TEMPLATE=\"/path/to/example/template\"\n\n# set the default template with a string\nexport NB_DEFAULT_TEMPLATE=\"{{title}} • {{content}}\"\n```\n<!-- {% endraw %} -->\n\nUse [`nb add --no-template`](#add) to skip using a template when\none is assigned.\n\n##### Shortcut Aliases: `nb a`, `nb +`\n\n`nb` includes shortcuts for many commands, including\n[`nb a`](#add) and [`nb +`](#add) for [`nb add`](#add):\n\n```bash\n# create a new note in your text editor\nnb a\n\n# create a new note with the filename \"example.md\"\nnb a example.md\n\n# create a new note containing \"This is a note.\"\nnb + \"This is a note.\"\n\n# create a new note containing the clipboard contents with xclip\nxclip -o | nb +\n\n# create a new note in the notebook named \"example\"\nnb example:a\n```\n\n##### Other Aliases: `nb create`, `nb new`\n\n[`nb add`](#add) can also be invoked with\n[`nb create`](#add) and [`nb new`](#add) for convenience:\n\n```bash\n# create a new note containing \"Example note content.\"\nnb new \"Example note content.\"\n\n# create a new note with the title \"Example Note Title\"\nnb create --title \"Example Note Title\"\n```\n\n##### Adding with `nb browse`\n\nItems can also be added within terminal and GUI web browsers using\n[`nb browse add`](#browse) / [`nb b a`](#browse):\n\n```bash\n❯ nb browse add\n❯nb · home : +\n\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n\n[add]\n```\n\nPass a filename, relative path, and / or notebook name to\ncreate a new note at that location:\n\n```bash\n# open the add form in the browser to create the file \"file.md\" in the folder \"example\"\nnb browse add \"example/file.md\"\n```\n\n[`nb browse add`](#browse) includes options for quickly\npre-populating new notes with content:\n\n```bash\n❯ nb browse add --title \"Example Title\" --content \"Example content.\" --tags tag1,tag2\n❯nb · home : +\n\n[# Example Title                                      ]\n[                                                     ]\n[#tag1 #tag2                                          ]\n[                                                     ]\n[Example content.                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n\n[add]\n```\n\n[`nb browse add`](#browse) can also be opened with\n[`nb add --browse`](#add) / [`nb a -b`](#add).\n\nFor more information, see [Browsing](#-browsing).\n\n#### Listing & Filtering\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#ls\"><code>nb ls</code></a>,\n    <a href=\"#list\"><code>nb list</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\nTo list notes and notebooks, run [`nb ls`](#ls) (shortcut alias: `nb`):\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-theme-utility-home.png\"\n        alt=\"nb ls\"\n        width=\"450\">\n</div>\n\nNotebooks are listed above the line,\nwith the current notebook highlighted and/or underlined,\ndepending on terminal capabilities.\n[`nb ls`](#ls) also includes a footer with example commands for easy reference.\nThe notebook header and command footer can be configured or hidden with\n[`nb set header`](#header) and\n[`nb set footer`](#footer).\n\n```bash\n❯ nb ls\nhome\n----\n[3] example.md · \"Example content.\"\n[2] sample.md · \"Sample content.\"\n[1] demo.md · \"- Demo list item one.\"\n```\n\nNotes from the current notebook are listed in the order they were last modified.\nBy default, each note is listed with its\nid, filename, and an excerpt from the first line of the note.\nWhen a note has a title, the title is displayed\ninstead of the filename and first line.\n\nMarkdown titles can be defined within a note using\n[either Markdown `h1` style](https://daringfireball.net/projects/markdown/syntax#header)\nor [YAML front matter](#front-matter):\n\n```markdown\n# Example Title\n```\n\n```markdown\nSample Title\n============\n```\n\n```markdown\n---\ntitle: Demo Title\n---\n```\n\n[Org](https://orgmode.org/),\n[LaTeX](https://www.latex-project.org/),\nand [AsciiDoc](https://asciidoc.org/)\ntitles are recognized in `.org`,`.latex`, and `.asciidoc` / `.adoc` files:\n\n```text\n#+title: Example Org Title\n```\n\n```latex\n\\title{Example LaTeX Title}\n```\n\n```asciidoc\n= Example AsciiDoc Title\n```\n\nOnce defined, titles are displayed in place of the filename and first line\nin the output of [`nb ls`](#ls):\n\n```bash\n❯ nb ls\nhome\n----\n[3] Example Title\n[2] Sample Title\n[1] Demo Title\n```\n\nPass an id, filename, or title to view the listing for that note:\n\n```bash\n❯ nb ls Sample\\ Title\n[2] Sample Title\n\n❯ nb ls 3\n[3] Example Title\n```\n\nIf there is no exact match, `nb` will list items with\ntitles and filenames that fuzzy match the query:\n\n```bash\n❯ nb ls exa\n[3] Example Title\n\n❯ nb ls ample\n[3] Example Title\n[2] Sample Title\n```\n\nMultiple words act like an `OR` filter, listing any\ntitles or filenames that match any of the words:\n\n```bash\n❯ nb ls example demo\n[3] Example Title\n[1] Demo Title\n```\n\nWhen multiple words are quoted, filter titles and filenames for that phrase:\n\n```bash\n❯ nb ls \"example title\"\n[3] Example Title\n```\n\nFor full text search, see [Search](#-search).\n\nTo view excerpts of notes, use the [`--excerpt`](#ls) or [`-e`](#ls) option,\nwhich optionally accepts a length:\n\n```bash\n❯ nb ls 3 --excerpt\n[3] Example Title\n-----------------\n# Example Title\n\nThis is an example excerpt.\n\n❯ nb ls 3 -e 8\n[3] Example Title\n-----------------\n# Example Title\n\nThis is an example excerpt.\n\nMore example content:\n\n- one\n- two\n```\n\nSeveral classes of file types are represented with emoji\n[indicators](#indicators) to make them easily identifiable in lists.\nFor example, bookmarks and encrypted notes are listed with `🔖` and `🔒`:\n\n```bash\n❯ nb ls\nhome\n----\n[4] Example Note\n[3] 🔒 encrypted-note.md.enc\n[2] 🔖 Example Bookmark (example.com)\n[1] 🔖 🔒 encrypted.bookmark.md.enc\n```\n\nFile types include:\n\n```text\n 🔉  Audio\n 📖  Book\n 🔖  Bookmark\n 🔒  Encrypted\n 📂  Folder\n 🌄  Image\n 📄  PDF, Word, or Open Office document\n 📹  Video\n```\n\nBy default, items are listed starting with the most recently modified.\nTo reverse the order, use the [`-r`](#ls) or [`--reverse`](#ls) flag:\n\n```bash\n❯ nb ls\nhome\n----\n[2] Todos\n[3] Example Title\n[1] Ideas\n\n❯ nb ls --reverse\n[1] Ideas\n[3] Example Title\n[2] Todos\n```\n\nNotes can be sorted with the [`-s`](#ls) / [`--sort`](#ls) flag,\nwhich can be combined with [`-r`](#ls) / [`--reverse`](#ls):\n\n```bash\n❯ nb ls\nhome\n----\n[2] Sample Title\n[3] Example Title\n[1] Demo Title\n\n❯ nb ls --sort\n[1] Demo Title\n[2] Sample Title\n[3] Example Title\n\n❯ nb ls --sort --reverse\n[3] Example Title\n[2] Sample Title\n[1] Demo Title\n```\n\n`nb` with no subcommand behaves like an alias for [`nb ls`](#ls),\nso the examples above can be run without the `ls`:\n\n```bash\n❯ nb\nhome\n----\n[2] Sample Title\n[3] Example Title\n[1] Demo Title\n\n❯ nb example\n[3] Example Title\n\n❯ nb 3 --excerpt\n[3] Example Title\n-----------------\n# Example Title\n\nThis is an example excerpt.\n\n❯ nb 3 -e 8\n[3] Example Title\n-----------------\n# Example Title\n\nThis is an example excerpt.\n\nMore example content:\n\n- one\n- two\n\n❯ nb --sort\n[1] Demo Title\n[2] Sample Title\n[3] Example Title\n\n❯ nb --sort --reverse\n[3] Example Title\n[2] Sample Title\n[1] Demo Title\n```\n\nShort options can be combined for brevity:\n\n```bash\n# equivalent to `nb --sort --reverse --excerpt 2` and `nb -s -r -e 2`:\n❯ nb -sre 2\n[3] Example Title\n-----------------\n# Example Title\n\n[2] Sample Title\n----------------\nSample Title\n============\n[1] Demo Title\n--------------\n---\ntitle: Demo Title\n```\n\n`nb` and [`nb ls`](#ls) display the 15 most recently modified items.\nThe default limit can be changed with [`nb set limit <number>`](#limit).\nTo list a different number of items on a per-command basis, use the\n[`-n <limit>`](#ls),\n[`--limit <limit>`](#ls),\n[`--<limit>`](#ls),\n[`-a`](#ls),\nand [`--all`](#ls)\nflags:\n\n```bash\n❯ nb -n 1\nhome\n----\n[5] Example Five\n4 omitted. 5 total.\n\n❯ nb --limit 2\nhome\n----\n[5] Example Five\n[4] Example Four\n3 omitted. 5 total.\n\n❯ nb --3\nhome\n----\n[5] Example Five\n[4] Example Four\n[3] Example Three\n2 omitted. 5 total.\n\n❯ nb --all\nhome\n----\n[5] Example Five\n[4] Example Four\n[3] Example Three\n[2] Example Two\n[1] Example One\n```\n\nLists can be paginated with\n[`-p <number>`](#ls) / [`--page <number>`](#ls),\nwhich paginates by the value of [`nb set limit`](#limit) by\ndefault, or the value of\n[`-n <limit>`](#ls),\n[`--limit <limit>`](#ls),\nor [`--<limit>`](#ls)\nwhen present:\n\n```bash\n❯ nb\nhome\n----\n[6] Example Six\n[5] Example Five\n[4] Example Four\n[3] Example Three\n[2] Example Two\n[1] Example One\n\n❯ nb set limit 3\nNB_LIMIT set to 3\n\n❯ nb --page 1\n[6] Example Six\n[5] Example Five\n[4] Example Four\n\n❯ nb -p 2\n[3] Example Three\n[2] Example Two\n[1] Example One\n\n❯ nb -p 2 --limit 2\n[4] Example Four\n[3] Example Three\n\n❯ nb -p 3 --2\n[2] Example Two\n[1] Example One\n```\n\nList [#tagged](#tagging) items by passing `\\#escaped` or `\"#quoted\"` hashtags\nor tags specified with the [`--tags`](#ls) option. Multiple tags perform an\n`AND` query:\n\n```bash\n# list items in the current notebook tagged with \"#tag1\", escaped\nnb \\#tag1\n\n# list items in the \"example\" notebook tagged with \"#tag2\", quoted\nnb example: \"#tag2\"\n\n# list items in all notebooks tagged with \"#tag1\", long option\nnb \\#tag1 --all\n\n# list items in the current notebook tagged with \"#tag1\" AND \"#tag2\"\nnb \\#tag1 \"#tag2\"\n\n# list items in all notebooks tagged with \"#tag2\" AND \"#tag3\", short option\nnb --tags tag2,tag3 -a\n```\n\n[`nb ls`](#ls) is a combination of\n[`nb notebooks`](#notebooks) and [`nb list`](#list)\nin one view and accepts the same arguments as [`nb list`](#list),\nwhich lists only notes without the notebook list and with no limit by default:\n\n```bash\n❯ nb list\n[100] Example One Hundred\n[99]  Example Ninety-Nine\n[98]  Example Ninety-Eight\n... lists all notes ...\n[2]   Example Two\n[1]   Example One\n```\n\nFor more information about options for listing notes, run\n[`nb help ls`](#ls)\nand\n[`nb help list`](#list).\n\n##### Listing with `browse`\n\nItems can be listed within terminal and GUI web browsers using\n[`nb browse`](#browse) / [`nb b`](#browse):\n\n```bash\n❯ nb browse example:sample/demo/\n❯nb · example : sample / demo / +\n\nsearch: [                    ]\n\n[example:sample/demo/7] Title Seven\n[example:sample/demo/6] Title Six\n[example:sample/demo/5] Title Five\n[example:sample/demo/4] Title Four\n[example:sample/demo/3] Title Three\n\nnext ❯\n```\n\nFor more information, see [Browsing](#-browsing).\n\n#### Editing\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#edit\"><code>nb edit</code></a>,\n    <a href=\"#browse\"><code>nb browse edit</code></a>\n  </sup>\n</p>\n\nYou can edit an item in your editor with\n[`nb edit`](#edit) (shortcut: [`nb e`](#edit)):\n\n```bash\n# edit note by id\nnb edit 3\n\n# edit note by filename\nnb edit example.md\n\n# edit note by title\nnb edit \"A Document Title\"\n\n# edit note 12 in the notebook named \"example\"\nnb edit example:12\n\n# edit note 12 in the notebook named \"example\", alternative\nnb example:12 edit\n\n# edit note 12 in the notebook named \"example\", alternative\nnb example:edit 12\n\n# edit the last modified item\nnb edit --last\n```\n\n[`edit`](#edit) and other subcommands that take an identifier\ncan be called with the identifier and subcommand name reversed:\n\n```bash\n# edit note by id\nnb 3 edit\n```\n\n[`nb edit`](#edit) can also receive piped content, which it\nappends to the specified note without opening the editor:\n\n```bash\necho \"Content to append.\" | nb edit 1\n```\n\nContent can be passed with the [`--content <content>`](#edit) option,\nwhich also appends the content without opening the editor:\n\n```bash\nnb edit 1 --content \"Content to append.\"\n```\n\nUse the [`--overwrite`](#edit) option to overwrite existing file content\nand the [`--prepend`](#edit) option to prepend the new content before existing content.\n\nWhen content is piped or specified with [`--content <content>`](#edit),\nuse the [`--edit`](#edit) flag to open the file in the editor\nbefore the change is committed.\n\nEdit the last modified item with [`--last`](#edit) / [`-l`](#edit):\n\n```bash\n# edit the last modified item\nnb edit --last\n\n# edit the last modified item, short option\nnb edit -l\n```\n\n##### Editing Encrypted Notes\n\nWhen a note is encrypted,\n[`nb edit`](#edit) prompts you for the note password,\nopens the unencrypted content in your editor,\nand then automatically reencrypts the note when you are done editing.\n\n##### Shortcut Alias: `nb e`\n\n[`nb edit`](#edit) can be called by the shortcut alias, [`nb e`](#edit):\n\n```bash\n# edit note by id\nnb e 3\n\n# edit note by filename\nnb e example.md\n\n# edit note by title\nnb e \"A Document Title\"\n\n# edit note by id, alternative\nnb 3 e\n\n# edit note 12 in the notebook named \"example\"\nnb e example:12\n\n# edit note 12 in the notebook named \"example\", alternative\nnb example:12 e\n\n# edit note 12 in the notebook named \"example\", alternative\nnb example:e 12\n\n# edit the last modified item, short option\nnb e -l\n```\n\nFor [`nb edit`](#edit) help information, run [`nb help edit`](#edit).\n\n##### Editing with `browse`\n\nItems can be edited within terminal and GUI web browsers using\n[`nb browse edit`](#browse) / [`nb b e`](#browse):\n\n```bash\n❯ nb browse edit text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · editing · - | +\n\n[# Daring Fireball: Markdown (daringfireball.net)         ]\n[                                                         ]\n[<https://daringfireball.net/projects/markdown/>          ]\n[                                                         ]\n[## Related                                               ]\n[                                                         ]\n[- <https://en.wikipedia.org/wiki/Markdown>               ]\n[                                                         ]\n[## Comments                                              ]\n[                                                         ]\n[See also:                                                ]\n[                                                         ]\n[- [[text:formats/org]]                                   ]\n[- [[cli:apps/nb]]                                        ]\n[                                                         ]\n[## Tags                                                  ]\n[                                                         ]\n\n[save] · last: 2021-01-01 01:00:00\n```\n\nFor more information, see\n[`browse edit`](#browse-edit) and [Browsing](#-browsing).\n\n#### Viewing\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#show\"><code>nb show</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>,\n    <a href=\"#open\"><code>nb open</code></a>,\n    <a href=\"#peek\"><code>nb peek</code></a>\n  </sup>\n</p>\n\nNotes and other items can be viewed using\n[`nb show`](#show) (shortcut: [`nb s`](#show)):\n\n```bash\n# show note by id\nnb show 3\n\n# show note by filename\nnb show example.md\n\n# show note by title\nnb show \"A Document Title\"\n\n# show note by id, alternative\nnb 3 show\n\n# show note 12 in the notebook named \"example\"\nnb show example:12\n\n# show note 12 in the notebook named \"example\", alternative\nnb example:12 show\n\n# show note 12 in the notebook named \"example\", alternative\nnb example:show 12\n```\n\nBy default, [`nb show`](#show) opens notes in\n[`less`](https://linux.die.net/man/1/less),\nwith syntax highlighting if\n[`bat`](https://github.com/sharkdp/bat),\n[`highlight`](http://www.andre-simon.de/doku/highlight/en/highlight.php),\nor\n[Pygments](https://pygments.org/)\nis installed.\nYou can navigate in `less` using the following keys:\n\n```text\nKey               Function\n---               --------\nmouse scroll      Scroll up or down\narrow up or down  Scroll one line up or down\nf                 Jump forward one window\nb                 Jump back one window\nd                 Jump down one half window\nu                 Jump up one half window\n/<query>          Search for <query>\nn                 Jump to next <query> match\nq                 Quit\n```\n\n*If `less` scrolling isn't working in [iTerm2](https://www.iterm2.com/),\ngo to*\n\"Settings\"\n-> \"Advanced\"\n-> \"Scroll wheel sends arrow keys when in alternate screen mode\"\n*and change it to* \"Yes\".\n*[More Info](https://stackoverflow.com/a/37610820)*\n\nUse the [`-p`](#show) / [`--print`](#show) option\nto print to standard output with syntax highlighting:\n\n```bash\n❯ nb show 123 --print\n# Example Title\n\nExample content:\n\n- one\n- two\n- three\n```\n\nUse [`nb show --print --no-color`](#show) to print without syntax highlighting.\n\nWhen [Pandoc](https://pandoc.org/) is available,\nuse the [`-r`](#show) / [`--render`](#show) option to\nrender the note to HTML and open it in your terminal browser:\n\n```bash\nnb show example.md --render\n# opens example.md as an HTML page in w3m, links, or lynx\n```\n\n[`nb show`](#show) also supports previewing other file types in the terminal,\ndepending on the tools available in the environment. To prefer specific tools\nfor certain file types, `nb` provides configuration variables that can be\nset in your `~/.nbrc` file,\nwhich can be opened in your editor with [`nb settings edit`](#settings).\n\nSupported file types and tools include:\n\n- Markdown files ([`$NB_MARKDOWN_TOOL`](#nb_markdown_tool)):\n  - [`bat`](https://github.com/sharkdp/bat)\n  - [`glow`](https://github.com/charmbracelet/glow)\n  - [`lowdown`](https://kristaps.bsd.lv/lowdown)\n  - [`mdcat`](https://github.com/swsnr/mdcat)\n  - [`mdless`](https://github.com/ttscoff/mdless)\n  - [`mdv`](https://github.com/axiros/terminal_markdown_viewer)\n- PDF files:\n  - [`termpdf.py`](https://github.com/dsanson/termpdf.py)\n    with [kitty](https://sw.kovidgoyal.net/kitty/)\n  - [`pdftotext`](https://en.wikipedia.org/wiki/Pdftotext)\n- Audio files ([`$NB_AUDIO_TOOL`](#nb_audio_tool)):\n  - [`mplayer`](https://en.wikipedia.org/wiki/MPlayer)\n  - [`afplay`](https://ss64.com/osx/afplay.html)\n  - [`mpg123`](https://en.wikipedia.org/wiki/Mpg123)\n  - [`ffplay`](https://ffmpeg.org/ffplay.html)\n- [Images](#-images) ([`$NB_IMAGE_TOOL`](#nb_image_tool)):\n  - [`catimg`](https://github.com/posva/catimg)\n  - [Chafa](https://github.com/hpjansson/chafa)\n  - [ImageMagick](https://imagemagick.org/) with a terminal that\n    supports [sixels](https://en.wikipedia.org/wiki/Sixel)\n  - [`imgcat`](https://www.iterm2.com/documentation-images.html) with\n    [iTerm2](https://www.iterm2.com/)\n  - [kitty's `icat` kitten](https://sw.kovidgoyal.net/kitty/kittens/icat.html)\n  - [`termvisage`](https://github.com/AnonymouX47/termvisage)\n  - [`timg`](https://github.com/hzeller/timg)\n  - [`viu`](https://github.com/atanunq/viu)\n- Folders, Directories, Notebooks ([`$NB_DIRECTORY_TOOL`](#nb_directory_tool)):\n  - [`eza`](https://github.com/eza-community/eza)\n  - [`joshuto`](https://github.com/kamiyaa/joshuto)\n  - [`lsd`](https://github.com/lsd-rs/lsd)\n  - [Midnight Commander (`mc`)](https://en.wikipedia.org/wiki/Midnight_Commander)\n  - [`ranger`](https://ranger.github.io/)\n  - [`vifm`](https://vifm.info/)\n- Word Documents:\n  - [Pandoc](https://pandoc.org/) with\n    [`w3m`](https://en.wikipedia.org/wiki/W3m) or\n    [`links`](https://en.wikipedia.org/wiki/Links_(web_browser))\n- Excel, CSV, TSV, and data files ([`$NB_DATA_TOOL`](#nb_data_tool)):\n  - [VisiData](https://www.visidata.org/)\n  - [`sc-im`](https://github.com/andmarti1424/sc-im)\n  - [Tidy-Viewer (`tv`)](https://github.com/alexhallam/tv)\n- EPUB ebooks:\n  - [Pandoc](https://pandoc.org/) with\n    [`w3m`](https://en.wikipedia.org/wiki/W3m) or\n    [`links`](https://en.wikipedia.org/wiki/Links_(web_browser))\n\nWhen using [`nb show`](#show) with other file types or\nif the above tools are not available,\n[`nb show`](#show) opens files in\nyour system's preferred application for each type.\n\n[`nb show`](#show) also provides [options](#show) for\nquerying information about an item. For example, use the\n[`--added`](#show) / [`-a`](#show) and [`--updated`](#show) / [`-u`](#show)\nflags to print the date and time that an item was added or updated:\n\n```bash\n❯ nb show 2 --added\n2020-01-01 01:01:00 -0700\n\n❯ nb show 2 --updated\n2020-02-02 02:02:00 -0700\n```\n\n[`nb show`](#show) is primarily intended for viewing items within the terminal.\nTo view a file in the system's preferred GUI application, use\n[`nb open`](#open).\nTo [browse](#-browsing) rendered items in terminal and GUI web browsers, use\n[`nb browse`](#browse).\n\nFor full [`nb show`](#show) usage information, run [`nb help show`](#show).\n\n##### Shortcut Alias: `nb s`\n\n[`nb show`](#show) can be called using the shortcut alias [`nb s`](#show):\n\n```bash\n# show note by id\nnb s 3\n\n# show note by filename\nnb s example.md\n\n# show note by title\nnb s \"A Document Title\"\n\n# show note by id, alternative\nnb 3 s\n\n# show note 12 in the notebook named \"example\"\nnb s example:12\n\n# show note 12 in the notebook named \"example\", alternative\nnb example:12 s\n\n# show note 12 in the notebook named \"example\", alternative\nnb example:s 12\n```\n\n##### Alias: `nb view`\n\n[`nb show`](#show) can also be invoked with [`nb view`](#show) for convenience:\n\n```bash\n# show note by id\nnb view 3\n\n# show note by filename\nnb view example.md\n\n# show note by title\nnb view \"A Document Title\"\n\n# show note by id, alternative\nnb 3 view\n```\n\n##### Viewing with `browse`\n\nItems can be viewed within terminal and GUI web browsers using\n[`nb browse`](#browse) / [`nb b`](#browse):\n\n```bash\n❯ nb browse text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · edit | +\nDaring Fireball: Markdown (daringfireball.net)\n\nhttps://daringfireball.net/projects/markdown/\n\nRelated\n\n  • https://en.wikipedia.org/wiki/Markdown\n\nComments\n\nSee also:\n\n  • [[text:formats/org]]\n  • [[cli:apps/nb]]\n\nTags\n\n#markup #plain-text\n\nContent\n\nDaring Fireball: Markdown\n\nDownload\n\nMarkdown 1.0.1 (18 KB) — 17 Dec 2004\n\nIntroduction\n\nMarkdown is a text-to-HTML conversion tool for web writers. Markdown allows\nyou to write using an easy-to-read, easy-to-write plain text format, then\nconvert it to structurally valid XHTML (or HTML).\n```\n\nFor more information, see [Browsing](#-browsing).\n\n#### Deleting\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#delete\"><code>nb delete</code></a>,\n    <a href=\"#browse\"><code>nb browse delete</code></a>\n  </sup>\n</p>\n\nTo delete one or more notes, pass any number of\nids, filenames, titles, and other [selectors](#-selectors)\nto [`nb delete`](#delete) (shortcuts: [`nb d`](#delete), [`nb -`](#delete)):\n\n```bash\n# delete item by id\nnb delete 3\n\n# delete item by filename\nnb delete example.md\n\n# delete item by title\nnb delete \"A Document Title\"\n\n# delete item by id, alternative\nnb 3 delete\n\n# delete item 12 in the notebook named \"example\"\nnb delete example:12\n\n# delete item 12 in the notebook named \"example\", alternative\nnb example:12 delete\n\n# delete item 12 in the notebook named \"example\", alternative\nnb example:delete 12\n\n# delete item 345 in the folder named \"example\"\nnb delete example/345\n\n# delete items with the ids 89, 56, and 21\nnb delete 89 56 21\n```\n\nBy default, [`nb delete`](#delete) will display a confirmation prompt.\nTo skip, use the [`--force`](#delete) / [`-f`](#delete) option:\n\n```bash\nnb delete 3 --force\n```\n\n##### Shortcut Aliases: `nb d`, `nb -`\n\n[`nb delete`](#delete) has the aliases [`nb d`](#delete) and [`nb -`](#delete):\n\n```bash\n# delete note by id\nnb d 3\n\n# delete note by filename\nnb d example.md\n\n# delete note by title\nnb - \"A Document Title\"\n\n# delete note by id, alternative\nnb 3 d\n\n# delete note 12 in the notebook named \"example\"\nnb - example:12\n\n# delete note 12 in the notebook named \"example\", alternative\nnb example:12 d\n\n# delete note 12 in the notebook named \"example\", alternative\nnb example:d 12\n```\n\nFor [`nb delete`](#delete) help information, run [`nb help delete`](#delete).\n\n##### Deleting with `nb browse`\n\nItems can be deleted within terminal and GUI web browsers using\n[`nb browse delete`](#browse) / [`nb b d`](#browse):\n\n```bash\n❯ nb browse delete example:4\n❯nb · example : 4 · ↓ · edit · - | +\n\n              deleting\n\n[4] example_file.md \"Example Title\"\n\n              [delete]\n\n```\n\nFor more information, see [Browsing](#-browsing).\n\n### 🔖 Bookmarks\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#nb-help\"><code>nb&nbsp;&lt;url&gt;</code></a>,\n    <a href=\"#browse\"><code>nb&nbsp;browse</code></a>,\n    <a href=\"#bookmark\"><code>nb&nbsp;bookmark</code></a>,\n    <a href=\"#open\"><code>nb&nbsp;open</code></a>,\n    <a href=\"#peek\"><code>nb&nbsp;peek</code></a>,\n    <a href=\"#show\"><code>nb&nbsp;show</code></a>\n  </sup>\n</p>\n\n`nb` includes a bookmarking system to conveniently\ncreate, annotate, view, search, [browse](#-browsing), and manage\ncollections of bookmarks.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-bookmarks-gui-gui-terminal.png\"\n        alt=\"nb bookmarks\"\n        width=\"450\">\n</div>\n\nBookmarks in `nb` are stored as\n[simple structured Markdown files](#nb-markdown-bookmark-file-format)\ncontaining information extracted from the bookmarked pages.\n\nTo create a new bookmark, pass a URL as the first argument to `nb`:\n\n```bash\nnb https://example.com\n```\n\n`nb` automatically generates a bookmark using information from the page:\n\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\n`nb` embeds the page content in the bookmark, making it available for\n[full text search](#-search) with [`nb search`](#search) and\nlocally-served, distraction-free [reading and browsing](#-browsing)\nwith [`nb browse`](#browse).\nWhen [Pandoc](https://pandoc.org/) is installed,\nthe HTML page content is converted to Markdown.\nWhen [readability-cli](https://gitlab.com/gardenappl/readability-cli)\nis installed, markup is cleaned up to focus on content. When\n[Chromium](https://www.chromium.org) or\n[Chrome](https://www.google.com/chrome/) is installed on the system,\n`nb` automatically renders JavaScript-dependent pages\nand saves the resulting markup.\n\nMany shells automatically escape special characters in URLs. If a\nURL contains characters that are preventing it from being saved in full,\nURLs can also be enclosed in quotes when passed to `nb`:\n\n```bash\nnb \"https://example.com#sample-anchor\"\n```\n\nIn addition to caching the page content,\nyou can also include a quote from the page in a\n[`## Quote`](#-quote) section\nusing the\n[`-q <quote>`](#bookmark) / [`--quote <quote>`](#bookmark) option:\n\n```bash\nnb https://example.com --quote \"Example quote line one.\n\nExample quote line two.\"\n```\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Quote\n\n> Example quote line one.\n>\n> Example quote line two.\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\nAdd a comment in a [`## Comment`](#-comment) section using the\n[`-c <comment>`](#bookmark) / [`--comment <comment>`](#bookmark) option:\n\n```bash\nnb https://example.com --comment \"Example comment.\"\n```\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Comment\n\nExample comment.\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\nAdd related URLs and [linked](#-linking) [selectors](#-selectors)\nto a [`## Related`](#-related) section using the\n[`-r (<url> | <selector>)`](#bookmark) /\n[`--related (<url> | <selector>)`](#bookmark)\noption:\n\n```bash\nnb https://example.com --related example:123 -r https://example.net\n```\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Related\n\n- [[example:123]]\n- <https://example.net>\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\nBookmarks can be tagged using the\n[`-t <tag1>,<tag2>...`](#bookmark) /\n[`--tags <tag1>,<tag2>...`](#bookmark) option.\nTags are converted into [#hashtags](#-tagging) and\nadded to a [`## Tags`](#-tags) section:\n\n```bash\nnb https://example.com --tags tag1,tag2\n```\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\n[Search](#-search) for tagged bookmarks with\n[`nb search`](#search) / [`nb q`](#search):\n\n```bash\nnb search --tag tag1\n\nnb q -t tag1\n\nnb q \\#tag1\n```\n\n[`nb search`](#search) / [`nb q`](#search)\nautomatically searches archived page content:\n\n```bash\n❯ nb q \"example query\"\n[10] 🔖 example.bookmark.md \"Example Bookmark (example.com)\"\n------------------------------------------------------------\n5:Lorem ipsum example query.\n```\n\nBookmarks can also be encrypted:\n\n```bash\n# create a new password-protected, encrypted bookmark\nnb https://example.com --encrypt\n```\n\nEncrypted bookmarks require a password before they can be viewed or\nopened.\n\nMultiple URLs can be bookmarked with a single command by passing\nmultiple [`<url>`](#bookmark) arguments. Additional arguments will be reused\nfor each bookmark:\n\n```bash\n❯ nb https://example.com https://example.net --tags tag1,tag2 --filename example\nAdded: [1] 🔖 example.bookmark.md \"Example Domain (example.com)\"\nAdded: [2] 🔖 example-1.bookmark.md \"Example Domain (example.net)\"\n```\n\n#### Listing and Filtering Bookmarks\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-bookmarks-gui-terminal-terminal.png\"\n        alt=\"nb bookmark lists\"\n        width=\"500\">\n</div>\n\nBookmarks are included in\n`nb`,\n[`nb ls`](#ls),\n[`nb list`](#list),\nand [`nb browse`](#browse)\nalong with items of other types.\n[`nb bookmark`](#bookmark) and [`nb bookmark list`](#bookmark) can be used to\nlist and filter only bookmarks:\n\n```bash\n❯ nb bookmark\nAdd: nb <url> Help: nb help bookmark\n------------------------------------\n[3] 🔖 🔒 example.bookmark.md.enc\n[2] 🔖 Bookmark Two (example.com)\n[1] 🔖 Bookmark One (example.com)\n\n❯ nb bookmark list two\n[2] 🔖 Bookmark Two (example.com)\n```\n\nBookmarks are also included in `nb`, [`nb ls`](#ls), and [`nb list`](#list):\n\n```bash\n❯ nb\nhome\n----\n[7] 🔖 Bookmark Three (example.com)\n[6] Example Note\n[5] 🔖 Bookmark Two (example.net)\n[4] Sample Note\n[3] 🔖 🔒 example-encrypted.bookmark.md.enc\n[2] Demo Note\n[1] 🔖 Bookmark One (example.com)\n```\n\nUse the [`--type <type>`](#ls) / [`--<type>`](#ls)\noption as a filter to display only bookmarks:\n\n```bash\n❯ nb --type bookmark\n[7] 🔖 Bookmark Three (example.com)\n[5] 🔖 Bookmark Two (example.net)\n[3] 🔖 🔒 example-encrypted.bookmark.md.enc\n[1] 🔖 Bookmark One (example.com)\n\n❯ nb --bookmark\n[7] 🔖 Bookmark Three (example.com)\n[5] 🔖 Bookmark Two (example.net)\n[3] 🔖 🔒 example-encrypted.bookmark.md.enc\n[1] 🔖 Bookmark One (example.com)\n```\n\n`nb` saves the domain in the title, making it easy to filter by domain\nusing any list subcommands:\n\n```bash\n❯ nb example.com\n[7] 🔖 Bookmark Three (example.com)\n[1] 🔖 Bookmark One (example.com)\n```\n\nFor more listing options, see\n[`nb help ls`](#ls),\n[`nb help list`](#list),\nand [`nb help bookmark`](#bookmark).\n\n##### Shortcut Aliases: `nb bk`, `nb bm`\n\n[`nb bookmark`](#bookmark) can also be used with the aliases\n[`nb bk`](#bookmark) and [`nb bm`](#bookmark):\n\n```bash\n❯ nb bk\nAdd: nb <url> Help: nb help bookmark\n------------------------------------\n[7] 🔖 Bookmark Three (example.com)\n[5] 🔖 Bookmark Two (example.net)\n[3] 🔖 🔒 example-encrypted.bookmark.md.enc\n[1] 🔖 Bookmark One (example.com)\n\n❯ nb bm example.net\n[5] 🔖 Bookmark Two (example.net)\n```\n\n#### Viewing Bookmarks\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#browse\"><code>nb&nbsp;browse</code></a>,\n    <a href=\"#open\"><code>nb&nbsp;open</code></a>,\n    <a href=\"#peek\"><code>nb&nbsp;peek</code></a>,\n    <a href=\"#show\"><code>nb&nbsp;show</code></a>\n  </sup>\n</p>\n\n`nb` provides multiple ways to view bookmark files, bookmarked content,\nand bookmarked URLs.\n\nUse [`nb browse`](#browse) (shortcut: [`nb b`](#browse))\nto [browse](#-browsing) bookmarks with cached content,\n<a href=\"#-linking\">[[wiki-style links]]</a>,\nlinked [#tags](#-tagging), and external links:\n\n```bash\n❯ nb browse text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · edit | +\nDaring Fireball: Markdown (daringfireball.net)\n\nhttps://daringfireball.net/projects/markdown/\n\nRelated\n\n  • https://en.wikipedia.org/wiki/Markdown\n\nComments\n\nSee also:\n\n  • [[text:formats/org]]\n  • [[cli:apps/nb]]\n\nTags\n\n#markup #plain-text\n\nContent\n\nDaring Fireball: Markdown\n\nDownload\n\nMarkdown 1.0.1 (18 KB) — 17 Dec 2004\n\nIntroduction\n\nMarkdown is a text-to-HTML conversion tool for web writers. Markdown allows\nyou to write using an easy-to-read, easy-to-write plain text format, then\nconvert it to structurally valid XHTML (or HTML).\n```\n\nFor more information, see [Browsing](#-browsing).\n\n[`nb open`](#open) (shortcut: [`nb o`](#open)) opens the bookmarked URL in\nyour system's primary web browser:\n\n```bash\n# open bookmark by id\nnb open 3\n\n# open bookmark 12 in the notebook named \"example\"\nnb open example:12\n\n# open bookmark 12 in the notebook named \"example\", alternative\nnb example:12 open\n\n# open bookmark 12 in the notebook named \"example\", alternative\nnb example:open 12\n```\n\n*N.B. To use [`nb open`](#open) with\n[WSL](https://docs.microsoft.com/en-us/windows/wsl/install),\ninstall [wslu](https://github.com/wslutilities/wslu).*\n\n[`nb peek`](#peek) (shortcut: [`nb p`](#peek), alias: [`nb preview`](#peek))\nopens the bookmarked URL in your terminal web browser,\nsuch as\n[w3m](https://en.wikipedia.org/wiki/W3m),\n[Links](https://en.wikipedia.org/wiki/Links_(web_browser)), or\n[Lynx](https://en.wikipedia.org/wiki/Lynx_(web_browser)):\n\n```bash\n# peek bookmark by id\nnb peek 3\n\n# peek bookmark 12 in the notebook named \"example\"\nnb peek example:12\n\n# peek bookmark 12 in the notebook named \"example\", alternative\nnb example:12 peek\n\n# peek bookmark 12 in the notebook named \"example\", alternative\nnb example:peek 12\n```\n\n[`nb open`](#open) and [`nb peek`](#peek)\nwork seamlessly with encrypted bookmarks.\n`nb` simply prompts you for the bookmark's password.\n\n[`nb open`](#open) and [`nb peek`](#peek)\nautomatically check whether the URL is still valid.\nIf the page has been removed, `nb` can check\nthe [Internet Archive Wayback Machine](https://archive.org/web/)\nfor an archived copy.\n\nThe preferred terminal web browser can be set using\nthe `$BROWSER` environment variable,\nassigned in `~/.bashrc`, `~/.zshrc`, or similar:\n\n```bash\nexport BROWSER=lynx\n```\n\nWhen `$BROWSER` is not set, `nb` looks for\n[`w3m`](https://en.wikipedia.org/wiki/W3m),\n[`links`](https://en.wikipedia.org/wiki/Links_(web_browser)), and\n[`lynx`](https://en.wikipedia.org/wiki/Lynx_(web_browser))\nand uses the first one it finds.\n\n`$BROWSER` can also be used to easy specify the terminal browser for\nan individual command:\n\n```bash\n❯ BROWSER=links nb 12 peek\n# opens the URL from bookmark 12 in links\n\n❯ BROWSER=w3m nb 12 peek\n# opens the URL from bookmark 12 in w3m\n```\n\n[`nb show`](#show) and [`nb edit`](#edit)\ncan also be used to view and edit bookmark files,\nwhich include the cached page converted to Markdown.\n\n[`nb show <id> --render`](#show) / [`nb show <id> -r`](#show)\ndisplays the bookmark file converted to HTML in the terminal web browser,\nincluding all bookmark fields and the cached page content,\nproviding a cleaned-up, distraction-free, locally-served view of\nthe page content along with all of your notes.\n\n##### Shortcut Aliases: `nb o` and `nb p`\n\n[`nb open`](#open) and [`nb peek`](#peek)\ncan also be used with the shortcut aliases\n[`nb o`](#open) and [`nb p`](#peek):\n\n```bash\n# open bookmark by id\nnb o 3\n\n# open bookmark 12 in the notebook named \"example\"\nnb o example:12\n\n# open bookmark 12 in the notebook named \"example\", alternative\nnb example:12 o\n\n# peek bookmark by id\nnb p 3\n\n# peek bookmark 12 in the notebook named \"example\"\nnb p example:12\n\n# peek bookmark 12 in the notebook named \"example\", alternative\nnb example:12 p\n```\n\n#### Bookmark File Format\n\nBookmarks are identified by a `.bookmark.md` file extension.\nThe bookmark URL is the first URL in the file within `<` and `>` characters.\nTo create a minimally valid bookmark file with [`nb add`](#add):\n\n```bash\nnb add example.bookmark.md --content \"<https://example.com>\"\n```\n\nFor a full overview, see\n[`nb` Markdown Bookmark File Format](#nb-markdown-bookmark-file-format).\n\n#### `bookmark` -- A command line tool for managing bookmarks.\n\n`nb` includes [`bookmark`](#bookmark-help), a full-featured\ncommand line interface for creating, viewing, searching, and editing bookmarks.\n\n[`bookmark`](#bookmark-help) is a shortcut for the\n[`nb bookmark`](#bookmark) subcommand,\naccepting all of the same subcommands and options with identical behavior.\n\nBookmark a page:\n\n```bash\n❯ bookmark https://example.com --tags tag1,tag2\nAdded: [3] 🔖 20200101000000.bookmark.md \"Example Title (example.com)\"\n```\nList and filter bookmarks with\n[`bookmark`](#bookmark) and [`bookmark list`](#bookmark):\n\n```bash\n❯ bookmark\nAdd: bookmark <url> Help: bookmark help\n---------------------------------------\n[3] 🔖 🔒 example.bookmark.md.enc\n[2] 🔖 Example Two (example.com)\n[1] 🔖 Example One (example.com)\n\n❯ bookmark list two\n[2] 🔖 Example Two (example.com)\n```\n\nView a bookmark in your terminal web browser:\n\n```bash\nbookmark peek 2\n```\n\nOpen a bookmark in your system's primary web browser:\n\n```bash\nbookmark open 2\n```\n\nPerform a full text search of bookmarks and archived page content:\n\n```bash\n❯ bookmark search \"example query\"\n[10] 🔖 example.bookmark.md \"Example Bookmark (example.com)\"\n------------------------------------------------------------\n5:Lorem ipsum example query.\n```\n\nSee [`bookmark help`](#bookmark-help) for more information.\n\n### ✅ Todos\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#do\"><code>nb do</code></a>,\n    <a href=\"#tasks\"><code>nb tasks</code></a>,\n    <a href=\"#todo\"><code>nb todo</code></a>,\n    <a href=\"#undo\"><code>nb undo</code></a>\n  </sup>\n</p>\n\nUse [`nb todo`](#todo) (shortcut: [`nb to`](#todo))\nto create, list, and update todos.\n`nb` todos are [structured Markdown documents](#nb-markdown-todo-file-format)\nreferencing a single primary todo,\nwith optional [tasks](#%EF%B8%8F-tasks).\n\nUse [`nb todo add`](#todo) to create a new todo:\n\n```bash\n# create a new todo titled \"Example todo one.\"\n❯ nb todo add \"Example todo one.\"\nAdded: [1] ✔️ [ ] Example todo one.\n\n❯ nb show 1 --print\n# [ ] Example todo one.\n```\n\nUse the [`--due <date>`](#todo) option to add an optional due date in a\n[`## Due`](#-due) section:\n\n```bash\n# create a new todo titled \"Example todo two.\" with a due date of \"2100-01-01\"\n❯ nb todo add \"Example todo two.\" --due \"2100-01-01\"\nAdded: [2] ✔️ [ ] Example todo two.\n\n❯ nb show 2 --print\n# [ ] Example todo two.\n\n## Due\n\n2100-01-01\n```\n\nAdd an optional [description](#-description-1) with the\n[`--description <description>`](#todo)\noption:\n\n```bash\n❯ nb todo add \"Example todo three.\" --description \"Example description.\"\nAdded: [3] ✔️ [ ] Example todo three.\n\n❯ nb show 3 --print\n# [ ] Example todo three.\n\n## Description\n\nExample description.\n```\n\nTodos can have [tasks](#%EF%B8%8F-tasks).\nTasks added with one or more [`--task <task>`](#todo) options\nare represented as a markdown task list and placed in a\n[`## Tasks`](#-tasks) section:\n\n```bash\n❯ nb todo add \"Example todo seven.\" --task \"Task one.\" --task \"Task two.\" --task \"Task three.\"\nAdded: [7] ✔️ [ ] Example todo seven.\n\n❯ nb show 7 --print\n# [ ] Example todo seven.\n\n## Tasks\n\n- [ ] Task one.\n- [ ] Task two.\n- [ ] Task three.\n```\n\nRelated URLs and [linked](#-linking) [selectors](#-selectors)\ncan be added to a [`## Related`](#-related-1) field using the\n[`-r (<url> | <selector>)`](#todo) / [`--related (<url> | <selector>)`](#todo)\noption:\n\n```bash\n❯ nb todo add \"Example todo four.\" --related example:123 -r https://example.com\nAdded: [4] ✔️ [ ] Example todo four.\n\n❯ nb show 4 --print\n# [ ] Example todo four.\n\n## Related\n\n- [[example:123]]\n- <https://example.com>\n```\n\n[Tags](#-tagging) can be added to todos with the\n[`--tags <tag1>,<tag2>...`](#todo) option:\n\n```bash\n❯ nb todo add \"Example todo five.\" --tags tag1,tag2\nAdded: [5] ✔️ [ ] Example todo five.\n\n❯ nb show 5 --print\n# [ ] Example todo five.\n\n## Tags\n\n#tag1 #tag2\n```\n\n[Tags](#-tagging), [links](#-linking), and URLs can be\n[browsed](#-browsing)\nin terminal and GUI web browsers with [`nb browse`](#browse).\n\n#### Listing Todos\n\nList todos in with [`nb todos`](#todo):\n\n```bash\n# list todos in the current notebook\n❯ nb todos\n[6] ✔️ [ ] Example todo six.\n[5] ✅ [x] Example todo five.\n[4] ✔️ [ ] Example todo four.\n[3] ✅ [x] Example todo three.\n[2] ✅ [x] Example todo two.\n[1] ✔️ [ ] Example todo one.\n\n# list todos in the notebook named \"sample\"\n❯ nb todos sample:\n[sample:4] ✅ [x] Sample todo four.\n[sample:3] ✔️ [ ] Sample todo three.\n[sample:2] ✔️ [ ] Sample todo two.\n[sample:1] ✅ [x] Sample todo one.\n\n```\n\nOpen / undone todos can be listed with [`nb todos open`](#todo):\n\n```bash\n# list open todos in the current notebook\n❯ nb todos open\n[6] ✔️ [ ] Example todo six.\n[4] ✔️ [ ] Example todo four.\n[1] ✔️ [ ] Example todo one.\n\n# list open todos in the notebook named \"sample\"\n❯ nb tasks open sample:\n[sample:3] ✔️ [ ] Sample todo three.\n[sample:2] ✔️ [ ] Sample todo two.\n```\n\nClosed / done todos can be listed with [`nb todos closed`](#todo):\n\n```bash\n# list closed todos in the current notebook\n❯ nb todos closed\n[5] ✅ [x] Example todo five.\n[3] ✅ [x] Example todo three.\n[2] ✅ [x] Example todo two.\n\n# list closed todos in the notebook named \"sample\"\n❯ nb tasks closed sample:\n[sample:4] ✅ [x] Sample todo four.\n[sample:1] ✅ [x] Sample todo one.\n```\n\nSee\n[`nb help todo`](#todo)\nfor more information.\n\n#### `do` / `undo`\n\nMark a todo as done or closed with [`nb do`](#do):\n\n```bash\n# add a new todo titled \"Example todo six.\"\n❯ nb todo add \"Example todo six.\"\nAdded: [6] ✔️ [ ] Example todo six.\n\n# mark todo 6 as done / closed\n❯ nb do 6\nDone: [6] ✅ [x] Example todo six.\n```\n\nRe-open a closed todo with [`nb undo`](#undo):\n\n```bash\n# mark todo 6 as undone / open\n❯ nb undo 6\nUndone: [6] ✔️ [ ] Example todo six.\n```\n\nSee\n[`nb help do`](#do)\nand\n[`nb help undo`](#undo)\nfor more information.\n\n### ✔️ Tasks\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#do\"><code>nb do</code></a>,\n    <a href=\"#tasks\"><code>nb tasks</code></a>,\n    <a href=\"#todo\"><code>nb todo</code></a>,\n    <a href=\"#undo\"><code>nb undo</code></a>\n  </sup>\n</p>\n\n`nb` can list and update tasks in [todos](#-todos) and other Markdown documents.\n\nTasks are defined as one or more Markdown list items starting with\n`- [ ]` to indicate an open task or `- [x]` to indicate a done / closed task:\n\n```markdown\n- [ ] Example open task.\n- [x] Example closed task.\n```\n\nList tasks in items, folders, and notebooks with\n[`nb tasks`](#tasks) (shortcut: [`nb t`](#tasks)),\nwhich lists both tasks and todos:\n\n```bash\n# list tasks in item 7\n❯ nb tasks 7\n[7] ✔️ [ ] Example todo seven.\n------------------------------\n[7 1] [x] Task one.\n[7 2] [x] Task two.\n[7 3] [ ] Task three.\n\n# list tasks and todos in the notebook named \"example\"\n❯ nb tasks example:\n[example:9] ✔️ [ ] Example todo nine.\n[example:8] ✅ [x] Example todo eight.\n--------------------------------------\n[example:8 1] [x] Task one.\n[example:8 2] [x] Task two.\n\n[example:6] ✔️ [ ] Example todo six.\n[example:4] Example Note Title\n------------------------------\n[example:4 1] [ ] Task one.\n[example:4 2] [x] Task two.\n[example:4 3] [ ] Task three.\n\n[example:3] ✔️ [ ] Example todo three.\n```\n\nOpen / undone tasks can be listed with [`nb tasks open`](#tasks):\n\n```bash\n# list open tasks in item 7\n❯ nb tasks open 7\n[7] ✔️ [ ] Example todo seven.\n------------------------------\n[7 3] [ ] Task three.\n\n# list open tasks and todos in the notebook named \"example\"\n❯ nb tasks open example:\n[example:9] ✔️ [ ] Example todo nine.\n[example:6] ✔️ [ ] Example todo six.\n[example:4] Example Note Title\n------------------------------\n[example:4 1] [ ] Task one.\n[example:4 3] [ ] Task three.\n\n[example:3] ✔️ [ ] Example todo three.\n```\n\nClosed / done tasks can be listed with [`nb tasks closed`](#tasks):\n\n```bash\n# list closed tasks in item 7\n❯ nb tasks closed 7\n[7] ✔️ [ ] Example todo seven.\n------------------------------\n[7 1] [x] Task one.\n[7 2] [x] Task two.\n\n# list closed tasks and todos in the notebook named \"example\"\n❯ nb tasks closed example:\n[example:8] ✅ [x] Example todo eight.\n--------------------------------------\n[example:8 1] [x] Task one.\n[example:8 2] [x] Task two.\n\n[example:4] Example Note Title\n------------------------------\n[example:4 2] [x] Task two.\n```\n\nTasks are identified by the item [selector](#-selectors), followed by\na space, then followed by the sequential number of the task in the file.\n\nUse [`nb do`](#do) to mark tasks as done / closed:\n\n```bash\n# list tasks in item 9\n❯ nb tasks 9\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\n[9 1] [ ] Task one.\n[9 2] [ ] Task two.\n[9 3] [ ] Task three.\n\n# mark task 2 in item 9 as done / closed\n❯ nb do 9 2\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\nDone: [9 2] [x] Task two.\n\n# list tasks in item 9\n❯ nb tasks 9\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\n[9 1] [ ] Task one.\n[9 2] [x] Task two.\n[9 3] [ ] Task three.\n```\n\nUndo a done / closed task with [`nb undo`](#undo):\n\n```bash\n# mark task 2 in item 9 as undone / open\n❯ nb undo 9 2\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\nUndone: [9 2] [ ] Task two.\n\n# list tasks in item 9\n❯ nb tasks 9\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\n[9 1] [ ] Task one.\n[9 2] [ ] Task two.\n[9 3] [ ] Task three.\n```\n\nSee\n[`nb help tasks`](#tasks)\nfor more information.\n\n### 🏷 #tagging\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#add\"><code>nb add</code></a>,\n    <a href=\"#bookmark\"><code>nb bookmark</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>,\n    <a href=\"#list\"><code>nb list</code></a>,\n    <a href=\"#ls\"><code>nb ls</code></a>,\n    <a href=\"#search\"><code>nb search</code></a>\n  </sup>\n</p>\n\nTagging is a flexible and powerful way to organize, filter, and discover your\nnotes, bookmarks, and todos in `nb`.\n\nTags in `nb` are written as `#hashtags`\nand can be placed anywhere within a document. A hashtag is defined as a `#`\ncharacter followed by any number of letters, numbers, underscores, or dashes,\nallowing you to create custom categories or keywords tailored to your workflow.\n\nTagging lets you group related items, quickly search for topics, set up ad hoc\ncollections, and create multi-dimensional taxonomies that complement notebooks\nand folders.\n\nTags can be added when creating or editing items, or embedded\ndirectly in your note content.\n\n#### Nested Tagging\n\nIn addition to standard hashtags, `nb` supports hierarchical tags using\nslashes, such as `#project/design/ui`. This enables an organizational structure\nwhere tags can represent parent-child relationships. For example, tagging a\nnote with `#topic/subtopic/detail` lets you group related notes at different\nlevels of specificity.\n\nWhen searching for tags, nested tags are matched by prefix:\n- Searching for `#project` matches notes tagged with `#project`,\n  `#project/design`, and `#project/design/ui`.\n- Searching for `#project/design` matches `#project/design` and any deeper\n  descendants like `#project/design/ui`.\n- Searching for an exact nested tag like `#project/design/ui` matches only\n  that tag.\n- Searching for a branch that doesn't exist, such as `#project/ui` when only\n  `#project/design/ui` exists, will match nothing.\n\nThis makes it easy to filter, organize, and browse notes and bookmarks using\neither broad or specific tag queries.\n\n#### Adding Tags\n\nNotes and bookmarks can be tagged when they are created using the\n`--tags <tag1>,<tag2>...` option,\nwhich is available with\n[`nb add`](#add),\n[`nb <url>`](#nb-help),\n[`nb browse add`](#browse),\n[`nb bookmark`](#bookmark),\nand\n[`nb todo`](#todo).\n`--tags` takes a comma-separated list of tags, converts them to\n`#hashtags`,\nand adds them to the document.\n\nTags added to notes with [`nb add --tags`](#add) are placed between the title\nand body text:\n\n```bash\n❯ nb add --title \"Example Title\" \"Example note content.\" --tags tag1,tag2\n```\n\n```markdown\n# Example Title\n\n#tag1 #tag2\n\nExample note content.\n```\n\nTags added to [bookmarks](#bookmarks) with\n[`nb <url> --tags`](#nb-help) and [`nb bookmark <url> --tags`](#bookmark)\nare placed in a [`## Tags`](#-tags) section:\n\n```bash\n❯ nb https://example.com --tags tag1,tag2\n```\n\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\nTags added to [todos](#-todos) with\n[`nb todo add --tags`](#todo)\nare placed in a [`## Tags`](#-tags-1) section:\n\n```bash\n❯ nb todo add --tags tag1,tag2 \"Example todo.\"\n```\n\n```markdown\n# [ ] Example todo.\n\n## Tags\n\n#tag1 #tag2\n```\n\n#### Listing and Searching Tags\n\nUse [`nb --tags`](#nb-help), [`nb ls --tags`](#ls),\nand [`nb list --tags`](#list)\nto list the tags present in a notebook, folder, or item:\n\n```bash\n# list all tags found in items in the current notebook\nnb --tags\n\n# list all tags found in the folder named \"example\"\nnb example/ --tags\n\n# list all tags in the item with id 123 in the notebook named \"sample\"\nnb sample:123 --tags\n```\n\nList tagged items by passing `\\#escaped` or `\"#quoted\"` hashtags or tags\nspecified with the [`--tags`](#ls) option to [`nb`](#ls) / [`nb ls`](#ls):\n\n```bash\n# list items in the current notebook tagged with \"#tag1\", escaped\nnb \\#tag1\n\n# list items in the \"example\" notebook tagged with \"#tag2\", quoted\nnb example: \"#tag2\"\n\n# list items in all notebooks tagged with \"#tag3\", long option\nnb --tags tag3 --all\n\n# list items in all notebooks tagged with \"#tag3\", short option\nnb --tags tag3 -a\n```\n\nCombine multiple tags to search for items containing all specified tags:\n\n```bash\n# list items in the current notebook tagged with \"#tag1\" AND \"#tag2\"\nnb \\#tag1 \"#tag2\"\n\n# list items in the current notebook tagged with \"#tag2\" AND \"#tag3\"\nnb --tags tag2,tag3\n\n# list items in all notebooks tagged with \"#tag1\" AND \"#tag2\" AND \"#tag3\" AND \"#tag4\"\nnb \\#tag1 \"#tag2\" --tags tag3,tag4 --all\n```\n\nTagged items can be [searched](#-search) with\n[`nb search`](#search) / [`nb q`](#search):\n\n```bash\n# search for items tagged with \"#tag1\"\nnb search --tag tag1\n\n# search for items tagged with \"#tag1\", shortcut and short option\nnb q -t tag1\n\n# search for items tagged with \"#tag1\", shortcut and argument\nnb q \\#tag1\n\n# search for items tagged with \"#tag1\", shortcut and argument, alternative\nnb q \"#tag1\"\n\n# search for items tagged with \"#tag1\" AND \"#tag2\"\nnb q --tag tag1 --tag tag2\n\n# search for items tagged with \"#tag1\" AND \"#tag2\", short options\nnb q -t tag1 -t tag2\n\n# search for items tagged with \"#tag1\" AND \"#tag2\", arguments\nnb q \\#tag1 \\#tag2\n\n# search for items tagged with \"#tag1\" AND \"#tag2\", tag list\nnb q --tags tag1,tag2\n\n# search for items tagged with either \"#tag1\" OR \"#tag2\", options\nnb q -t tag1 --or -t tag2\n\n# search for items tagged with either \"#tag1\" OR \"#tag2\", arguments\nnb q \\#tag1 --or \\#tag2\n\n# search for items tagged with either \"#tag1\" OR \"#tag2\", single argument\nnb q \"#tag1|#tag2\"\n\n# search for items tagged with \"#tag1\" AND \"#tag2\" AND \"#tag3\"\nnb q -t tag1 --tags tag2,tag3\n\n# search for items tagged with \"#tag1\" OR \"#tag2\" OR \"#tag3\"\nnb q -t tag1 --or --tags tag2,tag3\n\n# search for items tagged with \"#tag1\" OR \"#tag2\" OR \"#tag3\"\nnb q \\#tag1 --or -t tag2 --or \"#tag3\"\n```\n\n#### Browsing Tags\n\nLinked tags can be [browsed](#-browsing) with [`nb browse`](#browse),\nproviding another dimension of browsability in terminal and GUI web browsers,\ncomplimenting <a href=\"#-linking\">[[wiki-style linking]]</a>.\n\nTags in notes,\nbookmarks,\nfiles in text-based formats,\nWord `.docx` documents,\nand [Open Document](https://en.wikipedia.org/wiki/OpenDocument) `.odt` files\nare rendered as links to the list of items in the notebook sharing that tag:\n\n```bash\n❯nb · example : 321\n\nExample Title\n\n#tag1 #tag2\n\nExample content with link to [[Sample Title]].\n\nMore example content:\n\n- one\n- two\n- three\n```\n\nUse the [`-t <tag>`](#browse) / [`--tag <tag>`](#browse) option\nto open [`nb browse`](#browse) to the list of\nall items in the current notebook or a specified notebook or folder that\nshare a tag:\n\n```bash\n# open to a list of items tagged with \"#tag2\" in the \"example\" notebook\n❯ nb browse example: --tag tag2\n❯nb · example\n\nsearch: [#tag2               ]\n\n[example:321] Example Title\n[example:654] Sample Title\n[example:789] Demo Title\n\n# shortcut alias and short option\n❯ nb b example: -t tag2\n❯nb · example\n\nsearch: [#tag2               ]\n\n[example:321] Example Title\n[example:654] Sample Title\n[example:789] Demo Title\n```\n\nFor more information about full-text search, see\n[Search](#-search) and [`nb search`](#search).\nFor more information about browsing, see\n[Browsing](#-browsing) and [`nb browse`](#browse).\n\n### 🔗 Linking\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\nNotes,\nbookmarks,\nfiles in text-based formats,\nWord `.docx` documents,\nand [Open Document](https://en.wikipedia.org/wiki/OpenDocument) `.odt` files\ncan reference other items using\n<a href=\"#-linking\">[[wiki-style links]]</a>,\nmaking `nb` a powerful terminal-first platform for\n[Zettelkasten](#-zettelkasten),\nwiki-style knowledge mapping,\nand other link-based note-taking methods.\n\nTo add a link from a note or bookmark to another in the same notebook,\ninclude the id, title, or relative path for the target item\nwithin double square brackets anywhere in the linking document:\n\n```bash\n# link to the item with id 123 in the root level of current notebook\n[[123]]\n\n# link to the item titled \"Example Title\" in the root level of the current notebook\n[[Example Title]]\n\n# link to the item with id 456 in the folder named \"Sample Folder\"\n[[Sample Folder/456]]\n\n# link to the item titled \"Demo Title\" in the folder named \"Sample Folder\"\n[[Sample Folder/Demo Title]]\n```\n\nTo link to an item in another notebook,\nadd the notebook name with a colon before the identifier:\n\n```bash\n# link to the item with id 123 in the \"sample\" folder in the \"example\" notebook\n[[example:sample/123]]\n\n# link to the item titled \"Example Title\" in the \"demo\" notebook\n[[demo:Example Title]]\n\n# link to the item with filename \"Example File.md\" in the \"sample\" notebook\n[[sample:Example File.md]]\n```\n\nThe text for a link can be specified after a pipe `|` character:\n\n```bash\n# render link to item 123 in the \"example\" notebook as [[Example Link Text]]\n[[example:123|Example Link Text]]\n```\n\n<a href=\"#-linking\">[[wiki-style links]]</a> cooperate well with\n[Org links](https://orgmode.org/guide/Hyperlinks.html),\nwhich have a similar syntax,\nproviding a convenient option for linking collections of Org files.\n\nLinked items can be [browsed](#-browsing) with [`nb browse`](#browse).\n\nFor more information about identifying items, see [Selectors](#-selectors).\n\n### 🌍 Browsing\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\nUse [`nb browse`](#browse) (shortcut: [`nb b`](#browse)) to\nbrowse, view, edit, and search linked notes, bookmarks, notebooks, folders,\nand other items using terminal and GUI web browsers.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/gui-gui-terminal-browse.png\"\n        alt=\"nb browse\"\n        width=\"500\">\n</div>\n\n[`nb browse`](#browse) includes an embedded, terminal-first web application\nthat renders\n<a href=\"#-linking\">[[wiki-style links]]</a>\nand\n[#hashtags](#-tagging)\nas internal links, enabling you to browse your notes and notebooks in web\nbrowsers, including seamlessly browsing to and from the offsite links in\nbookmarks and notes.\n\n```bash\n❯ nb browse\n❯nb · home : +\n\nsearch: [                    ]\n\n[home:6]  📌 Example Markdown Title\n[home:12] 🔒 example-encrypted.md.enc\n[home:11] 🔖 Example Bookmark (example.com)\n[home:10] 🔖 🔒 example-encrypted.bookmark.md.enc\n[home:9]  Example .org Title\n[home:8]  🌄 example-image.png\n[home:7]  📄 example.pdf\n[home:5]  🔉 example-audio.mp3\n[home:4]  Example LaTeX Title\n[home:3]  📹 example-video.mp4\n[home:2]  example.md\n[home:1]  📂 Example Folder\n```\n\nLists are displayed using the same format as `nb` and [`nb ls`](#ls),\nincluding [pinned](#-pinning) items, with each list item linked.\nLists are automatically paginated to fit the height of the terminal window.\n\n```bash\n❯ nb browse example:sample/demo/\n❯nb · example : sample / demo / +\n\nsearch: [                    ]\n\n[example:sample/demo/7] Title Seven\n[example:sample/demo/6] Title Six\n[example:sample/demo/5] Title Five\n[example:sample/demo/4] Title Four\n[example:sample/demo/3] Title Three\n\nnext ❯\n```\n\n[`nb browse`](#browse) is designed to make it easy to navigate within\nterminal web browsers using only keyboard commands,\nwhile also supporting mouse interactions.\nThe [`nb browse`](#browse) interface includes links\nto quickly jump to parent folders,\nthe current notebook,\nand other notebooks.\n\n[`nb browse`](#browse) opens in\n[w3m](https://en.wikipedia.org/wiki/W3m),\n[Links](https://en.wikipedia.org/wiki/Links_\\(web_browser\\)),\nor in the browser set in the `$BROWSER` environment variable.\nUse [`nb browse --gui`](#browse) / [`nb b -g`](#browse) to\nopen in the system's primary [GUI web browser](#browse---gui).\n\nTo open a specific item in [`nb browse`](#browse),\npass the [selector](#-selectors) for the item, folder, or notebook\nto [`nb browse`](#browse):\n\n```bash\n# open the item with id 42 in the folder named \"sample\" in the \"example\" notebook\n❯ nb browse example:sample/42\n❯nb · example : sample / 42 · ↓ · edit | +\n\nExample Title\n\n#tag1 #tag2\n\nExample content with link to [[Demo Title]].\n\nMore example content:\n\n  • one\n  • two\n  • three\n```\n\nItems can also be browsed with\n[`nb show --browse`](#show) / [`nb s -b`](#show),\nwhich behaves identically.\n\n[`nb browse`](#browse) is particularly useful for [bookmarks](#-bookmarks).\nCached content is rendered in the web browser along with comments and notes.\nInternal and external links are easily accessible directly in the terminal,\nproviding a convenient, distraction-free approach for browsing collections\nof bookmarks.\n\n```bash\n❯ nb browse text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · edit | +\nDaring Fireball: Markdown (daringfireball.net)\n\nhttps://daringfireball.net/projects/markdown/\n\nRelated\n\n  • https://en.wikipedia.org/wiki/Markdown\n\nComments\n\nSee also:\n\n  • [[text:formats/org]]\n  • [[cli:apps/nb]]\n\nTags\n\n#markup #plain-text\n\nContent\n\nDaring Fireball: Markdown\n\nDownload\n\nMarkdown 1.0.1 (18 KB) — 17 Dec 2004\n\nIntroduction\n\nMarkdown is a text-to-HTML conversion tool for web writers. Markdown allows\nyou to write using an easy-to-read, easy-to-write plain text format, then\nconvert it to structurally valid XHTML (or HTML).\n```\n\nNotes, bookmarks, files in text-based formats, source code,\nWord `.docx` documents, and\n[Open Document](https://en.wikipedia.org/wiki/OpenDocument) `.odt`\nfiles are converted into HTML and rendered in the browser. Use the down\narrow (`↓`) link to view or download the original file.\n\n[MathJax](https://www.mathjax.org/) support can be enabled by setting\nthe [`$NB_MATHJAX_ENABLED`](https://github.com/xwmx/nb#nb_mathjax_enabled)\nvariable in your `~/.nbrc` file:\n\n```bash\nexport NB_MATHJAX_ENABLED=1\n```\n\nWith this variable set, `nb` will automatically download and install MathJax\nfrom [GitHub](https://github.com/mathjax/MathJax) and enable it when items\nare viewed in [`nb browse --gui`](#browse).\n\n#### `browse edit`\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/gui-terminal-browse-edit.png\"\n        alt=\"nb browse edit\"\n        width=\"500\">\n</div>\n\nItems in text formats can be edited within terminal and GUI web browsers using\nthe `edit` link on the item page or by opening the item with\n[`nb browse edit`](#browse) / [`nb b e`](#browse),\nwhich automatically resizes the form to fit the current terminal window:\n\n```bash\n❯ nb browse edit text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · editing · - | +\n\n[# Daring Fireball: Markdown (daringfireball.net)         ]\n[                                                         ]\n[<https://daringfireball.net/projects/markdown/>          ]\n[                                                         ]\n[## Related                                               ]\n[                                                         ]\n[- <https://en.wikipedia.org/wiki/Markdown>               ]\n[                                                         ]\n[## Comments                                              ]\n[                                                         ]\n[See also:                                                ]\n[                                                         ]\n[- [[text:formats/org]]                                   ]\n[- [[cli:apps/nb]]                                        ]\n[                                                         ]\n[## Tags                                                  ]\n[                                                         ]\n\n[save] · last: 2021-01-01 01:00:00\n```\n\nTerminal web browsers provide different editing workflows.\n[`w3m`](https://en.wikipedia.org/wiki/W3m) opens items in your `$EDITOR`,\nthen returns you back to the browser to save changes and continue browsing.\nEdits in [`links`](https://en.wikipedia.org/wiki/Links_(web_browser))\nare performed directly in the browser.\n\nSyntax highlighting, block selection, and other\n[advanced editor features](#browse---gui-editing)\nare available with [`nb browse --gui`](#browse).\n\n#### `browse add`\n\nAdd an item within the browser using the `+` link or\n[`nb browse add`](#browse) / [`nb b a`](#browse).\nPass a notebook, folder, and / or filename selector to create a new note\nin that location:\n\n```bash\n❯ nb browse add text:formats/\n❯nb · text : formats / +\n\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n\n[add]\n```\n\n[`nb browse add`](#browse) includes options for quickly pre-populating\nnew notes with content:\n\n```bash\n❯ nb browse add --title \"Example Title\" --content \"Example content.\" --tags tag1,tag2\n❯nb · home : +\n\n[# Example Title                                    ]\n[                                                   ]\n[#tag1 #tag2                                        ]\n[                                                   ]\n[Example content.                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n\n[add]\n```\n\n#### `browse delete`\n\nUse the `-` link on the [`nb browse edit`](#browse) page or\n[`nb browse delete`](#browse) / [`nb b d`](#browse)\nto delete an item:\n\n```bash\n❯ nb browse delete example:4\n❯nb · example : 4 · ↓ · edit · - | +\n\n              deleting\n\n[4] example_file.md \"Example Title\"\n\n              [delete]\n\n```\n\n#### `browse` Search\n\n[`nb browse`](#browse) includes a search field powered by\n[`nb search`](#search)\nthat can be used to search the current notebook or folder.\nSearch queries are treated as command line arguments for\n[`nb search`](#search),\nproviding the ability to perform `AND` and `OR` queries.\nUse the\n[`-q <query>`](#browse) / [`--query <query>`](#browse)\noption to open [`nb browse`](#browse) to\nthe results page for a search:\n\n```bash\n# open to a list of items containing \"example\" in the current notebook\n❯ nb browse --query \"example\"\n❯nb · home\n\nsearch: [example             ]\n\n[home:321] Test Title\n[home:654] Sample Title\n[home:789] Demo Title\n\n# using shortcut alias and short option\n❯ nb b -q \"example\"\n❯nb · home\n\nsearch: [example             ]\n\n[home:321] Test Title\n[home:654] Sample Title\n[home:789] Demo Title\n```\n\nSearch for [#tags](#-tagging) with the\n[`-t`](#browse) / [`--tag`](#browse) / [`--tags`](#browse) options:\n\n```bash\n# open to a list of items tagged with \"#tag2\" in the current notebook\n❯ nb browse --tag tag2\n❯nb · home\n\nsearch: [#tag2               ]\n\n[home:654] Sample Title\n[home:789] Demo Title\n\n# using shortcut alias and short option\n❯ nb b -t tag2\n❯nb · home\n\nsearch: [#tag2               ]\n\n[home:654] Sample Title\n[home:789] Demo Title\n```\n\nFor more information about search options, see [Search](#-search) and\n[`nb search`](#search).\n\n#### `browse --gui`\n\nTo open any [`nb browse`](#browse) view in\nthe system's primary GUI web browser,\nadd the [`nb browse --gui`](#browse) / [`nb b -g`](#browse) option:\n\n```bash\n# open the item with id 123 in the \"sample\" notebook in the system's primary GUI browser\nnb browse sample:123 --gui\n\n# open the folder named \"example\" in the system's primary GUI browser,\n# short option\nnb browse example/ -g\n\n# open the current notebook in the system's primary GUI browser,\n# shortcut alias and short option\nnb b -g\n```\n\n##### `browse --gui` Editing\n\nBy default,\n[`nb browse --gui`](#browse)\nuses the browser's default `<textarea>` for editing items.\n\n[Ace](https://ace.c9.io/) is a text editor for GUI web browsers\nthat provides advanced text editing functionality,\nincluding block selection and\n[syntax highlighting](#gui-web-syntax-highlighting).\n\nTo use Ace as the editor for [`nb browse --gui`](#browse),\nadd the following line to set the\n[`$NB_ACE_ENABLED`](https://github.com/xwmx/nb#nb_ace_enabled)\nvariable in your `~/.nbrc` file:\n\n```bash\nexport NB_ACE_ENABLED=1\n```\n\nThe next time a form is loaded in [`nb browse`](#browse),\n`nb` will automatically download\n(from [GitHub](https://github.com/ajaxorg/ace-builds/)),\ninstall,\nand enable the Ace editor in\n[`nb browse edit --gui`](#browse) and [`nb browse add --gui`](#browse).\n\n#### `browse` Portability\n\n[`nb browse`](#browse) depends on\neither [`socat`](https://www.kali.org/tools/socat/)\nor\n[`ncat`](https://nmap.org/ncat/) (available as part of\nthe `ncat` or `nmap` package in most package managers) and\n[`pandoc`](https://pandoc.org/). When neither `socat` nor `ncat` is\navailable and the Bash version is 5.2 or higher, [`nb browse`](#browse)\nfalls back to a pure Bash implementation that supports all features\nexcept the Ace editor. When only `pandoc` is available,\nthe current note is rendered and\n<a href=\"#-linking\">[[wiki-style links]]</a>\ngo to unrendered, original files.\nWhen `socat`,`ncat`, or Bash 5.2+ is available without `pandoc`,\nfiles in plain text formats are rendered with the original markup unconverted.\nIf neither `ncat`, `socat`, Bash 5.2+, nor `pandoc` is available,\n[`nb browse`](#browse) falls back to the default behavior of [`nb show`](#show).\n\nWhen `nb` is installed on Windows,\n`socat` ([MSYS](https://packages.msys2.org/package/socat),\n[Cygwin](https://cygwin.com/packages/summary/socat.html)) is recommended.\n\n#### `browse` Privacy\n\n[`nb browse`](#browse) is completely local and self-contained within `nb`,\nfrom the CSS and JavaScript\nall the way down through the HTTP request parsing and response building,\nwith no imports, libraries, frameworks, or third-party code\noutside of the few binary dependencies\n(`bash`, `git`, `ncat` / `socat`, `pandoc`),\nthe Linux / Unix environment,\nand the optional [Ace editor](#ace-editor).\n\nTerminal web browsers don't use JavaScript, so visits from them are not\nvisible to some web analytics tools.\n[`nb browse`](#browse) includes a number of additional features\nto enhance privacy and avoid leaking information:\n\n- Page content is cached locally within each bookmark file,\n  making it readable in terminal and GUI web browsers\n  without requesting the page again or needing to be connected to the internet.\n- `<img>` tags in bookmarked content are removed to avoid requests.\n- Outbound links are automatically rewritten to use an\n  [exit page redirect](https://geekthis.net/post/hide-http-referer-headers/#exit-page-redirect)\n  to mitigate leaking information via the\n  [referer header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer).\n- All pages include the `<meta name=\"referrer\" content=\"no-referrer\" />` tag.\n- Links include a `rel=\"noopener noreferrer\"` attribute.\n- `lynx` is opened with the `-noreferer` option.\n\n#### `browse` AsciiDoc\n\nTo [`browse`](#browse) items in [AsciiDoc](https://asciidoc.org/) format,\ninstall [`asciidoctor`](https://asciidoctor.org/).\n\n#### Shortcut Alias: `nb b`\n\n[`nb browse`](#browse) can also be used with the alias [`nb b`](#browse):\n\n```bash\n# open the current notebook in the terminal web browser\nnb b\n\n# open the item with id 123 in the \"example\" notebook using the terminal web browser\nnb b example:123\n\n# open the notebook named \"sample\" in the GUI web browser\nnb b sample: -g\n```\n\nFor more information, see [`nb browse`](#browse).\n\n### 🌄 Images\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#browse\"><code>nb browse</code></a>,\n    <a href=\"#import\"><code>nb import</code></a>,\n    <a href=\"#open\"><code>nb open</code></a>,\n    <a href=\"#show\"><code>nb show</code></a>\n  </sup>\n</p>\n\n`nb` can be used to view, organize, browse, reference, and work with images in\nterminals,\nweb browsers,\nand GUI applications.\n\n#### Image Items\n\n[Import](#%EF%B8%8F-import--export) images with [`nb import`](#import):\n\n```bash\n# import the image file \"example.png\" into the current notebook\nnb import example.png\n\n# import an image file from a URL into the current notebook\nnb import https://raw.githubusercontent.com/xwmx/nb/master/docs/images/nb.png\n\n# nb import \"sample.jpg\" into the \"demo\" folder in the \"example\" notebook\nnb import sample.jpg example:demo/\n```\n\nImported images are displayed with [`🌄` indicators](#indicators) in\n[lists](#listing--filtering):\n\n```bash\n❯ nb\nhome\n----\n[5] Example Five\n[4] 🌄 example-image.png\n[3] Example Three\n[2] Example Two\n[1] Example One\n```\n\nImported image items can be opened in the system GUI application for\nthe item's file type using [`nb open`](#open):\n\n```bash\n# open the image \"example-image.png\" in the system GUI photo viewer\nnb open example-image.png\n\n# open the image with id \"4\" in the system GUI photo viewer\nnb 4 o\n```\n\nImage items can be viewed in web browsers with [`nb browse`](#browse),\nproviding a convenient mechanism for\n[browsing](#-browsing) notebooks and folders containing image collections.\n\n[`nb browse`](#browse) renders image items within in an `<img>` tag\non the item page. Open the item page for an image item by passing a\n[selector](#-selectors) to [`nb browse`](#browse), optionally including the\n[`-g`](#browse) / [`--gui`](#browse) option\nto open the page in the system GUI web browser:\n\n```bash\n# open item with id \"123\" in the terminal web browser\nnb browse 123\n\n# open item with id \"456\" in the \"example\" notebook in the GUI web browser\nnb browse example:456 --gui\n\n# open item \"example:456\" in the GUI web browser, alternative\nnb example:456 b -g\n```\n\nThe original file can be viewed or downloaded from the item page\nby either clicking the image item or using the down arrow (`↓`) link.\n\n[`nb browse --gui`](#browse---gui) displays images in any GUI web browser.\nSome terminal web browsers, such as [`w3m`](http://w3m.sourceforge.net/),\ncan be configured to display images.\n\n[`nb show`](#show) can display images directly in the terminal with\nsupported tools and configurations, including:\n\n- [`catimg`](https://github.com/posva/catimg)\n- [Chafa](https://github.com/hpjansson/chafa)\n- [ImageMagick](https://imagemagick.org/) with a terminal that\n  supports [sixels](https://en.wikipedia.org/wiki/Sixel)\n- [`imgcat`](https://www.iterm2.com/documentation-images.html) with\n  [iTerm2](https://www.iterm2.com/)\n- [kitty's `icat` kitten](https://sw.kovidgoyal.net/kitty/kittens/icat.html)\n- [`termvisage`](https://github.com/AnonymouX47/termvisage)\n- [`timg`](https://github.com/hzeller/timg)\n- [`viu`](https://github.com/atanunq/viu)\n\nA preferred image viewer tool can be set with the\n[`$NB_IMAGE_TOOL`](#nb_image_tool) variable in your `~/.nbrc` file,\nwhich can be opened in your editor with [`nb settings edit`](#settings).\n\n#### Inline Images\n\nImages can be referenced and rendered inline within\nnotes, bookmarks, and other items.\n\nTo reference an image in the same notebook,\nspecify the image's relative path within the notebook:\n\n```markdown\n# reference \"example.jpg\" from markdown\n![](example.jpg)\n\n# reference \"demo.png\" in the \"sample\" folder from markdown\n![](sample/demo.png)\n```\n\nImages in any notebook can be referenced using the `--original` URL,\nobtainable from the image's [`nb browse`](#browse) item page\nby either clicking the image item or using the down arrow (`↓`) link.\n\n```markdown\n# reference \"example.jpg\" in the \"home\" notebook with the --original URL\n![](http://localhost:6789/--original/home/example.jpg)\n```\n\nImage references in content are rendered inline within web browsers with\n[`nb browse`](#browse) and [`nb show --render`](#show).\n\n`<img>` tags are stripped from bookmarked content when rendering to HTML.\nInline images can still be used in other bookmark sections like\n[`## Comment`](#-comment).\n\n### 🗂 Zettelkasten\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a>\n  </sup>\n</p>\n\nZettelkasten (German: \"slip box\") is a method of note-taking and\npersonal knowledge management modeled around a few key features:\n\n- Notes are taken liberally on index cards.\n- Each note is numbered for easy reference.\n- Index cards are organized into boxes.\n- Index cards can reference other index cards.\n- Cards can include tags and other metadata.\n\nSince `nb` works directly on plain text files\norganized in normal system directories in normal git repositories,\n`nb` is a very close digital analogue to physical zettelkasten note-taking.\n\n|    Zettelkasten   |                       `nb`                      |\n|:-----------------:|:-----------------------------------------------:|\n| index cards       | [notes](#-notes) & [bookmarks](#-bookmarks)     |\n| numbering         | ids & [selectors](#-selectors)                  |\n| slip boxes        | [notebooks](#-notebooks)                        |\n| tags              | [#tags](#-tagging)                              |\n| metadata          | [front matter](#front-matter)                   |\n| cross-references  |  <a href=\"#-linking\">[[wiki-style links]]</a>   |\n| fast note-taking  | [`nb add`](#adding)/[`nb <url>`](#-bookmarks)   |\n\nFor more information about Zettelkasten, see\n[Wikipedia](https://en.wikipedia.org/wiki/Zettelkasten).\n\n### 📂 Folders\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#add\"><code>nb add</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>,\n    <a href=\"#folders\"><code>nb folders</code></a>,\n    <a href=\"#list\"><code>nb list</code></a>,\n    <a href=\"#ls\"><code>nb ls</code></a>\n  </sup>\n</p>\n\nItems can be organized in folders.\nTo add a note to a folder,\ncall [`nb add`](#add) with the folder's relative path within the notebook\nfollowed by a slash:\n\n```bash\n# add a new note in the folder named \"example\"\nnb add example/\n\n# add a new note in the folder named \"demo\" in \"example\"\nnb add example/demo/\n```\n\n`nb` automatically creates any intermediate folders as needed.\n\nFolders can be created directly using [`nb add folder`](#add),\n[`nb folders add`](#folders), and [`nb add --type folder`](#add):\n\n```bash\n# create a new folder named \"sample\"\nnb add folder sample\n\n# create a new folder named \"sample\", alternative\nnb folders add sample\n\n# create a new folder named \"demo\"\nnb add demo --type folder\n\n# create a folder named \"example\" containing a folder named \"test\"\nnb add example/test --type folder\n```\n\nTo list the items in a folder, pass the folder relative path to\n`nb`,\n[`nb ls`](#ls),\n[`nb list`](#list),\nor [`nb browse`](#browse)\nwith a trailing slash:\n\n```bash\n❯ nb example/demo/\nhome\n----\n[example/demo/3] Title Three\n[example/demo/2] Title Two\n[example/demo/1] Title One\n```\n\nFolders can also be identified by the folder's id\nand listed with a trailing slash:\n\n```bash\n❯ nb list\n[1] 📂 example\n\n❯ nb list 1/\n[example/2] 📂 demo\n[example/1] document.md\n\n❯ nb list 1/2/\n[example/demo/3] Title Three\n[example/demo/2] Title Two\n[example/demo/1] Title One\n```\n\nItems in folders can be idenitified with\nthe folder's relative path using either folder ids or names,\nfollowed by the id, title, or filename of the item:\n\n```bash\n# list item 1 (\"Title One\", one.md) in the example/demo/ folder\nnb list example/demo/1\n\n# edit item 1 (\"Title One\", one.md) in the example/demo/ folder\nnb edit example/2/one.md\n\n# show item 1 (\"Title One\", one.md) in the example/demo/ folder\nnb show 1/2/Title\\ One\n\n# delete item 1 (\"Title One\", one.md) in the example/demo/ folder\nnb delete 1/demo/1\n```\n\nFor folders and items in other notebooks,\ncombine the relative path with the notebook name, separated by a colon:\n\n```bash\n# list the contents of the \"sample\" folder in the \"example\" notebook\nnb example:sample/\n\n# add an item to the \"sample/demo\" folder in the \"example\" notebook\nnb add example:sample/demo/\n\n# edit item 3 in the \"sample/demo\" folder in the \"example\" notebook\nnb edit example:sample/demo/3\n```\n\n[Browse](#-browsing) starting at any folder with [`nb browse`](#browse):\n\n```bash\n❯ nb browse example:sample/demo/\n❯nb · example : sample / demo /\n\nsearch: [                    ]\n\n[example:sample/demo/5] Title Five\n[example:sample/demo/4] Title Four\n[example:sample/demo/3] Title Three\n[example:sample/demo/2] Title Two\n[example:sample/demo/1] Title One\n```\n\nFor more information about identifying folders, see [Selectors](#-selectors).\n\n### 📌 Pinning\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#pin\"><code>nb pin</code></a>,\n    <a href=\"#unpin\"><code>nb unpin</code></a>,\n    <a href=\"#ls\"><code>nb ls</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\nItems can be pinned so they appear first in\n`nb`, [`nb ls`](#ls), and [`nb browse`](#browse):\n\n```bash\n❯ nb\nhome\n----\n[2] 📌 Title Two\n[5] Title Five\n[4] Title Four\n[3] Title Three\n[1] Title One\n```\n\nUse [`nb pin`](#pin) and [`nb unpin`](#unpin) to pin and unpin items:\n\n```bash\n❯ nb\nhome\n----\n[5] Title Five\n[4] Title Four\n[3] Title Three\n[2] Title Two\n[1] Title One\n\n❯ nb pin 4\nPinned: [4] four.md \"Title Four\"\n\n❯ nb pin 1\nPinned: [1] one.md \"Title One\"\n\n❯ nb\nhome\n----\n[4] 📌 Title Four\n[1] 📌 Title One\n[5] Title Five\n[3] Title Three\n[2] Title Two\n\n❯ nb unpin 4\nUnpinned: [4] four.md \"Title Four\"\n\n❯ nb\nhome\n----\n[1] 📌 Title One\n[5] Title Five\n[4] Title Four\n[3] Title Three\n[2] Title Two\n```\n\n`nb` can also be configured to pin notes that contain\na specified [#hashtag](#-tagging) or other search pattern.\nTo enable tag / search-based pinning,\nset the [`$NB_PINNED_PATTERN`](#nb_pinned_pattern) environment variable to\nthe desired [#tag](#-tagging) or pattern.\n\nFor example, to treat all items tagged with `#pinned` as pinned items,\nadd the following line to your `~/.nbrc` file,\nwhich can be opened in your editor with [`nb settings edit`](#settings):\n\n```bash\nexport NB_PINNED_PATTERN=\"#pinned\"\n```\n\nAll [indicator icons](#indicators) in `nb` can be customized, so\nto use a different character as the pindicator,\nsimply add a line like the following to your `~/.nbrc` file:\n\n```bash\nexport NB_INDICATOR_PINNED=\"💖\"\n```\n\n```bash\n❯ nb\nhome\n----\n[1] 💖 Title One\n[5] Title Five\n[4] Title Four\n[3] Title Three\n[2] Title Two\n```\n\nTo bump an item to the top of the list without pinning, use the\n[`bump` plugin](#bump).\n\n### 🔍 Search\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#search\"><code>nb search</code></a>\n  </sup>\n</p>\n\nUse [`nb search`](#search) (shortcut: [`nb q`](#search)) to\nperform full text searches, with support for regular expressions,\n[#tags](#-tagging), and `AND`, `OR`, and `NOT` queries:\n\n```bash\n# search current notebook for \"example query\"\nnb search \"example query\"\n\n# search the notebook \"example\" for \"example query\"\nnb search example: \"example query\"\n\n# search the folder named \"demo\" for \"example query\"\nnb search demo/ \"example query\"\n\n# search all unarchived notebooks for \"example query\" and list matching items\nnb search \"example query\" --all --list\n\n# search for \"example\" AND \"demo\" with multiple arguments\nnb search \"example\" \"demo\"\n\n# search for \"example\" AND \"demo\" with option\nnb search \"example\" --and \"demo\"\n\n# search for \"example\" OR \"sample\" with argument\nnb search \"example|sample\"\n\n# search for \"example\" OR \"sample\" with option\nnb search \"example\" --or \"sample\"\n\n# search for items matching both \"Example\" AND \"Sample\", and NOT \"Demo\"\nnb search \"Example\" --and \"Sample\" --not \"Demo\"\n\n# search items containing the hashtag \"#example\"\nnb search \"#example\"\n\n# search with a regular expression\nnb search \"\\d\\d\\d-\\d\\d\\d\\d\"\n\n# search bookmarks for \"example\"\nnb search \"example\" --type bookmark\n\n# search bookmarks for \"example\", alternative\nnb bk q \"example\"\n\n# search the current notebook for \"example query\"\nnb q \"example query\"\n\n# search the notebook named \"example\" for \"example query\"\nnb q example: \"example query\"\n\n# search all unarchived notebooks for \"example query\" and list matching items\nnb q -la \"example query\"\n```\n\n[`nb search`](#search) prints the id number, filename,\nand title of each matched file,\nfollowed by each search query match and its line number,\nwith color highlighting:\n\n```bash\n❯ nb search \"example\"\n[314]  🔖 example.bookmark.md \"Example Bookmark (example.com)\"\n--------------------------------------------------------------\n1:# Example Bookmark (example.com)\n\n3:<https://example.com>\n\n[2718] example.md \"Example Note\"\n--------------------------------\n1:# Example Note\n```\n\nTo just print the note information line without the content matches,\nuse the [`-l`](#search) or [`--list`](#search) option:\n\n```bash\n❯ nb search \"example\" --list\n[314]  🔖 example.bookmark.md \"Example Bookmark (example.com)\"\n[2718] example.md \"Example Note\"\n```\n\nMultiple query arguments are treated as `AND` queries,\nreturning items that match all queries.\n`AND` queries can also be specified with the\n[`--and <query>`](#search) option:\n\n```bash\n# search for items tagged with \"#example\" AND \"#demo\" AND \"#sample\" using\n# multiple arguments\nnb q \"#example\" \"#demo\" \"#sample\"\n\n# options\nnb q \"#example\" --and \"#demo\" --and \"#sample\"\n```\n\n`nb` matches `AND` query terms regardless of where they appear in a document,\nan improvement over most approaches for performing `AND` queries\nwith command line tools,\nwhich typically only match terms appearing on the same line.\n\n`OR` queries return items that match at least one of the queries\nand can be created by separating terms in a single argument\nwith a pipe character `|` or with the [`--or <query>`](#search) option:\n\n```bash\n# search for \"example\" OR \"sample\" with argument\nnb q \"example|sample\"\n\n# search for \"example\" OR \"sample\" with option\nnb q \"example\" --or \"sample\"\n```\n\n[`--or`](#search) and [`--and`](#search) queries can be used together:\n\n```bash\nnb q \"example\" --or \"sample\" --and \"demo\"\n# equivalent: example|sample AND demo|sample\n```\n\n`NOT` queries exclude items that match the specified query and are\nspecified with [`--not <query>`](#search), which can be used with\n`--and` and `--or`:\n\n```bash\n# search for items that match \"Example\", excluding items that also match \"Sample\"\nnb search \"Example\" --not \"Sample\"\n\n# search for items matching both \"Example\" AND \"Sample\", and NOT \"Demo\"\nnb search \"Example\" --and \"Sample\" --not \"Demo\"\n```\n\nSearch for [#tags](#-tagging) with flexible\n[`nb search --tags [<tags>]`](#search) / [`nb q -t [<tags>]`](#search) options:\n\n```bash\n# search for tags in the current notebook\nnb search --tags\n\n# search for tags in the \"sample\" notebook, shortcut alias\nnb sample:q --tags\n\n# search for items tagged with \"#tag1\"\nnb search --tag tag1\n\n# search for items tagged with \"#tag1\", shortcut alias and short option\nnb q -t tag1\n\n# search for items tagged with \"#tag1\", shortcut alias and argument\nnb q \\#tag1\n\n# search for items tagged with \"#tag1\", shortcut alias and argument, alternative\nnb q \"#tag1\"\n\n# search for items in the \"sample\" notebook tagged with \"#tag1\" AND \"#tag2\"\nnb sample:search --tag tag1 --tag tag2\n\n# search for items in the \"sample\" notebook tagged with \"#tag1\" AND \"#tag2\"\nnb sample:q --tags tag1,tag2\n\n# search for items in the current notebook tagged with \"#tag1\" AND \"#tag2\"\nnb q --tag tag1 --tag tag2\n\n# search for items in the current notebook tagged with \"#tag1\" OR \"#tag2\"\nnb q -t tag1 --or -t tag2\n\n# search for items tagged with \"#tag1\" AND \"#tag2\" AND \"#tag3\"\nnb q -t tag1 --tags tag2,tag3\n\n# search for items tagged with \"#tag1\" OR \"#tag2\" OR \"#tag3\"\nnb q -t tag1 --or --tags tag2,tag3\n\n# search for items tagged with \"#tag1\" OR \"#tag2\" OR \"#tag3\"\nnb q \\#tag1 --or -t tag2 --or \"#tag3\"\n```\n\n[`nb search`](#search) leverages Git's powerful built-in\n[`git grep`](https://git-scm.com/docs/git-grep).\n`nb` also supports performing searches with alternative search tools\nusing the [`--utility <name>`](#search) option.\n\nSupported alternative search tools:\n- [`rga`](https://github.com/phiresky/ripgrep-all)\n- [`rg`](https://github.com/BurntSushi/ripgrep)\n- [`ag`](https://github.com/ggreer/the_silver_searcher)\n- [`ack`](https://beyondgrep.com/)\n- [`grep`](https://en.wikipedia.org/wiki/Grep)\n\n##### Shortcut Alias: `nb q`\n\n[`nb search`](#search) can also be used with the alias\n[`nb q`](#search) (for \"query\"):\n\n```bash\n# search for \"example\" and print matching excerpts\nnb q \"example\"\n\n# search for \"example\" and list each matching file\nnb q -l \"example\"\n\n# search for \"example\" in all unarchived notebooks\nnb q -a \"example\"\n\n# search for \"example\" in the notbook named \"sample\"\nnb sample:q \"example\"\n```\n\nFor more information about search, see [`nb help search`](#search).\n\n##### Searching with `browse`\n\nSearches can be performed within terminal and GUI web browsers using\n[`nb browse --query`](#browse) / [`nb b -q`](#browse):\n\n```bash\n❯ nb browse --query \"#example\"\n❯nb · home : +\n\nsearch: [#example             ]\n\n[home:7]   Title Seven\n[home:32]  Title Thirty-Two\n[home:56]  Title Fifty-Six\n[home:135] Title One Hundred and Thirty-Five\n```\n\nFor more information, see [Browsing](#-browsing).\n\n### ↔ Moving & Renaming\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#move\"><code>nb move</code></a>,\n    <a href=\"#copy\"><code>nb copy</code></a>\n  </sup>\n</p>\n\nUse [`nb move`](#move) (alias: [`nb rename`](#move), shortcut: [`nb mv`](#move))\nto move and rename items:\n\n```bash\n# move \"example.md\" to \"sample.org\"\nnb move example.md sample.org\n\n# rename note 2 (\"example.md\") to \"New Name.md\"\nnb rename 2 \"New Name\"\n```\n\nItems can be moved between notebooks and folders:\n\n```bash\n# move note 12 from the \"example\" notebook into \"Sample Folder\" in the \"demo\" notebook\nnb move example:12 demo:Sample\\ Folder/\n```\n\nWhen the file extension is omitted, the existing extension is used:\n\n```bash\n# rename \"example.bookmark.md\" to \"New Name.bookmark.md\"\nnb move example.bookmark.md \"New Name\"\n```\n\nWhen only a file extension is specified, only the extension is updated:\n\n```bash\n# change the file extension of note 5 (\"demo file.md\") to .org (\"demo file.org\")\nnb rename 5 .org\n```\n\nUse [`nb rename --to-bookmark`](#move) to change the extension of a note\nto `.bookmark.md`,\n[`nb rename --to-todo`](#move) to change the extension to `.todo.md`,\nand [`nb rename --to-note`](#move) to change the extension\nof a bookmark or todo to either `.md` or the extension set with\n[`nb set default_extension`](#default_extension):\n\n```bash\n# rename note 3 (\"example.md\") to a bookmark named \"example.bookmark.md\"\nnb rename 3 --to-bookmark\n\n# rename bookmark 6 (\"sample.bookmark.md\") to a note named \"sample.md\"\nnb rename 6 --to-note\n\n# rename note 7 (\"demo.md\") to a todo named \"demo.todo.md\"\nnb rename 7 --to-todo\n```\n\nUse [`nb rename --to-title`](#move) to set the filename to the note title,\nlowercased with spaces and disallowed filename characters replaced\nwith underscores:\n\n```bash\n❯ nb rename 12 --to-title\nMoving:   [12] 20210101010000.md \"Example Title\"\nTo:       example_title.md\nProceed?  [y/N]\n```\n\nCopy an item to a destination notebook, folder path, or filename\nwith [`nb copy`](#copy) (alias: [`nb duplicate`](#copy)):\n\n```bash\n# copy item 456 to \"sample.md\"\nnb copy 456 sample.md\n\n# copy item 678 to the \"example\" notebook\nnb copy 678 example:\n\n# copy item 789 to the \"demo\" folder\nnb copy 789 demo/\n\n# copy item 543 to test.md in the \"sample\" folder in the \"example\" notebook\nnb copy 543 example:sample/test.md\n```\n\nOmit a destination to copy the item in place:\n\n```bash\n# copy item 123 (\"example.md\") to example-1.md\n❯ nb copy 123\nAdded: [124] example-1.md\n\n# copy item 123 (\"example.md\") to example-2.md, alias\n❯ nb duplicate 123\nAdded: [125] example-2.md\n```\n\nFor more information about moving, renaming, and copying items, see\n[`nb help move`](#move) and [`nb help copy`](#copy).\n\n### 🗒 Revision History\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#history\"><code>nb history</code></a>,\n    <a href=\"#notebooks\"><code>nb notebooks</code></a>\n  </sup>\n</p>\n\nWhenever a note is added, modified, or deleted,\n`nb` automatically commits the change to git transparently in the background.\n\nUse [`nb history`](#history) to view the revision history of\nany notebook, folder, or item:\n\n```bash\n# show history for current notebook\nnb history\n\n# show history for note number 4\nnb history 4\n\n# show history for note with filename example.md\nnb history example.md\n\n# show history for note titled \"Example\"\nnb history Example\n\n# show history for the notebook named \"example\"\nnb example:history\n\n# show history for the notebook named \"example\", alternative\nnb history example:\n\n# show the history for note 12 in the notebook named \"example\"\nnb history example:12\n```\n\n[`nb history`](#history) uses `git log` by default and prefers\n[`tig`](https://github.com/jonas/tig) when available.\n\n#### Authorship\n\nBy default, git commits are attributed to the email and name configured in your\n[global `git` configuration](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration).\n\nChange the email and name used for a notebook with\n[`nb notebooks author`](#notebooks):\n\n```bash\n# edit the commit author email and name for the current notebook\n❯ nb notebooks author\nCurrent configuration for: home\n--------------------------\nemail (global): example@example.test\nname  (global): Example Name\n\nUpdate?  [y/N]\n\n# edit the commit author email and name for the notebook named \"example\"\n❯ nb notebooks author example\nCurrent configuration for: example\n--------------------------\nemail (global): example@example.test\nname  (global): Example Name\n\nUpdate?  [y/N]\n```\n\nThe updated author email and name applies to subsequent commits.\n\nTo use a different email and name from the beginning of a notebook's\nhistory, create the new notebook using\n[`nb notebooks add --author`](#notebooks) or\n[`nb notebooks init --author`](#notebooks).\n\n### 📚 Notebooks\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#notebooks\"><code>nb&nbsp;notebooks</code></a>,\n    <a href=\"#archive\"><code>nb&nbsp;archive</code></a>,\n    <a href=\"#unarchive\"><code>nb&nbsp;unarchive</code></a>,\n    <a href=\"#use\"><code>nb&nbsp;use</code></a>\n  </sup>\n</p>\n\nYou can create additional notebooks, each of which has its own version history.\n\nCreate a new notebook with [`nb notebooks add`](#notebooks):\n\n```bash\n# add a notebook named example\nnb notebooks add example\n```\n\n`nb` and [`nb ls`](#ls) list the available notebooks above the list of notes:\n\n```bash\n❯ nb\nexample · home\n--------------\n[3] Title Three\n[2] Title Two\n[1] Title One\n```\n\nCommands in `nb` run within the current notebook, and identifiers\nsuch as ids, filenames, and titles refer to notes within the current notebook.\n`nb edit 3`, for example, tells `nb` to\n[`edit`](#edit) note with id `3` within the current notebook.\n\nTo switch to a different notebook, use [`nb use`](#use):\n\n```bash\n# switch to the notebook named \"example\"\nnb use example\n```\n\nIf you are in one notebook and you want\nto perform a command in a different notebook without switching to it,\nadd the notebook name with a colon before the command name:\n\n```bash\n# add a new note in the notebook \"example\"\nnb example:add\n\n# add a new note in the notebook \"example\", shortcut alias\nnb example:a\n\n# show note 5 in the notebook \"example\"\nnb example:show 5\n\n# show note 5 in the notebook \"example\", shortcut alias\nnb example:s 5\n\n# edit note 12 in the notebook \"example\"\nnb example:edit 12\n\n# edit note 12 in the notebook \"example\", shortcut alias\nnb example:e 12\n\n# search for \"example query\" in the notebook \"example\"\nnb example:search \"example query\"\n\n# search for \"example query\" in the notebook \"example\", shortcut alias\nnb example:q \"example query\"\n\n# show the revision history of the notebook \"example\"\nnb example:history\n```\n\nThe notebook name with colon can also be used as a modifier to\nthe id, filename, or title:\n\n```bash\n# edit note 12 in the notebook \"example\"\nnb edit example:12\n\n# edit note 12 in the notebook \"example\", shortcut alias\nnb e example:12\n\n# edit note 12 in the notebook \"example\", alternative\nnb example:12 edit\n\n# edit note 12 in the notebook \"example\", alternative, shortcut alias\nnb example:12 e\n\n# show note titled \"misc\" in the notebook \"example\"\nnb show example:misc\n\n# show note titled \"misc\" in the notebook \"example\", shortcut alias\nnb s example:misc\n\n# delete note with filename \"todos.md\" in the notebook \"example\", alternative\nnb example:todos.md delete\n\n# delete note with filename \"todos.md\" in the notebook \"example\", alternative,\n# shortcut alias\nnb example:todos.md d\n```\n\nWhen a notebook name with colon is called without a subcommand,\n`nb` runs [`nb ls`](#ls) in the specified notebook:\n\n```bash\n❯ nb example:\nexample · home\n--------------\n[example:3] Title Three\n[example:2] Title Two\n[example:1] Title One\n```\n\nA bookmark can be created in another notebook by specifying\nthe notebook name with colon, then a space, then the URL and bookmark options:\n\n```bash\n# create a new bookmark in a notebook named \"sample\"\n❯ nb sample: https://example.com --tags tag1,tag2\n```\n\nNotes can also be moved between notebooks:\n\n```bash\n# move note 3 from the current notebook to \"example\"\nnb move 3 example:\n\n# move note 5 in the notebook \"example\" to the notebook \"sample\"\nnb move example:5 sample:\n```\n\n##### Example Workflow\n\nThe flexibility of `nb`'s argument handling makes it easy to\nbuild commands step by step as items are listed, filtered, viewed, and edited,\nparticularly in combination with shell history:\n\n```bash\n# list items in the \"example\" notebook\n❯ nb example:\nexample · home\n--------------\n[example:3] Title Three\n[example:2] Title Two\n[example:1] Title One\n\n# filter list\n❯ nb example: three\n[example:3] Title Three\n\n# view item\n❯ nb example:3 show\n# opens item in `less`\n\n# edit item\n❯ nb example:3 edit\n# opens item in $EDITOR\n```\n\n##### Notebooks and Tab Completion\n\n[`nb` tab completion](#tab-completion) is optimized for\nfrequently running commands in various notebooks using the colon syntax,\nso installing the completion scripts is recommended\nand makes working with notebooks easy, fluid, and fun.\n\nFor example, listing the contents of a notebook is usually as simple as typing\nthe first two or three characters of the name,\nthen pressing the `<tab>` key,\nthen pressing `<enter>` / `<return>`:\n\n```bash\n❯ nb exa<tab>\n# completes to \"example:\"\n❯ nb example:\nexample · home\n--------------\n[example:3] Title Three\n[example:2] Title Two\n[example:1] Title One\n```\n\nScoped notebook commands are also available in tab completion:\n\n```bash\n❯ nb exa<tab>\n# completes to \"example:\"\n❯ nb example:hi<tab>\n# completes to \"example:history\"\n```\n\n#### Notebooks, Tags, and Taxonomy\n\n`nb` is optimized to work well with a collection of notebooks, so\nnotebooks are a good way to organize notes and bookmarks by top-level topic.\n\n[#tags](#-tagging) are searchable across notebooks and can be created ad hoc,\nmaking notebooks and tags distinct and complementary organizational systems\nin `nb`.\n\nSearch for a tag in or across notebooks with\n[`nb search`](#search) / [`nb q`](#search):\n\n```bash\n# search for #tag in the current notebook\nnb q --tag tag\n\n# search for #tag in all notebooks, short options\nnb q -t tag -a\n\n# search for #tag in the \"example\" notebook, argument\nnb q example: \"#tag\"\n```\n\n#### Global and Local Notebooks\n\n##### Global Notebooks\n\nBy default, all `nb` notebooks are global, making them\nalways accessible in the terminal regardless of the current working directory.\nGlobal notebooks are stored in the directory configured in\n[`nb set nb_dir`](#nb_dir),\nwhich is `~/.nb` by default.\n\n##### Local Notebooks\n\n`nb` also supports creating and working with local notebooks.\nLocal notebooks are notebooks that are\nanywhere on the system outside of [`$NB_DIR`](#nb_dir-1).\nAny folder can be an `nb` local notebook, which is just a normal folder\nthat has been initialized as a git repository and contains an `nb` .index file.\nInitializing a folder as an `nb` local notebook is a very easy way to\nadd structured git versioning to any folder of documents and other files.\n\nWhen `nb` runs within a local notebook,\nthe local notebook is set as the current notebook:\n\n```bash\n❯ nb\nlocal · example · home\n----------------------\n[3] Title Three\n[2] Title Two\n[1] Title One\n```\n\nA local notebook is always referred to by the name `local`\nand otherwise behaves just like a global notebook\nwhenever a command is run from within it:\n\n```bash\n# add a new note in the local notebook\nnb add\n\n# edit note 15 in the local notebook\nnb edit 15\n\n# move note titled \"Todos\" from the home notebook to the local notebook\nnb move home:Todos local:\n\n# move note 1 from the local notebook to the home notebook\nnb move 1 home:\n\n# search the local notebook for <query string>\nnb search \"query string\"\n\n# search the local notebook and all unarchived global notebooks for <query string>\nnb search \"query string\" --all\n```\n\nLocal notebooks can be created with [`nb notebooks init`](#notebooks):\n\n```bash\n# initialize the current directory as a notebook\nnb notebooks init\n\n# create a new notebook at ~/example\nnb notebooks init ~/example\n\n# clone an existing notebook to ~/example\nnb notebooks init ~/example https://github.com/example/example.git\n```\n\nLocal notebooks can also be created by exporting a global notebook:\n\n```bash\n# export global notebook named \"example\" to \"../path/to/destination\"\nnb notebooks export example ../path/to/destination\n\n# alternative\nnb export example ../path/to/destination\n```\n\nLocal notebooks can also be imported, making them global:\n\n```bash\n# import notebook or folder at \"../path/to/notebook\"\nnb notebooks import ../path/to/notebook\n\n# alternative\nnb import ../path/to/notebook\n```\n\n[`nb notebooks init`](#notebooks) and [`nb notebooks import`](#notebooks)\ncan be used together to easily turn any directory of existing files\ninto a global `nb` notebook:\n\n```bash\n❯ ls\nexample-directory\n\n❯ nb notebooks init example-directory\nInitialized local notebook: /home/username/example-directory\n\n❯ nb notebooks import example-directory\nImported notebook: example-directory\n\n❯ nb notebooks\nexample-directory\nhome\n```\n\n#### Archiving Notebooks\n\n<p>\n  <sup>\n    <a href=\"#-notebooks\">↑</a> ·\n    <a href=\"#archive\"><code>nb&nbsp;archive</code></a>,\n    <a href=\"#status\"><code>nb&nbsp;status</code></a>,\n    <a href=\"#unarchive\"><code>nb&nbsp;unarchive</code></a>\n  </sup>\n</p>\n\nNotebooks can be archived using\n[`nb archive`](#archive) (shortcut: [`nb ar`](#archive)):\n\n```bash\n# archive the current notebook\nnb archive\n\n# archive the notebook named \"example\"\nnb archive example\n\n# archive the current notebook, shortcut alias\nnb ar\n\n# archive the notebook named \"example\", shortcut alias\nnb ar example\n```\n\nWhen a notebook is archived it is not included in\n[`nb`](#ls) / [`nb ls`](#ls) output,\n[`nb search --all`](#search),\nor tab completion,\nnor synced automatically with [`nb sync --all`](#sync).\n\n```bash\n❯ nb\nexample1 · example2 · example3 · [1 archived]\n---------------------------------------------\n[3] Title Three\n[2] Title Two\n[1] Title One\n```\n\nArchived notebooks can still be used individually\nusing normal notebook commands:\n\n```bash\n# switch the current notebook to the archived notebook \"example\"\nnb use example\n\n# run the `list` subcommand in the archived notebook \"example\"\nnb example:list\n```\n\nCheck a notebook's archival status with\n[`nb status`](#status) (shortcut: [`nb st`](#status)) and\n[`nb notebooks status`](#notebooks):\n\n```bash\n# print status information, including archival status, for the current notebook\nnb status\n\n# print status information, including archival status, for the notebook named \"example\"\nnb status example\n\n# print status information, including archival status, for the current notebook,\n# shortcut alias\nnb st\n\n# print status information, including archival status, for the notebook named \"example\",\n# shortcut alias\nnb st example\n\n# print the archival status of the current notebook\nnb notebooks status\n\n# print the archival status of the notebook named \"example\"\nnb notebooks status example\n```\n\nUse [`nb unarchive`](#unarchive) (shortcut: [`nb unar`](#unarchive))\nto unarchive a notebook:\n\n```bash\n# unarchive the current notebook\nnb unarchive\n\n# unarchive the notebook named \"example\"\nnb unarchive example\n```\n\nFor more information about working with notebooks, see\n[`nb help notebooks`](#notebooks),\n[`nb help archive`](#archive),\nand [`nb help unarchive`](#unarchive).\n\nFor technical details about notebooks, see\n[`nb` Notebook Specification](#nb-notebook-specification).\n\n### 🔄 Git Sync\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#remote\"><code>nb remote</code></a>,\n    <a href=\"#sync\"><code>nb sync</code></a>\n  </sup>\n</p>\n\nEach notebook can be synced with a remote git repository by\nsetting the remote URL using [`nb remote`](#remote):\n\n```bash\n# set the current notebook's remote to a private GitHub repository\nnb remote set https://github.com/example/example\n\n# set the remote for the notebook named \"example\"\nnb example:remote set https://github.com/example/example\n```\n\nAny notebook with a remote URL will sync automatically\nevery time a command is run in that notebook.\n\nWhen you use `nb` on multiple systems, you can\nset a notebook on each system to the same remote\nand `nb` will keep everything in sync in the background\nevery time there's a change in that notebook.\n\nSince each notebook has its own git history,\nyou can have some notebooks syncing with remotes\nwhile other notebooks are only available locally on that system.\n\nMany services provide free private git repositories, so\ngit syncing with `nb` is easy, free, and vendor-independent.\nYou can also sync your notes using\nDropbox, Drive, Box, Syncthing, or another syncing tool\nby changing your `nb` directory with\n[`nb set nb_dir <path>`](#nb_dir),\nand git syncing will still work simultaneously.\n\nClone an existing notebook by passing the URL to\n[`nb notebooks add`](#notebooks):\n\n```bash\n# create a new notebook named \"example\" cloned from a private GitLab repository\nnb notebooks add example https://gitlab.com/example/example.git\n```\n\nTurn off syncing for a notebook by removing the remote:\n\n```bash\n# remove the remote from the current notebook\nnb remote remove\n\n# remove the remote from the notebook named \"example\"\nnb example:remote remove\n```\n\nAutomatic git syncing can be turned on or off with\n[`nb set auto_sync`](#auto_sync).\n\nTo sync manually, use [`nb sync`](#sync):\n\n```bash\n# manually sync the current notebook\nnb sync\n\n# manually sync the notebook named \"example\"\nnb example:sync\n```\n\nTo bypass `nb` syncing and run `git` commands directly within a\nnotebook, use [`nb git`](#git):\n\n```bash\n# run `git fetch` in the current notebook\nnb git fetch origin\n\n# run `git status` in the notebook named \"example\"\nnb example:git status\n```\n\n#### Syncing Multiple Notebooks with One Remote\n\nMultiple notebooks can be synced to one remote using orphan branches.\nAn\n[orphan branch](https://git-scm.com/docs/git-checkout#Documentation/git-checkout.txt---orphanltnewbranchgt)\nis a branch with a history that is independent\nfrom the repository's `main`, `master`,\nor equivalent primary branch history.\nTo sync a notebook with a new orphan branch,\nadd the remote using [`nb remote set`](#remote)\nand select the option to create a new orphan branch.\nThe name of orphan branch is derived from notebook name\nand can alternatively be specified as an argument to\n[`nb remote set`](#remote):\n\n```bash\n# set the remote for the current notebook to a remote URL and branch\nnb remote set https://github.com/xwmx/example demo-branch\n```\n\nTo create a notebook using an existing orphan branch on a remote,\npass the branch name to\n[`nb init`](#init),\n[`nb notebooks add`](#notebooks), or\n[`nb notebooks init`](#notebooks) after the URL:\n\n```bash\n# initialize new \"home\" notebook with the branch \"sample-branch\" on the remote\nnb init https://github.com/xwmx/example sample-branch\n\n# add a new \"example\" notebook from the branch \"example-branch\" on the remote\nnb notebooks add example https://github.com/xwmx/example example-branch\n```\n\nTo list all branches on a remote, use [`nb remote branches`](#remote):\n\n```bash\n# list all branches on the current remote\nnb remote branches\n\n# list all branches on a remote repository identified by a URL\nnb remote branches \"https://github.com/xwmx/example\"\n```\n\nFor information about assigning remotes, see [`nb help remote`](#remote).\n\n#### Private Repositories and Git Credentials\n\nSyncing with private repositories requires\nconfiguring git to not prompt for credentials.\nFor repositories cloned over HTTPS,\n[credentials can be cached with git\n](https://docs.github.com/en/free-pro-team@latest/github/using-git/caching-your-github-credentials-in-git).\nFor repositories cloned over SSH,\n[keys can be added to the ssh-agent\n](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent).\n\nUse [`nb sync`](#sync) within a notebook to determine\nwhether your configuration is working.\nIf `nb sync` displays a password prompt,\nthen follow the instructions above to configure your credentials.\nThe password prompt can be used to authenticate, but\n`nb` does not cache or otherwise handle git credentials in any way,\nso there will likely be multiple password prompts during each sync\nif credentials are not configured.\n\n#### Sync Conflict Resolution\n\n`nb` handles git operations automatically, so\nyou shouldn't ever need to use the `git` command line tool directly.\n`nb` merges changes when syncing\nand handles conflicts using a couple different strategies.\n\nWhen [`nb sync`](#sync) encounters a conflict in a text file\nand can't cleanly merge overlapping local and remote changes,\n`nb` saves both versions within the file separated by git conflict markers\nand prints a message indicating which files contain conflicting text.\nUse [`nb edit`](#edit) to remove the conflict markers\nand delete any unwanted text.\n\nFor example, in the following file, the second list item was changed\non two systems, and git has no way to determine which one we want to keep:\n\n```\n# Example Title\n\n- List Item apple\n<<<<<<< HEAD\n- List Item apricot\n=======\n- List Item pluot\n>>>>>>> 719od01... [nb] Commit\n- List Item plum\n```\n\nThe local change is between the lines starting with\n`<<<<<<<` and `=======`,\nwhile the remote change is between the\n`=======` and `>>>>>>>`\nlines.\n\nTo resolve this conflict by keeping both items, simply\nedit the file with [`nb edit`](#edit) and\nremove the lines starting with `<<<<<<<`, `=======`, and `>>>>>>>`:\n\n```\n# Example Title\n\n- List Item apple\n- List Item apricot\n- List Item pluot\n- List Item plum\n```\n\nWhen `nb` encounters a conflict in a binary file,\nsuch as an encrypted note,\nboth versions of the file are saved in the notebook as individual files,\nwith `--conflicted-copy` appended to the filename\nof the version from the remote.\nTo resolve a conflicted copy of a binary file,\ncompare both versions and merge them manually,\nthen delete the `--conflicted-copy`.\n\nIf you do encounter a conflict that `nb` says it can't merge at all,\n[`nb git`](#git) and [`nb run`](#run) can be used to\nperform git and shell operations within the notebook\nto resolve the conflict manually.\nPlease also\n[open an issue](https://github.com/xwmx/nb/issues/new)\nwith any relevant details\nthat could inform a strategy for handling any such cases automatically.\n\n### ↕️ Import / Export\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#import\"><code>nb import</code></a>,\n    <a href=\"#export\"><code>nb export</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\n#### Importing\n\nFiles of any type can be imported into a notebook using\n[`nb import`](#import) (shortcut: [`nb i`](#import)).\n[`nb edit`](#edit) and [`nb open`](#open) open files in\nyour system's default application for that file type.\n\n```bash\n# import an image file\nnb import ~/Pictures/example.png\n\n# open image in your default image viewer\nnb open example.png\n\n# import a .docx file\nnb import ~/Documents/example.docx\n\n# open .docx file in Word or your system's .docx viewer\nnb open example.docx\n```\n\nMultiple filenames and globbing are supported:\n\n```bash\n# import all files and directories in the current directory\nnb import ./*\n\n# import all markdown files in the current directory\nnb import ./*.md\n\n# import example.md and sample.md in the current directory\nnb import example.md sample.md\n```\n\n[`nb import`](#import) can also download and import files directly from the web:\n\n```bash\n# import a PDF file from the web\nnb import https://example.com/example.pdf\n# Imported \"https://example.com/example.pdf\" to \"example.pdf\"\n\n# open example.pdf in your system's PDF viewer\nnb open example.pdf\n```\n\nSome imported file types have [indicators](#indicators) to make them\neasier to identify in lists:\n\n```bash\n❯ nb\nhome\n----\n[6] 📖 example-ebook.epub\n[5] 🌄 example-picture.png\n[4] 📄 example-document.docx\n[3] 📹 example-video.mp4\n[2] 🔉 example-audio.mp3\n[1] 📂 Example Folder\n```\n\n#### Importing Bookmarks\n\nBookmarks exported from Chrome, Firefox, and Edge can be imported with\n[`nb import bookmarks`](#import). A new `nb` bookmark file is created for\neach bookmark.\n\n#### Exporting\n\nNotes, bookmarks, and other files can be exported using [`nb export`](#export).\nIf [Pandoc](https://pandoc.org/) is installed,\nnotes can be automatically converted to any of the\n[formats supported by Pandoc](https://pandoc.org/MANUAL.html#option--to).\nBy default, the output format is determined by the file extension:\n\n```bash\n# export a Markdown note to a .docx Microsoft Office Word document\nnb export example.md /path/to/example.docx\n\n# export a note titled \"Movies\" to an HTML web page.\nnb export Movies /path/to/example.html\n```\n\nFor more control over the `pandoc` options, use the\n[`nb export pandoc`](#export) subcommand:\n\n```bash\n# export note 42 as an epub with pandoc options\nnb export pandoc 42 --from markdown_strict --to epub -o path/to/example.epub\n```\n\n[`nb export notebook`](#export) and [`nb import notebook`](#import) can be\nused to export and import notebooks:\n\n```bash\n# export global notebook named \"example\" to \"../path/to/destination\"\nnb export notebook example ../path/to/destination\n\n# import notebook or folder at \"../path/to/notebook\"\nnb import notebook ../path/to/notebook\n```\n\n[`nb export notebook`](#export) and [`nb import notebook`](#import)\nbehave like aliases for\n[`nb notebooks export`](#notebooks) and [`nb notebooks import`](#notebooks),\nand the subcommands can be used interchangeably.\n\nFor more information about imported and exported notebooks, see\n[Global and Local Notebooks](#global-and-local-notebooks).\n\nFor [`nb import`](#import) and [`nb export`](#export) help information, see\n[`nb help import`](#import) and [`nb help export`](#export).\n\n#### Exporting with `browse`\n\nItems can be exported using terminal and GUI [web browsers](#-browsing).\nUse the down arrow (`↓`) link\non the [`nb browse`](#browse) item page\nto download the original file:\n\n```bash\n❯ nb browse 123\n❯nb · home : 123 · ↓ | +\n\n    example.pdf\n\n```\n\n### ⚙️ `set` & `settings`\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#-variables\">Variables</a>,\n    <a href=\"#settings\"><code>nb settings</code></a>,\n    <a href=\"#unset\"><code>nb unset</code></a>\n  </sup>\n</p>\n\n[`nb set`](#settings) and [`nb settings`](#settings)\nopen the settings prompt,\nwhich provides an easy way to change your `nb` settings.\n\n```bash\nnb set\n```\n\nTo update a setting in the prompt,\nenter the setting name or number and then enter the new value.\n`nb` will add the setting to your `~/.nbrc` configuration file.\n\n#### Example: editor\n\n`nb` can be configured to use a specific command line editor\nusing the `editor` setting.\n\nThe settings prompt for a setting can be started by passing\nthe setting name or number to [`nb set`](#settings):\n\n```bash\n❯ nb set editor\n[6]  editor\n     ------\n     The command line text editor used by `nb`.\n\n     • Example Values:\n\n         atom\n         code\n         emacs\n         hx\n         macdown\n         mate\n         micro\n         nano\n         pico\n         subl\n         vi\n         vim\n\nEDITOR is currently set to vim\n\nEnter a new value, unset to set to the default value, or q to quit.\nValue:\n```\n\nA setting can also be updated without the prompt by\npassing both the name and value to [`nb set`](#settings):\n\n```bash\n# set editor with setting name\n❯ nb set editor code\nEDITOR set to code\n\n# set editor with setting number (6)\n❯ nb set 6 code\nEDITOR set to code\n\n# set the color theme to blacklight\n❯ nb set color_theme blacklight\nNB_COLOR_THEME set to blacklight\n\n# set the default `ls` limit to 10\n❯ nb set limit 10\nNB_LIMIT set to 10\n```\n\nUse [`nb settings get`](#settings) to print the value of a setting:\n\n```bash\n❯ nb settings get editor\ncode\n\n❯ nb settings get 6\ncode\n```\n\nUse\n[`nb unset`](#unset) or\n[`nb settings unset`](#settings)\nto unset a setting and revert to the default:\n\n```bash\n❯ nb unset editor\nEDITOR restored to the default: vim\n\n❯ nb settings get editor\nvim\n```\n\n[`nb set`](#settings) and [`nb settings`](#settings)\nare aliases that refer to the same subcommand,\nso the two subcommand names can be used interchangeably.\n\nFor more information about [`set`](#settings) and [`settings`](#settings), see\n[`nb help settings`](#settings).\n\n### 🎨 Color Themes\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#color_theme\"><code>nb&nbsp;set&nbsp;color_theme</code></a>,\n    <a href=\"#syntax_theme\"><code>nb&nbsp;set&nbsp;syntax_theme</code></a>,\n    <a href=\"#color_primary\"><code>nb&nbsp;set&nbsp;color_primary</code></a>,\n    <a href=\"#color_secondary\"><code>nb&nbsp;set&nbsp;color_secondary</code></a>\n  </sup>\n</p>\n\n`nb` uses color to highlight various interface elements, including\nids and [selectors](#-selectors),\nthe current notebook name,\nthe shell prompt,\ndivider lines,\n[syntax elements](#terminal-syntax-highlighting-theme),\nand links.\n\n`nb` includes several built-in color themes\nand also supports user-defined themes.\nThe current color theme can be set using [`nb set color_theme`](#color_theme):\n\n```bash\nnb set color_theme\n```\n\n#### Built-in Color Themes\n\n##### `blacklight`\n\n| ![blacklight](https://xwmx.github.io/misc/nb/images/nb-theme-blacklight-home.png) | ![blacklight](https://xwmx.github.io/misc/nb/images/nb-theme-blacklight-web.png)  |\n|:--:|:--:|\n|    |    |\n\n##### `console`\n\n| ![console](https://xwmx.github.io/misc/nb/images/nb-theme-console-home.png)       | ![console](https://xwmx.github.io/misc/nb/images/nb-theme-console-web.png)        |\n|:--:|:--:|\n|    |    |\n\n##### `desert`\n\n| ![desert](https://xwmx.github.io/misc/nb/images/nb-theme-desert-home.png)         | ![desert](https://xwmx.github.io/misc/nb/images/nb-theme-desert-web.png)          |\n|:--:|:--:|\n|    |    |\n\n##### `electro`\n\n| ![electro](https://xwmx.github.io/misc/nb/images/nb-theme-electro-home.png)       | ![electro](https://xwmx.github.io/misc/nb/images/nb-theme-electro-web.png)        |\n|:--:|:--:|\n|    |    |\n\n##### `forest`\n\n| ![forest](https://xwmx.github.io/misc/nb/images/nb-theme-forest-home.png)         | ![forest](https://xwmx.github.io/misc/nb/images/nb-theme-forest-web.png)          |\n|:--:|:--:|\n|    |    |\n\n##### `nb` (default)\n\n| ![nb](https://xwmx.github.io/misc/nb/images/nb-theme-nb-home.png)                 | ![nb](https://xwmx.github.io/misc/nb/images/nb-theme-nb-web.png)                  |\n|:--:|:--:|\n|    |    |\n\n##### `ocean`\n\n| ![ocean](https://xwmx.github.io/misc/nb/images/nb-theme-ocean-home.png)           | ![ocean](https://xwmx.github.io/misc/nb/images/nb-theme-ocean-web.png)            |\n|:--:|:--:|\n|    |    |\n\n##### `raspberry`\n\n| ![raspberry](https://xwmx.github.io/misc/nb/images/nb-theme-raspberry-home.png)   | ![raspberry](https://xwmx.github.io/misc/nb/images/nb-theme-raspberry-web.png)    |\n|:--:|:--:|\n|    |    |\n\n##### `smoke`\n\n| ![smoke](https://xwmx.github.io/misc/nb/images/nb-theme-monochrome-home.png)      | ![smoke](https://xwmx.github.io/misc/nb/images/nb-theme-smoke-web.png)            |\n|:--:|:--:|\n|    |    |\n\n##### `unicorn`\n\n| ![unicorn](https://xwmx.github.io/misc/nb/images/nb-theme-unicorn-home.png)       | ![unicorn](https://xwmx.github.io/misc/nb/images/nb-theme-unicorn-web.png)        |\n|:--:|:--:|\n|    |    |\n\n##### `utility`\n\n| ![utility](https://xwmx.github.io/misc/nb/images/nb-theme-utility-home.png)       | ![utility](https://xwmx.github.io/misc/nb/images/nb-theme-utility-web.png)        |\n|:--:|:--:|\n|    |    |\n\n#### Custom Color Themes\n\nColor themes are\n[`nb` plugins](#-plugins) with a `.nb-theme` file extension.\n`.nb-theme` files are expected to contain one `if` statement\ntesting for the theme name\nand setting the color environment variables to `tput` ANSI color numbers:\n\n```bash\n# turquoise.nb-theme\nif [[ \"${NB_COLOR_THEME}\" == \"turquoise\" ]]\nthen\n  export NB_COLOR_PRIMARY=43\n  export NB_COLOR_SECONDARY=38\nfi\n```\n\nView this theme as a complete file:\n[`plugins/turquoise.nb-theme`](https://github.com/xwmx/nb/blob/master/plugins/turquoise.nb-theme)\n\nThemes can be installed using [`nb plugins`](#plugins):\n\n```bash\n❯ nb plugins install https://github.com/xwmx/nb/blob/master/plugins/turquoise.nb-theme\nPlugin installed:\n/home/example/.nb/.plugins/turquoise.nb-theme\n```\n\nOnce a theme is installed,\nuse [`nb set color_theme`](#color_theme) to set it as the current theme:\n\n```bash\n❯ nb set color_theme turquoise\nNB_COLOR_THEME set to turquoise\n```\n\nThe primary and secondary colors can also be overridden individually,\nmaking color themes easily customizable:\n\n```bash\n# open the settings prompt for the primary color\nnb set color_primary\n\n# open the settings prompt for the secondary color\nnb set color_secondary\n```\n\nTo view a table of available colors and numbers, run:\n\n```bash\nnb set colors\n```\n\n#### Terminal Syntax Highlighting Theme\n\n`nb` displays files with syntax highlighting when\n[`bat`](https://github.com/sharkdp/bat),\n[`highlight`](http://www.andre-simon.de/doku/highlight/en/highlight.php),\nor\n[Pygments](https://pygments.org/)\nis installed.\n\nWhen `bat` is installed, syntax highlighting\ncolor themes are available for both light and dark terminal backgrounds.\nTo view a list of available themes\nand set the syntax highlighting color theme,\nuse [`nb set syntax_theme`](#syntax_theme).\n\n#### GUI Web Syntax Highlighting\n\nSyntax highlighting is also available when\nviewing and editing items in text formats with\n[`nb browse --gui`](#browse---gui),\nwhich incorporates the color theme's primary color into the syntax theme:\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-web-pandoc-ruby-utility.png\"\n        alt=\"nb syntax highlighting\"\n        width=\"500\">\n</div>\n\n#### Indicators\n\n`nb` uses emoji characters to represent information about files in lists.\nThese characters are referred to internally as \"indicators\"\nand can be customized by assigning a different character to\nthe indicator's environment variable in your `~/.nbrc` file,\nwhich can be opened with [`nb settings edit`](#settings).\n\nFor example, to use a different indicator for pinned items,\nadd a line like the following to your `~/.nbrc` file:\n\n```bash\nexport NB_INDICATOR_PINNED=\"✨\"\n```\n\nTo turn off an indicator, assign the variable to an empty string:\n\n```bash\nexport NB_INDICATOR_PINNED=\"\"\n```\n\nAvailable indicator [variables](#-variables) with default values:\n\n```bash\nexport  NB_INDICATOR_AUDIO=\"🔉\"\nexport  NB_INDICATOR_BOOKMARK=\"🔖\"\nexport  NB_INDICATOR_DOCUMENT=\"📄\"\nexport  NB_INDICATOR_EBOOK=\"📖\"\nexport  NB_INDICATOR_ENCRYPTED=\"🔒\"\nexport  NB_INDICATOR_FOLDER=\"📂\"\nexport  NB_INDICATOR_IMAGE=\"🌄\"\nexport  NB_INDICATOR_PINNED=\"📌\"\nexport  NB_INDICATOR_TODO=\"✔️ \"\nexport  NB_INDICATOR_TODO_DONE=\"✅\"\nexport  NB_INDICATOR_VIDEO=\"📹\"\n```\n\n### $ Shell Theme Support\n\n- [`astral` Zsh Theme](https://github.com/xwmx/astral) - Displays the\n    current notebook name in the context line of the prompt.\n\n### 🔌 Plugins\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#plugin-help\">Plugin Help</a>,\n    <a href=\"#plugins\"><code>nb plugins</code></a>\n  </sup>\n</p>\n\n`nb` includes support for plugins, which can be used to create new\nsubcommands, design themes, and otherwise extend the functionality of `nb`.\n\n`nb` supports two types of plugins, identified by their file extensions:\n\n<dl>\n  <dt><code>.nb-theme</code></dt>\n  <dd>Plugins defining <a href=\"#custom-color-themes\">color themes</a>.</dd>\n  <dt><code>.nb-plugin</code></dt>\n  <dd>Plugins defining new subcommands and adding functionality.</dd>\n</dl>\n\nPlugins are managed with the [`nb plugins`](#plugins) subcommand and\nare installed in the `${NB_DIR}/.plugins` directory.\n\nPlugins can be installed from either a URL or a path using the\n[`nb plugins install`](#plugins) subcommand.\n\n```bash\n# install a plugin from a URL\nnb plugins install https://raw.githubusercontent.com/xwmx/nb/master/plugins/clip.nb-plugin\n\n# install a plugin from a standard GitHub URL\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/example.nb-plugin\n\n# install a theme from a standard GitHub URL\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/turquoise.nb-theme\n\n# install a plugin from a path\nnb plugins install plugins/example.nb-plugin\n```\n\nThe `<url>` should be the full URL to the plugin file.\n`nb` also recognizes regular GitHub URLs,\nwhich can be used interchangeably with raw GitHub URLs.\n\nInstalled plugins can be listed with [`nb plugins`](#plugins),\nwhich optionally takes a name and prints full paths:\n\n```bash\n❯ nb plugins\nclip.nb-plugin\nexample.nb-plugin\nturquoise.nb-theme\n\n❯ nb plugins clip.nb-plugin\nclip.nb-plugin\n\n❯ nb plugins --paths\n/home/example/.nb/.plugins/clip.nb-plugin\n/home/example/.nb/.plugins/example.nb-plugin\n/home/example/.nb/.plugins/turquoise.nb-theme\n\n❯ nb plugins turquoise.nb-theme --paths\n/home/example/.nb/.plugins/turquoise.nb-theme\n```\n\nUse [`nb plugins uninstall`](#plugins) to uninstall a plugin:\n\n```bash\n❯ nb plugins uninstall example.nb-plugin\nPlugin successfully uninstalled:\n/home/example/.nb/.plugins/example.nb-plugin\n```\n\n#### Creating Plugins\n\nPlugins are written in a Bash-compatible shell scripting language\nand have an `.nb-plugin` extension.\n\n`nb` includes a few example plugins:\n\n- [`example.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/example.nb-plugin)\n- [`clip.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/clip.nb-plugin)\n- [`ebook.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/ebook.nb-plugin)\n\nCreate a new subcommand in three easy steps:\n\n##### 1. Add the new subcommand name with `_subcommands add <name>`:\n\n```bash\n_subcommands add \"example\"\n```\n\n##### 2. Define help and usage text with `_subcommands describe <subcommand> <usage>`:\n\n```bash\n_subcommands describe \"example\" <<HEREDOC\nUsage:\n  nb example\n\nDescription:\n  Print \"Hello, World!\"\nHEREDOC\n```\n\n##### 3. Define the subcommand as a function, named with a leading underscore:\n\n```bash\n_example() {\n  printf \"Hello, World!\\\\n\"\n}\n```\n\nThat's it! 🎉\n\nView the complete plugin:\n[`plugins/example.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/example.nb-plugin)\n\nWith `example.nb-plugin` installed, `nb` includes an `nb example` subcommand\nthat prints \"Hello, World!\"\n\nFor a full example,\n[`clip.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/clip.nb-plugin)\nadd clipboard functionality to `nb` and demonstrates how to create a\nplugin using `nb` subcommands and simple shell scripting.\n\nYou can install any plugin you create locally with\n[`nb plugins install <path>`](#plugins),\nand you can publish it on GitHub, GitLab,\nor anywhere else online and install it with\n[`nb plugins install <url>`](#plugins).\n\n#### API\n\nThe `nb` API is the [command line interface](#nb-help), which is designed for\ncomposability and provides a variety of powerful options for interacting with\nnotes, bookmarks, notebooks, and `nb` functionality. Within plugins,\nsubcommands can be called using their function names, which are named with\nleading underscores. Options can be used to output information in formats\nsuitable for parsing and processing:\n\n```bash\n# print the content of note 3 to standard output with no color\n_show 3 --print --no-color\n\n# list all unarchived global notebook names\n_notebooks --names --no-color --unarchived --global\n\n# list all filenames in the current notebook\n_list --filenames --no-id --no-indicator\n\n# print the path to the current notebook\n_notebooks current --path\n```\n\n`nb` automatically scans arguments for\n[selectors](#-selectors) with notebook names\nand updates the current notebook if a valid one is found.\n\nIdentifier selectors are passed to subcommands as arguments along with\nany subcommand options. Use [`show <selector>`](#show) to query\ninformation about the file specified in the selector. For example, to\nobtain the filename of a selector-specified file, use\n[`show <selector> --filename`](#show):\n\n```bash\n_example() {\n  local _selector=\"${1:-}\"\n  [[ -z \"${_selector:-}\" ]] && printf \"Usage: example <selector>\\\\n\" && exit 1\n\n  # Get the filename using the selector.\n  local _filename=\n  _filename=\"$(_show \"${_selector}\" --filename)\"\n\n  # Rest of subcommand function...\n}\n```\n\n[`notebooks current --path`](#notebooks) returns the path to the current\nnotebook:\n\n```bash\n# _example() continued:\n\n# get the notebook path\nlocal _notebook_path=\n_notebook_path=\"$(_notebooks current --path)\"\n\n# print the file at \"${_notebook_path}/${_filename}\" to standard output\ncat \"${_notebook_path}/${_filename}\"\n```\n\nSee\n[`clip.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/clip.nb-plugin)\nfor a practical example using both [`show <selector>`](#show) and\n[`notebooks current --path`](#notebooks) along with other\nsubcommands called using their underscore-prefixed function names.\n\n### `:/` Selectors\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a>\n  </sup>\n</p>\n\nItems in `nb` are primarily identified using structured arguments called\n\"selectors.\" Selectors are like addresses for notebooks, folders, and items.\nA selector can be as simple as an id like `123` or folder path like `example/`,\nor it can combine multiple elements to identify\nan item in a nested folder within a particular notebook, such as:\n\n```bash\ncli:tools/shellcheck/home-page.bookmark.md\n```\n\nAn item, folder, or notebook selector is constructed by specifying the\nnotebook name, folder path, and / or item identifier\nin the following pattern:\n\n```text\nnotebook:folder/path/item-idenitifer\n```\n\nRepresented in a [docopt](http://docopt.org/)-like format:\n\n```text\n[<notebook>:][<folder-path>/][<id> | <filename> | <title>]\n```\n\nNotebooks are identified by the notebook name followed by a colon.\nFolder and item identifiers without a notebook name refer to\nitems within the current notebook.\nWhen a selector consists of notebook name and colon\nwith no folder path or item identifier,\nthe command runs in the root folder of the notebook:\n\n```bash\n# list items in the \"example\" notebook\nnb example:\n\n# add a new note named \"Example Title\" to the \"example\" notebook\nnb add example: --title \"Example Title\"\n\n# edit item with id \"123\" in the notebook \"example\"\nnb edit example:123\n```\n\nA notebook selector can be combined with a subcommand name to\nrun the command within the notebook:\n\n```bash\n# list all items in the \"example\" notebook and display excerpts\nnb example:list -e\n\n# edit item with id \"123\" in the \"example\" notebook\nnb example:edit 123\n\n# show the git history for the notebook named \"example\"\nnb example:history\n```\n\nFolders are identified by relative path from the notebook root.\nFolders can be referenced by either id or name, and segments\nin nested paths can mix and match names and ids:\n\n```bash\n# list items in the folder named \"sample\" in the folder named demo\"\nnb sample/demo/\n\n# add a new item to the folder named \"demo\" in the folder with id \"3\"\nnb add 3/demo/\n\n# show the history of the folder with id \"4\" in the folder named\n# \"sample\" in the notebook named \"example\"\nnb history example:sample/4/\n```\n\nA trailing slash indicates that the command is expected to operate on\nthe contents of the folder. When a trailing slash is omitted, the\nselector refers to the folder itself:\n\n```bash\n❯ nb list sample\n[1] 📂 sample\n\n❯ nb list sample/\n[sample/3] Title Three\n[sample/2] Title Two\n[sample/1] Title One\n```\n\nFor more information about folders, see [Folders](#-folders).\n\nAn item is identified by id, filename, or title, optionally preceded by\nnotebook name or folder path:\n\n```bash\n# edit item with id \"123\"\nnb edit 123\n\n# open the item titled \"demo title\" in the folder with id \"3\"\nnb open 3/demo\\ title\n\n# show \"file.md\" in the \"sample\" folder in the \"example\" notebook\nnb show example:sample/file.md\n```\n\nItems can also be specified using the full path:\n\n```bash\n# edit \"demo.md\" in the \"sample\" folder in the \"home\" notebook\nnb edit /home/example/.nb/home/sample/demo.md\n```\n\n##### Examples\n\n*Idenitifer Selectors*\n\n```text\n123\nexample.md\ntitle\nrelative/path/to/123\nrelative/path/to/demo.md\nrelative/path/to/title\n/full/path/to/sample.md\nnotebook:123\nnotebook:example.md\nnotebook:title\nnotebook:relative/path/to/123\nnotebook:relative/path/to/demo.md\nnotebook:relative/path/to/title\n```\n\n*Subcommand Selectors*\n\n```text\nnotebook:\nnotebook:show\nnotebook:history\nnotebook:a\nnotebook:q\n```\n\n### `01` Metadata\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#show\"><code>nb show</code></a>\n  </sup>\n</p>\n\nMetadata in `nb` is primarily derived from git, the filesystem, and file\ncontent. For example, displayed timestamps are derived from\n[`git log`](https://git-scm.com/docs/git-log), with [`nb show --added`](#show)\ndisplaying the datetime of the first commit containing the file and\n[`nb show --updated`](#show) displaying the datetime of the last commit in\nwhich the file was modified. Meanwhile, the file system's modified\ntimestamp is used for sorting.\n\n`nb` also uses plain text files to store ids and state information in\ngit, including\n[`.index` files](#index-files),\n[`.pindex` files](#pindex-files),\nand [`.archived` files](#archived-notebooks).\n\n#### Front Matter\n\nUser-defined metadata can be added to notes in `nb` using [front\nmatter](https://jekyllrb.com/docs/front-matter/). Front matter is a\nsimple, human accessible, and future-friendly method for defining metadata\nfields in plain text and is well supported in tools for working with\nMarkdown.\n\nFront matter is defined within a Markdown file with triple-dashed lines\n(`---`) indicating the start and end of the block, with each field represented\nby a key name with a colon followed by the value:\n\n```markdown\n---\ntitle:  Example Title\nauthor: xwmx\nyear:   2021\n---\n\nExample content.\n\nMore example content:\n\n- one\n- two\n- three\n```\n\nAny metadata can be placed in the front matter block. `nb` uses the\n`title:` field for listing, filtering, and selecting items, if one is\npresent, and ignores any other fields.\n\nThe simple `key: value` syntax is suitable for many metadata fields.\nMore complex data can be defined using additional\n[YAML](https://en.wikipedia.org/wiki/YAML)\ncapabilities.\n\n### `❯` Interactive Shell\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#shell\"><code>nb shell</code></a>\n  </sup>\n</p>\n\n`nb` has an interactive shell that can be started with\n[`nb shell`](#shell), [`nb -i`](#nb-help), or [`nb --interactive`](#nb-help):\n\n```bash\n$ nb shell\n__          _\n\\ \\   _ __ | |__\n \\ \\ | '_ \\| '_ \\\n / / | | | | |_) |\n/_/  |_| |_|_.__/\n------------------\nnb shell started. Enter ls to list notes and notebooks.\nEnter help for usage information. Enter exit to exit.\nnb❯ ls\nhome\n----\n[3] Example\n[2] Sample\n[1] Demo\n\nnb❯ edit 3 --content \"New content.\"\nUpdated: [3] Example\n\nnb❯ bookmark https://example.com\nAdded: [4] 🔖 example.bookmark.md \"Example Title (example.com)\"\n\nnb❯ ls\nhome\n----\n[4] 🔖 Example Title (example.com)\n[3] Example\n[2] Sample\n[1] Demo\n\nnb❯ bookmark url 4\nhttps://example.com\n\nnb❯ search \"example\"\n[4] example.bookmark.md \"Example (example.com)\"\n-----------------------------------------------\n1:# Example (example.com)\n\n3:<https://example.com>\n\n[3] example.md \"Example\"\n------------------------\n1:# Example\n\nnb❯ exit\n$\n```\n\nThe `nb` shell recognizes all `nb` subcommands and options,\nproviding a streamlined, distraction-free approach for working with `nb`.\n\n### Shortcut Aliases\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a>\n  </sup>\n</p>\n\nSeveral core `nb` subcommands have shortcut aliases to make\nthem faster to work with:\n\n```bash\n# `a` (add): add a new note named \"example.md\"\nnb a example.md\n\n# `+` (add): add a new note titled \"Example Title\"\nnb + --title \"Example Title\"\n\n# `b` (browse): open the folder named \"sample\" in the web browser\nnb b sample/\n\n# `o` (open): open the URL from bookmark 12 in your web browser\nnb o 12\n\n# `p` (peek): open the URL from bookmark 6 in your terminal browser\nnb p 6\n\n# `e` (edit): edit note 5\nnb e 5\n\n# `d` (delete): delete note 19\nnb d 19\n\n# `d` (delete): delete note 123 in the notebook named \"example:\"\nnb - example:123\n\n# `s` (show): show note 27\nnb s 27\n\n# `q` (search): search notes for \"example query\"\nnb q \"example query\"\n\n# `h` (help): display the help information for the `add` subcommand\nnb h add\n\n# `u` (use): switch to example-notebook\nnb u example-notebook\n```\n\nFor more commands and options, run\n[`nb help`](#nb-help) or\n[`nb help <subcommand>`](#subcommands)\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/gui-browse-themes.png\"\n        alt=\"nb browse themes\"\n        width=\"700\">\n</div>\n\n### `?` Help\n\n<div align=\"center\">\n  <a href=\"#nb-help\">nb</a>&nbsp;·\n  <a href=\"#bookmark-help\">bookmark</a>&nbsp;·\n  <a href=\"#subcommands\">subcommands</a>&nbsp;·\n  <a href=\"#plugin-help\">plugins</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#add\">add</a>&nbsp;·\n  <a href=\"#archive\">archive</a>&nbsp;·\n  <a href=\"#bookmark\">bookmark</a>&nbsp;·\n  <a href=\"#browse\">browse</a>&nbsp;·\n  <a href=\"#completions\">completions</a>&nbsp;·\n  <a href=\"#copy\">copy</a>&nbsp;·\n  <a href=\"#count\">count</a>&nbsp;·\n  <a href=\"#delete\">delete</a>&nbsp;·\n  <a href=\"#do\">do</a>&nbsp;·\n  <a href=\"#edit\">edit</a>&nbsp;·\n  <a href=\"#env\">env</a>&nbsp;·\n  <a href=\"#export\">export</a>&nbsp;·\n  <a href=\"#folders\">folders</a>&nbsp;·\n  <a href=\"#git\">git</a>&nbsp;·\n  <a href=\"#help\">help</a>&nbsp;·\n  <a href=\"#history\">history</a>&nbsp;·\n  <a href=\"#import\">import</a>&nbsp;·\n  <a href=\"#init\">init</a>&nbsp;·\n  <a href=\"#list\">list</a>&nbsp;·\n  <a href=\"#ls\">ls</a>&nbsp;·\n  <a href=\"#move\">move</a>&nbsp;·\n  <a href=\"#notebooks\">notebooks</a>&nbsp;·\n  <a href=\"#open\">open</a>&nbsp;·\n  <a href=\"#peek\">peek</a>&nbsp;·\n  <a href=\"#pin\">pin</a>&nbsp;·\n  <a href=\"#plugins\">plugins</a>&nbsp;·\n  <a href=\"#remote\">remote</a>&nbsp;·\n  <a href=\"#run\">run</a>&nbsp;·\n  <a href=\"#search\">search</a>&nbsp;·\n  <a href=\"#settings\">settings</a>&nbsp;·\n  <a href=\"#shell\">shell</a>&nbsp;·\n  <a href=\"#show\">show</a>&nbsp;·\n  <a href=\"#status\">status</a>&nbsp;·\n  <a href=\"#subcommands-1\">subcommands</a>&nbsp;·\n  <a href=\"#sync\">sync</a>&nbsp;·\n  <a href=\"#tasks\">tasks</a>&nbsp;·\n  <a href=\"#todo\">todo</a>&nbsp;·\n  <a href=\"#unarchive\">unarchive</a>&nbsp;·\n  <a href=\"#undo\">undo</a>&nbsp;·\n  <a href=\"#unpin\">unpin</a>&nbsp;·\n  <a href=\"#unset\">unset</a>&nbsp;·\n  <a href=\"#update\">update</a>&nbsp;·\n  <a href=\"#use\">use</a>&nbsp;·\n  <a href=\"#version\">version</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#overview\">&nbsp;↑&nbsp;</a>\n</div>\n\n#### `nb help`\n\n[↑](#-help) · See also:\n[`help`](#help)\n\n```text\n__          _\n\\ \\   _ __ | |__\n \\ \\ | '_ \\| '_ \\\n / / | | | | |_) |\n/_/  |_| |_|_.__/\n\n[nb] Command line and local web note-taking, bookmarking, and archiving with\nplain text data storage, encryption, filtering and search, pinning, #tagging,\nGit-backed versioning and syncing, Pandoc-backed conversion, global and local\nnotebooks, customizable color themes, [[wiki-style linking]], plugins, and more\nin a single portable, user-friendly script.\n\nHelp:\n  nb help               Display this help information.\n  nb help <subcommand>  View help information for <subcommand>.\n  nb help --colors      View information about color settings.\n  nb help --readme      View the `nb` README file.\n\nUsage:\n  nb\n  nb [<ls-options>...] [<id> | <filename> | <path> | <title> | <notebook>]\n  nb [<url>] [<bookmark options>...]\n  nb add [<notebook>:][<folder-path>/][<filename>] [<content>]\n         [-b | --browse] [-c <content> | --content <content>] [--edit]\n         [-e | --encrypt] [-f <filename> | --filename <filename>]\n         [--folder <folder-path>] [--no-template] [--tags <tag1>,<tag2>...]\n         [--template <template>] [-t <title> | --title <title>] [--type <type>]\n  nb add bookmark [<bookmark-options>...]\n  nb add folder [<name>]\n  nb add todo [<todo-options>...]\n  nb archive [<notebook>]\n  nb bookmark [<ls-options>...]\n  nb bookmark [<notebook>:][<folder-path>/] <url>...\n              [-c <comment> | --comment <comment>] [--edit] [-e | --encrypt]\n              [-f <filename> | --filename <filename>] [--no-request]\n              [-q <quote> | --quote <quote>] [--save-source]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]...\n              [-t <tag1>,<tag2>... | --tags <tag1>,<tag2>...] [--title <title>]\n  nb bookmark [list [<list-options>...]]\n  nb bookmark (open | peek | url) (<id> | <filename> | <path> | <title>)\n  nb bookmark (edit | delete) (<id> | <filename> | <path> | <title>)\n  nb bookmark search <query>\n  nb browse [<notebook>:][<folder-path>/][<id> | <filename> | <title>] [--daemon]\n            [-g | --gui] [-n | --notebooks] [-p | --print] [-q | --query <query>]\n            [-s | --serve] [-t <tag> | --tag <tag> | --tags <tag1>,<tag2>...]\n  nb browse add [<notebook>:][<folder-path>/][<filename>]\n            [-c <content> | --content <content>] [--tags <tag1>,<tag2>...]\n            [-t <title> | --title <title>]\n  nb browse delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb browse edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb completions (check | install [-d | --download] | uninstall)\n  nb copy ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[<notebook>:][<folder-path>/]<filename>]\n  nb count [<notebook>:][<folder-path>/]\n  nb delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])...\n            [-f | --force]\n  nb do ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n        [<task-number>]\n  nb edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [-c <content> | --content <content>] [--edit]\n          [-e <editor> | --editor <editor>] [-l | --last] [--overwrite]\n          [--prepend]\n  nb env [-l | --long]\n  nb env [install | update] [--ace | --mathjax]\n  nb export ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <path> [-f | --force] [<pandoc options>...]\n  nb export notebook <name> [<path>]\n  nb export pandoc ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            [<pandoc options>...]\n  nb folders (add | delete) [<notebook>:][<folder-path>/]<folder-name>\n  nb folders <list-options>...\n  nb git [checkpoint [<message>] | dirty]\n  nb git <git-options>...\n  nb help [<subcommand>] [-p | --print]\n  nb help [-c | --colors] | [-r | --readme] | [-s | --short] [-p | --print]\n  nb history [<notebook>:][<folder-path>/][<id> | <filename> | <title>]\n  nb import [bookmarks | copy | download | move] (<path>... | <url>)\n            [--convert] [<notebook>:][<folder-path>/][<filename>]\n  nb import notebook <path> [<name>]\n  nb init [<remote-url> [<branch>]] [--author] [--email <email>]\n          [--name <name>]\n  nb list [-e [<length>] | --excerpt [<length>]] [--filenames]\n          [-f | --folders-first] [-n <limit> | --limit <limit> | --<limit>]\n          [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n          [--paths] [-s | --sort] [-r | --reverse] [--tags]\n          [-t <type> | --type <type> | --<type>]\n          [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n  nb ls [-a | --all] [-b | --browse] [-e [<length>] | --excerpt [<length>]]\n        [--filenames] [-f | --folders-first] [-g | --gui]\n        [-n <limit> | --limit <limit> | --<limit>] [--no-footer] [--no-header]\n        [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n        [--paths] [-s | --sort] [-r | --reverse] [--tags]\n        [-t <type> | --type <type> | --<type>]\n        [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n  nb move ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          ([<notebook>:][<path>] | --reset | --to-bookmark | --to-note |\n          --to-title | --to-todo) [-f | --force]\n  nb notebooks [<name> | <query>] [--ar | --archived] [--global] [--local]\n               [--names] [--paths] [--unar | --unarchived]\n  nb notebooks add ([<name>] [<remote-url> [<branch>... | --all]]) [--author]\n                   [--email <email>] [--name <name>]\n  nb notebooks (archive | open | peek | status | unarchive) [<name>]\n  nb notebooks author [<name> | <path>] [--email <email>] [--name <name>]\n  nb notebooks current [--path | --selected | --filename [<filename>]]\n                       [--global | --local]\n  nb notebooks delete <name> [-f | --force]\n  nb notebooks (export <name> [<path>] | import <path>)\n  nb notebooks init [<path> [<remote-url> [<branch>]]] [--author]\n                    [--email <email>] [--name <name>]\n  nb notebooks rename <old-name> <new-name>\n  nb notebooks select <selector>\n  nb notebooks show (<name> | <path> | <selector>) [--ar | --archived]\n                    [--escaped | --name | --path | --filename [<filename>]]\n  nb notebooks use <name>\n  nb open ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb peek ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb pin  ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb plugins [<name>] [--paths]\n  nb plugins install [<path> | <url>] [--force]\n  nb plugins uninstall <name> [--force]\n  nb remote [branches [<url>] | remove | rename [<branch-name>] <name>]\n  nb remote [delete <branch-name> | reset <branch-name>]\n  nb remote set <url> [<branch-name>]\n  nb run <command> [<arguments>...]\n  nb search ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <query>... [-a | --all] [--and <query>] [--not <query>] [--or <query>]\n            [-l | --list] [--path] [-t <tag1>,<tag2>... | --tag <tag1>,<tag2>...]\n            [-t | --tags] [--type <type> | --<type>] [--utility <name>]\n  nb set [<name> [<value>] | <number> [<value>]]\n  nb settings [colors [<number> | themes] | edit | list [--long]]\n  nb settings (get | show | unset) (<name> | <number>)\n  nb settings set (<name> | <number>) <value>\n  nb shell [<subcommand> [<options>...] | --clear-history]\n  nb show ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[-a | --added] | [--authors] | [-b | --browse] | --filename | --id |\n          --info-line | --path | [-p | --print] | --relative-path | [-r |\n          --render] | --title | --type [<type>] | [-u | --updated]] [--no-color]\n  nb show <notebook>\n  nb status [<notebook>]\n  nb subcommands [add <name>...] [alias <name> <alias>]\n                 [describe <name> <usage>]\n  nb sync [-a | --all]\n  nb tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n           [open | closed]\n  nb todo add [<notebook>:][<folder-path>/][<filename>] <title>\n              [--description <description>] [--due <date>]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]\n              [--tags <tag1>,<tag2>...] [--task <title>...]\n  nb todo do   ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  nb todo undo ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  nb todos [<notebook>:][<folder-path>/] [open | closed] [--pager]\n               [--tags <tag1>,<tag2>...]\n  nb todos tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n                 [open | closed] [--pager]\n  nb unarchive [<notebook>]\n  nb undo ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [<task-number>]\n  nb unpin ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb unset (<name> | <number>)\n  nb update\n  nb use <notebook>\n  nb -h | --help | help [<subcommand> | --readme]\n  nb -i | --interactive [<subcommand> [<options>...]]\n  nb --no-color\n  nb --version | version\n\nSubcommands:\n  (default)    List notes and notebooks. This is an alias for `nb ls`.\n               When a <url> is provided, create a new bookmark.\n  add          Add a note, folder, or file.\n  archive      Archive the current or specified notebook.\n  bookmark     Add, open, list, and search bookmarks.\n  browse       Browse and manage linked items in terminal and GUI web browsers.\n  completions  Install and uninstall completion scripts.\n  copy         Copy or duplicate an item.\n  count        Print the number of items in a notebook or folder.\n  delete       Delete a note.\n  do           Mark a todo or task as done.\n  edit         Edit a note.\n  env          Print environment information and install dependencies.\n  export       Export a note to a variety of different formats.\n  folders      Add, delete, and list folders.\n  git          Run `git` commands within the current notebook.\n  help         View help information for the program or a subcommand.\n  history      View git history for the current notebook or a note.\n  import       Import a file into the current notebook.\n  init         Initialize the first notebook.\n  list         List notes in the current notebook.\n  ls           List notebooks and notes in the current notebook.\n  move         Move or rename a note.\n  notebooks    Manage notebooks.\n  open         Open a bookmarked web page or notebook folder, or edit a note.\n  peek         View a note, bookmarked web page, or notebook in the terminal.\n  pin          Pin an item so it appears first in lists.\n  plugins      Install and uninstall plugins and themes.\n  remote       Configure the remote URL and branch for the notebook.\n  run          Run shell commands within the current notebook.\n  search       Search notes.\n  settings     Edit configuration settings.\n  shell        Start the `nb` interactive shell.\n  show         Show a note or notebook.\n  status       Run `git status` in the current notebook.\n  subcommands  List, add, alias, and describe subcommands.\n  status       Print notebook status information.\n  sync         Sync local notebook with the remote repository.\n  tasks        List tasks in todos, notebooks, folders, and other items.\n  todo         Manage todos and tasks.\n  unarchive    Unarchive the current or specified notebook.\n  undo         Mark a todo or task as not done.\n  unpin        Unpin a pinned item.\n  unset        Return a setting to its default value.\n  update       Update `nb` to the latest version.\n  use          Switch to a notebook.\n  version      Display version information.\n\nNotebook Usage:\n  nb <notebook>:[<subcommand>] [<identifier>] [<options>...]\n  nb <subcommand> <notebook>:<identifier> [<options>...]\n\nProgram Options:\n  -h, --help          Display this help information.\n  -i, --interactive   Start the `nb` interactive shell.\n  --no-color          Print without color highlighting.\n  --version           Display version information.\n\nMore Information:\n  https://github.com/xwmx/nb\n```\n\n#### `bookmark help`\n\n[↑](#-help) · See also:\n[Bookmarks](#-bookmarks),\n[`bookmark`](#bookmark),\n[`browse`](#browse)\n\n```text\n    __                __                        __\n   / /_  ____  ____  / /______ ___  ____ ______/ /__\n  / __ \\/ __ \\/ __ \\/ //_/ __ `__ \\/ __ `/ ___/ //_/\n / /_/ / /_/ / /_/ / ,< / / / / / / /_/ / /  / ,<\n/_.___/\\____/\\____/_/|_/_/ /_/ /_/\\__,_/_/  /_/|_|\n\nbookmark -- Command line bookmarking with tagging, encryption,\nfull-text page content search with regular expression support,\nGUI and terminal browser support, and data stored in plain text\nMarkdown files with Git-backed versioning and syncing.\n\nUsage:\n  bookmark [<ls-options>...]\n  bookmark [<notebook>:][<folder-path>] <url>\n              [-c <comment> | --comment <comment>] [--edit] [-e | --encrypt]\n              [-f <filename> | --filename <filename>] [--no-request]\n              [-q <quote> | --quote <quote>] [--save-source]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]...\n              [-t <tag1>,<tag2>... | --tags <tag1>,<tag2>...] [--title <title>]\n  bookmark (edit | delete | open | peek | url)\n              ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  bookmark search <query>\n\nOptions:\n  -c, --comment <comment>      A comment or description for this bookmark.\n  --edit                       Open the bookmark in your editor before saving.\n  -e, --encrypt                Encrypt the bookmark with a password.\n  -f, --filename <filename>    The filename for the bookmark. It is\n                               recommended to omit the extension so the\n                               default bookmark extension is used.\n  --no-request                 Don't request or download the target page.\n  -q, --quote <quote>          A quote or excerpt from the saved page.\n                               Alias: `--excerpt`\n  -r, --related <selector>     A selector for an item related to the\n                               bookmarked page.\n  -r, --related <url>          A URL for a page related to the bookmarked page.\n                               Multiple `--related` flags can be used in a\n                               command to save multiple related URLs.\n  --save-source                Save the page source as HTML.\n  -t, --tags <tag1>,<tag2>...  A comma-separated list of tags.\n  --title <title>              The bookmark title. When not specified,\n                               `nb` will use the html <title> tag.\n\nSubcommands:\n  (default)  Add a new bookmark for <url>, or list bookmarks.\n             Bookmarks can also be added with `nb <url>`\n  delete     Delete a bookmark.\n  edit       Edit a bookmark.\n  list       List bookmarks in the current notebook.\n             Shortcut Alias: `ls`\n  open       Open the bookmarked page in your system's primary web browser.\n             Shortcut Alias: `o`\n  peek       Open the bookmarked page in your terminal web browser.\n             Alias: `preview`\n             Shortcut Alias: `p`\n  search     Search bookmarks for <query>.\n             Shortcut Alias: `q`\n  url        Print the URL for the specified bookmark.\n\nDescription:\n  Create, view, search, edit, and delete bookmarks.\n\n  By default, the html page content is saved within the bookmark, making the\n  bookmarked page available for full-text search. When Pandoc [1] is\n  installed, the HTML content is converted to Markdown before saving.\n  When readability-cli [2] is install, markup is cleaned up to focus on\n  content.\n\n  `peek` opens the page in `w3m` [3] or `links` [4] when available.\n  To specify a preferred browser, set the `$BROWSER` environment variable\n  in your .bashrc, .zshrc, or equivalent, e.g.: export BROWSER=\"lynx\"\n\n  Bookmarks are identified by the `.bookmark.md` file extension. The\n  bookmark URL is the first URL in the file within \"<\" and \">\" characters:\n\n    <https://www.example.com>\n\n    1. https://pandoc.org/\n    2. https://gitlab.com/gardenappl/readability-cli\n    3. https://en.wikipedia.org/wiki/W3m\n    4. https://en.wikipedia.org/wiki/Links_(web_browser)\n\nRead More:\n  https://github.com/xwmx/nb#-bookmarks\n\nSee Also:\n  nb help browse\n  nb help open\n  nb help peek\n  nb help show\n\nExamples:\n  bookmark https://example.com\n  bookmark https://example.com --encrypt\n  bookmark https://example.com --tags example,sample,demo\n  bookmark https://example.com/about -c \"Example comment.\"\n  bookmark https://example.com/faqs -f example-filename\n  bookmark https://example.com --quote \"Example quote or excerpt.\"\n  bookmark list\n  bookmark search \"example query\"\n  bookmark open 5\n\n------------------------------------------\nPart of `nb` (https://github.com/xwmx/nb).\nFor more information, see: `nb help`.\n```\n\n### Subcommands\n\n<div align=\"center\">\n  <a href=\"#add\">add</a>&nbsp;·\n  <a href=\"#archive\">archive</a>&nbsp;·\n  <a href=\"#bookmark\">bookmark</a>&nbsp;·\n  <a href=\"#browse\">browse</a>&nbsp;·\n  <a href=\"#completions\">completions</a>&nbsp;·\n  <a href=\"#copy\">copy</a>&nbsp;·\n  <a href=\"#count\">count</a>&nbsp;·\n  <a href=\"#delete\">delete</a>&nbsp;·\n  <a href=\"#do\">do</a>&nbsp;·\n  <a href=\"#edit\">edit</a>&nbsp;·\n  <a href=\"#env\">env</a>&nbsp;·\n  <a href=\"#folders\">folders</a>&nbsp;·\n  <a href=\"#export\">export</a>&nbsp;·\n  <a href=\"#git\">git</a>&nbsp;·\n  <a href=\"#help\">help</a>&nbsp;·\n  <a href=\"#history\">history</a>&nbsp;·\n  <a href=\"#import\">import</a>&nbsp;·\n  <a href=\"#init\">init</a>&nbsp;·\n  <a href=\"#list\">list</a>&nbsp;·\n  <a href=\"#ls\">ls</a>&nbsp;·\n  <a href=\"#move\">move</a>&nbsp;·\n  <a href=\"#notebooks\">notebooks</a>&nbsp;·\n  <a href=\"#open\">open</a>&nbsp;·\n  <a href=\"#peek\">peek</a>&nbsp;·\n  <a href=\"#pin\">pin</a>&nbsp;·\n  <a href=\"#plugins\">plugins</a>&nbsp;·\n  <a href=\"#remote\">remote</a>&nbsp;·\n  <a href=\"#run\">run</a>&nbsp;·\n  <a href=\"#search\">search</a>&nbsp;·\n  <a href=\"#settings\">settings</a>&nbsp;·\n  <a href=\"#shell\">shell</a>&nbsp;·\n  <a href=\"#show\">show</a>&nbsp;·\n  <a href=\"#status\">status</a>&nbsp;·\n  <a href=\"#subcommands-1\">subcommands</a>&nbsp;·\n  <a href=\"#sync\">sync</a>&nbsp;·\n  <a href=\"#tasks\">tasks</a>&nbsp;·\n  <a href=\"#todo\">todo</a>&nbsp;·\n  <a href=\"#unarchive\">unarchive</a>&nbsp;·\n  <a href=\"#undo\">undo</a>&nbsp;·\n  <a href=\"#unpin\">unpin</a>&nbsp;·\n  <a href=\"#unset\">unset</a>&nbsp;·\n  <a href=\"#update\">update</a>&nbsp;·\n  <a href=\"#use\">use</a>&nbsp;·\n  <a href=\"#version\">version</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#overview\">&nbsp;↑&nbsp;</a>\n</div>\n\n#### `add`\n\n[↑](#-help) · See also:\n[Adding](#adding),\n[`bookmark`](#bookmark),\n[`browse`](#browse),\n[`delete`](#delete),\n[`edit`](#edit),\n[`folders`](#folders),\n[`import`](#import),\n[`show`](#show),\n[`todo`](#todo)\n\n```text\nUsage:\n  nb add [<notebook>:][<folder-path>/][<filename>] [<content>]\n         [-b | --browse] [-c <content> | --content <content>] [--edit]\n         [-e | --encrypt] [-f <filename> | --filename <filename>]\n         [--folder <folder-path>] [--no-template] [--tags <tag1>,<tag2>...]\n         [--template <template>] [-t <title> | --title <title>] [--type <type>]\n  nb add bookmark [<bookmark-options>...]\n  nb add folder [<name>]\n  nb add todo [<todo-options>...]\n\nOptions:\n  -b, --browse                Add using a terminal or GUI web browser.\n  -c, --content <content>     The content for the new note.\n  --edit                      Open the note in the editor before saving when\n                              content is piped or passed as an argument.\n  -e, --encrypt               Encrypt the note with a password.\n  -f, --filename <filename>   The filename for the new note.\n  --folder <folder-path>      Add within the folder located at <folder-path>.\n  --no-template               Skip the template when one is assigned.\n  --tags <tag1>,<tag2>...     A comma-separated list of tags.\n  --template <template>       A string template or path to a template file.\n  -t, --title <title>         The title for a new note. If `--title` is\n                              present, the filename is derived from the\n                              title, unless `--filename` is specified.\n  --type <type>               The file type for the new note, as a file\n                              extension.\n\nDescription:\n  Create a new note or folder.\n\n  If no arguments are passed, a new blank note file is opened with `$EDITOR`,\n  currently set to: example\n\n  If a non-option argument is passed, `nb` will treat it as a <filename≥\n  if a file extension is found. If no file extension is found,  `nb` will\n  treat the string as <content> and will create a new note without opening the\n  editor. `nb add` can also create a new note with piped content.\n\n  `nb` creates Markdown files by default. To create a note with a\n  different file type, use the extension in the filename or use the `--type`\n  option. To change the default file type, use `nb set default_extension`.\n\n  When the `-e` / `--encrypt` option is used, `nb` will encrypt the\n  note with AES-256 using OpenSSL by default, or GPG, if configured in\n  `nb set encryption_tool`.\n\nRead More:\n  https://github.com/xwmx/nb#adding\n\nSee Also:\n  nb help bookmark\n  nb help browse\n  nb help delete\n  nb help edit\n  nb help folders\n  nb help import\n  nb help show\n  nb help todo\n\nExamples:\n  nb add\n  nb add example.md\n  nb add \"Note content.\"\n  nb add example.md --title \"Example Title\" --content \"Example content.\"\n  echo \"Note content.\" | nb add\n  nb add -t \"Secret Document\" --encrypt\n  nb add example/document.md\n  nb add folder sample/demo\n  nb example:add\n  nb example:add -t \"Title\"\n  nb a\n  nb a \"Note content.\"\n  nb example:a\n  nb example:a -t \"Title\"\n\nAliases:\n  nb create\n  nb new\n\nShortcut Aliases:\n  nb a\n  nb +\n```\n\n#### `archive`\n\n[↑](#-help) · See also:\n[Archiving Notebooks](#archiving-notebooks),\n[`notebooks`](#notebooks),\n[`status`](#status),\n[`unarchive`](#unarchive)\n\n```text\nUsage:\n  nb archive [<name>]\n\nDescription:\n  Set the current notebook or notebook <name> to \"archived\" status.\n\n  This is an alias for `nb notebooks archive`.\n\nRead More:\n  https://github.com/xwmx/nb#archiving-notebooks\n\nSee Also:\n  nb help notebooks\n  nb help status\n  nb help unarchive\n\nExamples:\n  nb archive\n  nb archive example\n\nShortcut Alias:\n  nb ar\n```\n\n#### `bookmark`\n\n[↑](#-help) · See also:\n[Bookmarks](#-bookmarks),\n[`browse`](#browse),\n[`open`](#open),\n[`peek`](#peek),\n[`show`](#show)\n\n```text\nUsage:\n  nb bookmark [<ls-options>...]\n  nb bookmark [<notebook>:][<folder-path>/] <url>...\n              [-c <comment> | --comment <comment>] [--edit] [-e | --encrypt]\n              [-f <filename> | --filename <filename>] [--no-request]\n              [-q <quote> | --quote <quote>] [--save-source]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]...\n              [-t <tag1>,<tag2>... | --tags <tag1>,<tag2>...] [--title <title>]\n  nb bookmark list [<list-options>...]\n  nb bookmark (edit | delete | open | peek | url)\n              ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb bookmark search <query>\n\nOptions:\n  -c, --comment <comment>      A comment or description for this bookmark.\n  --edit                       Open the bookmark in your editor before saving.\n  -e, --encrypt                Encrypt the bookmark with a password.\n  -f, --filename <filename>    The filename for the bookmark. It is\n                               recommended to omit the extension so the\n                               default bookmark extension is used.\n  --no-request                 Don't request or download the target page.\n  -q, --quote <quote>          A quote or excerpt from the saved page.\n                               Alias: `--excerpt`\n  -r, --related <selector>     A selector for an item related to the\n                               bookmarked page.\n  -r, --related <url>          A URL for a page related to the bookmarked page.\n                               Multiple `--related` flags can be used in a\n                               command to save multiple related URLs.\n  --save-source                Save the page source as HTML.\n  -t, --tags <tag1>,<tag2>...  A comma-separated list of tags.\n  --title <title>              The bookmark title. When not specified,\n                               `nb` will use the html <title> tag.\n\nSubcommands:\n  (default)  Add a new bookmark for <url>, or list bookmarks.\n             Bookmarks can also be added with `nb <url>`\n  delete     Delete a bookmark.\n  edit       Edit a bookmark.\n  list       List bookmarks in the current notebook.\n             Shortcut Alias: `ls`\n  open       Open the bookmarked page in your system's primary web browser.\n             Shortcut Alias: `o`\n  peek       Open the bookmarked page in your terminal web browser.\n             Alias: `preview`\n             Shortcut Alias: `p`\n  search     Search bookmarks for <query>.\n             Shortcut Alias: `q`\n  url        Print the URL for the specified bookmark.\n\nDescription:\n  Create, view, search, edit, and delete bookmarks.\n\n  By default, the html page content is saved within the bookmark, making the\n  bookmarked page available for full-text search. When Pandoc [1] is\n  installed, the HTML content is converted to Markdown before saving.\n  When readability-cli [2] is install, markup is cleaned up to focus on\n  content.\n\n  `peek` opens the page in `w3m` [3] or `links` [4] when available.\n  To specify a preferred browser, set the `$BROWSER` environment variable\n  in your .bashrc, .zshrc, or equivalent, e.g.: export BROWSER=\"lynx\"\n\n  Bookmarks are identified by the `.bookmark.md` file extension. The\n  bookmark URL is the first URL in the file within \"<\" and \">\" characters:\n\n    <https://www.example.com>\n\n    1. https://pandoc.org/\n    2. https://gitlab.com/gardenappl/readability-cli\n    3. https://en.wikipedia.org/wiki/W3m\n    4. https://en.wikipedia.org/wiki/Links_(web_browser)\n\nRead More:\n  https://github.com/xwmx/nb#-bookmarks\n\nSee Also:\n  nb help browse\n  nb help open\n  nb help peek\n  nb help show\n\nExamples:\n  nb https://example.com\n  nb example: https://example.com\n  nb https://example.com --encrypt\n  nb https://example.com --tags example,sample,demo\n  nb https://example.com/about -c \"Example comment.\"\n  nb https://example.com/faqs -f example-filename\n  nb https://example.com --quote \"Example quote or excerpt.\"\n  nb bookmark list\n  nb bookmark search \"example query\"\n  nb bookmark open 5\n  nb bk\n\nShortcut Aliases:\n  nb bk\n  nb bm\n```\n\n#### `browse`\n\n[↑](#-help) · See also:\n[Browsing](#-browsing),\n[Images](#-images),\n[Linking](#-linking),\n[`add`](#add),\n[`delete`](#delete),\n[`edit`](#edit),\n[`list`](#list),\n[`ls`](#ls),\n[`open`](#open),\n[`peek`](#peek),\n[`pin`](#pin),\n[`search`](#search),\n[`show`](#show)\n\n```text\nUsage:\n  nb browse [<notebook>:][<folder-path>/][<id> | <filename> | <title>] [--daemon]\n            [-g | --gui] [-n | --notebooks] [-p | --print] [-q | --query <query>]\n            [-s | --serve] [-t <tag> | --tag <tag> | --tags <tag1>,<tag2>...]\n  nb browse add [<notebook>:][<folder-path>/][<filename>]\n            [-c <content> | --content <content>] [--tags <tag1>,<tag2>...]\n            [-t <title> | --title <title>]\n  nb browse delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb browse edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nSubcommands:\n  (default)  Open a notebook, folder, or item in the terminal or GUI web browser.\n  add        Open the add view in the browser.\n             Shortcut Aliases: `a`, `+`\n  delete     Open the delete view in the browser.\n             Shortcut Aliases: `d`, `-`\n  edit       Open the edit view in the browser.\n             Shortcut Alias:   `e`\n\nOptions:\n  -c, --content <content>      Add content to the new note.\n  --daemon                     Start the web server. Close with <CTRL-C>.\n  -g, --gui                    Open in the system's primary GUI web browser.\n  -n, --notebooks              Browse notebooks.\n  -p, --print                  Print to standard output.\n  -q, --query <query>          Open to the search results for <query>.\n  -s, --serve                  Start the web server. Close with any key.\n  -t, --tag <tag>              Search for a tag.\n  --tags <tag1>,<tag2>...      A comma-separated list of tags.\n  -t, --title <title>          Add a title to the new note.\n\nDescription:\n  Browse, view, and edit linked notes, bookmarks, notebooks, folders, and\n  other items using terminal and GUI web browsers.\n\n  `browse` includes an embedded web application designed for terminal\n  and GUI web browsers that renders [[wiki-style links]] and #tags as\n  internal links, providing the ability to browse notes and notebooks,\n  as well as seamlessly browse to and from the offsite links in\n  bookmarks and notes.\n\n  To link to a note or bookmark from another, include the selector for the\n  target item within double square brackets anywhere in the linking document:\n\n    # link to item 123 in the \"sample\" folder in the \"example\" notebook\n    [[example:sample/123]]\n\n    # link to the item titled \"Example Title\" in the \"demo\" notebook\n    [[demo:Example Title]]\n\n  `browse` supports `w3m` [1] and `links` [2], and depends on\n  `ncat` [3] or `socat` [4] and `pandoc` [5]:\n\n    1. https://en.wikipedia.org/wiki/W3m\n    2. https://en.wikipedia.org/wiki/Links_(web_browser)\n    3. https://nmap.org/ncat/\n    4. https://www.kali.org/tools/socat/\n    5. https://pandoc.org/\n\nRead More:\n  https://github.com/xwmx/nb#-browsing\n\nSee Also:\n  nb help add\n  nb help delete\n  nb help edit\n  nb help list\n  nb help ls\n  nb help open\n  nb help peek\n  nb help pin\n  nb help search\n  nb help show\n  nb help unpin\n\nExamples:\n  nb browse\n  nb browse example:\n  nb browse Example\\ Folder/\n  nb browse 123\n  nb browse demo:456\n  nb br\n\nShortcut Alias:\n  nb b\n```\n\n#### `completions`\n\n[↑](#-help) · See also:\n[Tab Completion](https://github.com/xwmx/nb/tree/master/etc),\n[`env`](#env)\n\n```text\nUsage:\n  nb completions (check | install [-d | --download] | uninstall)\n\nOptions:\n  -d, --download  Download the completion scripts and install.\n\nDescription:\n  Manage completion scripts.\n\nRead More:\n  https://github.com/xwmx/nb/blob/master/etc/README.md\n\nSee Also:\n  nb help env\n```\n\n#### `copy`\n\n[↑](#-help) · See also:\n[Moving & Renaming](#-moving--renaming),\n[`move`](#move)\n\n```text\nUsage:\n  nb copy ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[<notebook>:][<folder-path>/]<filename>]\n\nDescription:\n  Copy or duplicate an item.\n\nRead More:\n  https://github.com/xwmx/nb#-moving--renaming\n\nSee Also:\n  nb help move\n\nExamples:\n  nb copy 321\n  nb copy 456 example:\n  nb copy sample/demo.md\n\nAlias:\n  nb duplicate\n```\n\n#### `count`\n\n[↑&nbsp;](#-help)\n\n```text\nUsage:\n  nb count [<notebook>:][<folder-path>/]\n\nDescription:\n  Print the number of items in the first level of the current notebook,\n  <notebook>, or the folder at <folder-path>.\n```\n\n#### `delete`\n\n[↑](#-help) · See also:\n[Deleting](#deleting),\n[`add`](#add),\n[`browse`](#browse),\n[`edit`](#edit),\n[`move`](#move),\n[`show`](#show)\n\n```text\nUsage:\n  nb delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])...\n            [-f | --force]\n\nOptions:\n  -f, --force   Skip the confirmation prompt.\n\nDescription:\n  Delete one or more items.\n\nRead More:\n  https://github.com/xwmx/nb#deleting\n\nSee Also:\n  nb help add\n  nb help browse\n  nb help edit\n  nb help move\n  nb help show\n\nExamples:\n  nb delete 3\n  nb delete example.md\n  nb delete \"A Document Title\"\n  nb 3 delete --force\n  nb example:delete 12\n  nb delete example:12\n  nb example:12 delete\n  nb d 3\n  nb 3 d\n  nb d example:12\n  nb example:12 d\n\nAliases:\n  nb rm\n  nb trash\n\nShortcut Aliases:\n  nb d\n  nb -\n```\n\n#### `do`\n\n[↑](#-help) · See also:\n[Todos](#-todos),\n[Tasks](#%EF%B8%8F-tasks),\n[`tasks`](#tasks),\n[`todo`](#todo),\n[`undo`](#undo)\n\n```text\nUsage:\n  nb do ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n        [<task-number>]\n\nDescription:\n  Mark a todo or task as done.\n\nRead More:\n  https://github.com/xwmx/nb#-todos\n\nSee Also:\n  nb help tasks\n  nb help todo\n  nb help undo\n\nExamples:\n  nb do 123\n  nb do example:sample/321\n  nb do 543 7\n```\n\n#### `edit`\n\n[↑](#-help) · See also:\n[Editing](#editing),\n[`add`](#add),\n[`browse`](#browse),\n[`delete`](#delete),\n[`move`](#move),\n[`show`](#show)\n\n```text\nUsage:\n  nb edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [-c <content> | --content <content>] [--edit]\n          [-e <editor> | --editor <editor>] [-l | --last] [--overwrite]\n          [--prepend]\n\nOptions:\n  -c, --content <content>  Content to add to the item.\n  --edit                   Open the note in the editor before saving when\n                           content is piped or passed as an argument.\n  -e, --editor <editor>    Edit the note with <editor>, overriding the editor\n                           specified in the `$EDITOR` environment variable.\n  -l, --last               Edit the last modified item.\n  --overwrite              Overwrite existing content with <content> and\n                           standard input.\n  --prepend                Prepend <content> and standard input before\n                           existing content.\n\nDescription:\n  Open the specified note in `$EDITOR` or <editor> if specified.\n  Content piped to `nb edit` or passed using the `--content` option\n  is appended to the file without opening it in the editor,\n  unless the `--edit` flag is specified.\n\n  Non-text files are opened in your system's preferred app or program for\n  that file type.\n\nRead More:\n  https://github.com/xwmx/nb#editing\n\nSee Also:\n  nb help add\n  nb help browse\n  nb help delete\n  nb help move\n  nb help show\n\nExamples:\n  nb edit 3\n  nb edit example.md\n  nb edit \"A Document Title\"\n  echo \"Content to append.\" | nb edit 1\n  nb 3 edit\n  nb example:edit 12\n  nb edit example:12\n  nb example:12 edit\n  nb e 3\n  nb 3 e\n  nb e example:12\n  nb example:12 e\n\nShortcut Alias:\n  nb e\n```\n\n#### `env`\n\n[↑](#-help) · See also:\n[Installation](#installation),\n[`completions`](#completions),\n[`init`](#init),\n[`update`](#update),\n[`version`](#version)\n\n```text\nUsage:\n  nb env [-l | --long]\n  nb env [install | update] [--ace | --mathjax]\n\nSubcommands:\n  (default) Print environment and configuration information.\n  install   Install dependencies on supported systems.\n  update    Update dependencies.\n\nOptions:\n  --ace       Install or update Ace editor [1][2].\n  -l, --long  Print additional environmental information.\n  --mathjax   Install or update MathJax [3].\n\n    1. https://github.com/ajaxorg/ace\n    2. https://github.com/ajaxorg/ace-builds\n    3. https://github.com/mathjax/MathJax\n\nDescription:\n  Print program environment and configuration information, or install\n  dependencies.\n\nRead More:\n  https://github.com/xwmx/nb#installation\n\nSee Also:\n  nb help completions\n  nb help init\n  nb help update\n  nb help version\n```\n\n#### `export`\n\n[↑](#-help) · See also:\n[Import / Export](#%EF%B8%8F-import--export),\n[`browse`](#browse),\n[`import`](#import)\n\n```text\nUsage:\n  nb export ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <path> [-f | --force] [<pandoc options>...]\n  nb export notebook <name> [<path>]\n  nb export pandoc ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            [<pandoc options>...]\n\nOptions:\n  -f, --force   Skip the confirmation prompt when overwriting an existing file.\n\nSubcommands:\n  (default)     Export a file to <path>. If <path> has a different extension\n                than the source note, convert the note using `pandoc`.\n  notebook      Export the notebook <name> to the current directory or <path>.\n                Alias for `nb notebooks export`.\n  pandoc        Export the file to standard output or a file using `pandoc`.\n                `export pandoc` prints to standard output by default.\n\nDescription:\n  Export a file or notebook.\n\n  If Pandoc [1] is available, convert the note from its current format\n  to the format of the output file as indicated by the file extension\n  in <path>. Any additional arguments are passed directly to Pandoc.\n  See the Pandoc help information for available options.\n\n    1. https://pandoc.org/\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-import--export\n\nSee Also:\n  nb help browse\n  nb help import\n\nExamples:\n  # Export an Org note\n  nb export example.org /path/to/example.org\n\n  # Export a Markdown note to HTML and print to standard output\n  nb export pandoc example.md --from=markdown_strict --to=html\n\n  # Export a Markdown note to a .docx Microsoft Office Word document\n  nb export example.md /path/to/example.docx\n\n  # Export note 12 in the \"sample\" notebook to HTML\n  nb export sample:12 /path/to/example.html\n```\n\n#### `folders`\n\n[↑](#-help) · See also:\n[Folders](#-folders),\n[`add`](#add),\n[`delete`](#delete),\n[`list`](#list),\n[`ls`](#ls)\n\n```text\nUsage:\n  nb folders add [<notebook>:][<folder-path>/]<folder-name>\n  nb folders delete [<notebook>:][<folder-path>/]<folder-name>\n  nb folders <list-options>...\n\nSubcommands:\n  (default)  List folders.\n  add        Add a new folder.\n  delete     Delete a folder.\n\nDescription:\n  Add, delete, and list folders.\n\nRead More:\n  https://github.com/xwmx/nb#-folders\n\nSee Also:\n  nb help add\n  nb help delete\n  nb help list\n  nb help ls\n\nExamples:\n  nb folders\n  nb folders add example\n  nb folders delete example:sample\n\nAlias:\n  nb folder\n\nShortcut Alias:\n  nb f\n```\n\n#### `git`\n\n[↑](#-help) · See also:\n[Git Sync](#-git-sync),\n[History](#-revision-history),\n[`history`](#history),\n[`remote`](#remote),\n[`run`](#run),\n[`status`](#status),\n[`sync`](#sync)\n\n```text\nUsage:\n  nb git [checkpoint [<message>] | dirty]\n  nb git <git-options>...\n\nSubcommands:\n  checkpoint    Create a new git commit in the current notebook and sync with\n                the remote if `nb set auto_sync` is enabled.\n  dirty         0 (success, true) if there are uncommitted changes in the\n                current notebook. 1 (error, false) if the notebook is clean.\n\nDescription:\n  Run `git` commands within the current notebook directory.\n\nRead More:\n  https://github.com/xwmx/nb#-git-sync\n  https://github.com/xwmx/nb#-revision-history\n\nSee Also:\n  nb help history\n  nb help remote\n  nb help run\n  nb help status\n  nb help sync\n\nExamples:\n  nb git status\n  nb git diff\n  nb git log\n  nb example:git status\n```\n\n#### `help`\n\n[↑](#-help) · See also:\n[`nb help`](#nb-help)\n\n```text\nUsage:\n  nb help [<subcommand>] [-p | --print]\n  nb help [-c | --colors] | [-r | --readme] | [-s | --short] [-p | --print]\n\nOptions:\n  -c, --colors  View information about color themes and color settings.\n  -p, --print   Print to standard output / terminal.\n  -r, --readme  View the `nb` README file.\n  -s, --short   Print shorter help without subcommand descriptions.\n\nDescription:\n  Print the program help information. When a subcommand name is passed, print\n  the help information for the subcommand.\n\nExamples:\n  nb help\n  nb help add\n  nb help import\n  nb h notebooks\n  nb h e\n\nShortcut Alias:\n  nb h\n```\n\n#### `history`\n\n[↑](#-help) · See also:\n[History](#-revision-history),\n[Git Sync](#-git-sync),\n[`git`](#git),\n[`remote`](#remote),\n[`status`](#status),\n[`sync`](#sync)\n\n```text\nUsage:\n  nb history [<notebook>:][<folder-path>/][<id> | <filename> | <title>]\n\nDescription:\n  Display notebook history using `tig` [1] (if available) or `git log`.\n  When a note is specified, the history for that note is displayed.\n\n    1. https://github.com/jonas/tig\n\nRead More:\n  https://github.com/xwmx/nb#-revision-history\n  https://github.com/xwmx/nb#-git-sync\n\nSee Also:\n  nb help git\n  nb help remote\n  nb help status\n  nb help sync\n\nExamples:\n  nb history\n  nb history example.md\n  nb 3 history\n  nb history example:\n  nb example:history\n  nb example:history 12\n  nb history example:12\n  nb example:12 history\n```\n\n#### `import`\n\n[↑](#-help) · See also:\n[Import / Export](#%EF%B8%8F-import--export),\n[Images](#-images),\n[`add`](#add),\n[`export`](#export)\n\n```text\nUsage:\n  nb import [bookmarks | copy | download | move] (<path>... | <url>)\n            [--convert] [<notebook>:][<folder-path>/][<filename>]\n  nb import notebook <path> [<name>]\n\nOptions:\n  --convert  Convert HTML content to Markdown.\n\nSubcommands:\n  (default)  Copy or download the file(s) at <path> or <url>.\n  bookmarks  Import bookmarks from a Chrome, Firefox, or Edge export file.\n  copy       Copy the file(s) at <path> into the current notebook.\n  download   Download the file at <url> into the current notebook.\n  move       Move the file(s) at <path> into the current notebook.\n  notebook   Import the local notebook at <path> to make it global.\n\nDescription:\n  Copy, move, or download files into `nb`, import bookmarks, or import\n  a local notebook to make it global.\n\nDescription:\n  Copy, move, or download files into the current notebook or import\n  a local notebook to make it global.\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-import--export\n\nSee Also:\n  nb help add\n  nb help export\n\nExamples:\n  nb import ~/Pictures/example.png\n  nb import ~/Documents/example.docx\n  nb import https://example.com/example.pdf\n  nb example:import https://example.com/example.jpg\n  nb import ./*\n  nb import ./*.md\n  nb import ~/Pictures/example.png example-notebook:\n  nb import ~/Documents/example.docx example-folder/\n\nShortcut Alias:\n  nb i\n```\n\n#### `init`\n\n[↑](#-help) · See also: [`notebooks`](#notebooks)\n\n```text\nUsage:\n  nb init [<remote-url> [<branch>]] [--author] [--email <email>]\n          [--name <name>]\n\nOptions:\n  --author         Display the local email and name config prompt.\n  --email <email>  Set the local commit author email address to <email>.\n  --name  <name>   Set the local commit author name to <name>.\n\nDescription:\n  Initialize the initial \"home\" notebook and generate a configuration file at:\n\n      ~/.nbrc\n\n  Pass optional <remote-url> and <branch> arguments to create the initial\n  \"home\" notebook using a clone of an existing notebook.\n\nSee Also:\n  nb help notebooks\n\nExamples:\n  nb init\n  nb init https://github.com/example/example.git\n  nb init https://github.com/example/example.git example-branch\n```\n\n#### `list`\n\n[↑](#-help) · See also:\n[Listing & Filtering](#listing--filtering),\n[`browse`](#browse),\n[`ls`](#ls),\n[`pin`](#pin),\n[`search`](#search),\n[`unpin`](#unpin)\n\n```text\nUsage:\n  nb list [-e [<length>] | --excerpt [<length>]] [--filenames]\n          [-f | --folders-first] [-n <limit> | --limit <limit> | --<limit>]\n          [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n          [--paths] [-s | --sort] [-r | --reverse] [--tags]\n          [-t <type> | --type <type> | --<type>]\n          [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n\nOptions:\n  -e, --excerpt [<length>]        Print an excerpt <length> lines long under\n                                  each note's filename [default: 3].\n  --filenames                     Print the filename for each note.\n  -f, --folders-first             Print folders before other items.\n  -n, --limit <limit>, --<limit>  The maximum number of notes to list.\n  --no-id                         Don't include the id in list items.\n  --no-indicator                  Don't include the indicator in list items.\n  -p, --page <number>             The page to view in the list paginated by\n                                  a <limit> option or `nb set limit`.\n  --pager                         Display output in the pager.\n  --paths                         Print the full path to each item.\n  -s, --sort                      Order notes by id.\n  -r, --reverse                   List items in reverse order.\n  --tags                          List tags in the notebook or folder.\n  -t, --type <type>, --<type>     List items of <type>. <type> can be a file\n                                  extension or one of the following types:\n                                  archive, audio, book, bookmark, document,\n                                  folder, image, note, text, video\n\nDescription:\n  List notes in the current notebook.\n\n  When <id>, <filename>, <path>, or <title> are present, the listing for the\n  matching note is displayed. When no match is found, titles and filenames\n  are searched for any that match <query> as a case-insensitive regular\n  expression.\n\nRead More:\n  https://github.com/xwmx/nb#listing--filtering\n\nIndicators:\n  🔉  Audio\n  📖  Book\n  🔖  Bookmark\n  🔒  Encrypted\n  📂  Folder\n  🌄  Image\n  📄  PDF, Word, or Open Office document\n  📹  Video\n\nSee Also:\n  nb help browse\n  nb help ls\n  nb help pin\n  nb help search\n  nb help unpin\n\nExamples:\n  nb list\n  nb list example.md -e 10\n  nb list --excerpt --no-id\n  nb list --filenames --reverse\n  nb list \"^Example.*\"\n  nb list --10\n  nb list --type document\n  nb example:list\n```\n\n#### `ls`\n\n[↑](#-help) · See also:\n[Listing & Filtering](#listing--filtering),\n[`browse`](#browse),\n[`list`](#list),\n[`pin`](#pin),\n[`search`](#search),\n[`unpin`](#unpin)\n\n```text\nUsage:\n  nb ls [-a | --all] [-b | --browse] [-e [<length>] | --excerpt [<length>]]\n        [--filenames] [-f | --folders-first] [-g | --gui]\n        [-n <limit> | --limit <limit> | --<limit>] [--no-footer] [--no-header]\n        [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n        [--paths] [-s | --sort] [-r | --reverse] [--tags]\n        [-t <type> | --type <type> | --<type>]\n        [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n\nOptions:\n  -a, --all                       Print all items in the notebook. Equivalent\n                                  to no limit.\n  -b, --browse                    Open the specified item or current notebook\n                                  with `browse` in a terminal web browser.\n  -e, --excerpt [<length>]        Print an excerpt <length> lines long under\n                                  each note's filename [default: 3].\n  --filenames                     Print the filename for each note.\n  -f, --folders-first             Print folders before other items.\n  -g, --gui                       Open the specified item or current notebook\n                                  with `browse` in a GUI web browser.\n  -n, --limit <limit>, --<limit>  The maximum number of listed items.\n                                  [default: 15]\n  --no-footer                     Print without footer.\n  --no-header                     Print without header.\n  --no-id                         Don't include the id in list items.\n  --no-indicator                  Don't include the indicator in list items.\n  -p, --page <number>             The page to view in the list paginated by\n                                  a <limit> option or `nb set limit`.\n  --pager                         Display output in the pager.\n  --paths                         Print the full path to each item.\n  -s, --sort                      Order notes by id.\n  -r, --reverse                   List items in reverse order.\n  --tags                          List tags in the notebook or folder.\n  -t, --type <type>, --<type>     List items of <type>. <type> can be a file\n                                  extension or one of the following types:\n                                  archive, audio, book, bookmark, document,\n                                  folder, image, note, text, video\n\nDescription:\n  List notebooks and notes in the current notebook, displaying note titles\n  when available. `nb ls` is a combination of `nb notebooks` and\n  `nb list` in one view.\n\n  When <id>, <filename>, <path>, or <title> are present, the listing for the\n  matching note is displayed. When no match is found, titles and filenames\n  are searched for any that match <query> as a case-insensitive regular\n  expression.\n\n  Options are passed through to `list`. For more information, see\n  `nb help list`.\n\nRead More:\n  https://github.com/xwmx/nb#listing--filtering\n\nIndicators:\n  🔉  Audio\n  📖  Book\n  🔖  Bookmark\n  🔒  Encrypted\n  📂  Folder\n  🌄  Image\n  📄  PDF, Word, or Open Office document\n  📹  Video\n\nSee Also:\n  nb help browse\n  nb help list\n  nb help pin\n  nb help search\n  nb help unpin\n\nExamples:\n  nb\n  nb --all\n  nb ls\n  nb ls example.md -e 10\n  nb ls --excerpt --no-id\n  nb ls --reverse\n  nb ls \"^Example.*\"\n  nb ls --10\n  nb ls --type document\n  nb example:\n  nb example: -ae\n  nb example:ls\n\nShortcut Alias:\n  nb\n```\n\n#### `move`\n\n[↑](#-help) · See also:\n[Moving & Renaming](#-moving--renaming),\n[`copy`](#copy),\n[`delete`](#delete),\n[`edit`](#edit)\n\n```text\nUsage:\n  nb move ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          ([<notebook>:][<path>] | --reset | --to-bookmark | --to-note |\n          --to-title | --to-todo) [-f | --force]\n\nOptions:\n  -f, --force     Skip the confirmation prompt.\n  --reset         Reset the filename to the last modified timestamp.\n  --to-bookmark   Preserve the existing filename and replace the extension\n                  with \".bookmark.md\" to convert the note to a bookmark.\n  --to-note       Preserve the existing filename and replace the bookmark's\n                  \".bookmark.md\" extension with \".md\" to convert the bookmark\n                  to a Markdown note.\n  --to-title      Set the filename to the note title, lowercased with spaces\n                  and disallowed filename characters replaced with underscores.\n  --to-todo       Preserve the existing filename and replace the extension\n                  with \".todo.md\" to convert the note to a todo.\n\nDescription:\n  Move or rename a note. Move the note to <path> or change the file type.\n  When the file extension is omitted, the existing extension is used.\n  When only a file extension is specified, only the extension will be updated.\n\n  `nb move` and `nb rename` are aliases and can be used interchangeably.\n\nRead More:\n  https://github.com/xwmx/nb#-moving--renaming\n\nSee Also:\n  nb help copy\n  nb help delete\n  nb help edit\n\nExamples:\n  # move \"example.md\" to \"sample.org\"\n  nb move example.md sample.org\n\n  # rename note 3 (\"example.md\") to \"New Name.md\"\n  nb rename 3 \"New Name\"\n\n  # rename \"example.bookmark.md\" to \"New Name.bookmark.md\"\n  nb move example.bookmark.md \"New Name\"\n\n  # rename note 3 (\"example.md\") to a bookmark named \"example.bookmark.md\"\n  nb rename 3 --to-bookmark\n\n  # move note 12 into \"Sample Folder\" in the \"demo\" notebook\n  nb move example:12 demo:Sample\\ Folder/\n\n  # rename note 12 in the \"example\" notebook to \"sample.md\"\n  nb rename example:12 \"sample.md\"\n\n  # change the file extension of note 5 to .org\n  nb rename 5 .org\n\nAlias:\n  nb rename\n\nShortcut Alias:\n  nb mv\n```\n\n#### `notebooks`\n\n[↑](#-help) · See also:\n[Notebooks](#-notebooks),\n[`archive`](#archive),\n[`history`](#history),\n[`move`](#move),\n[`remote`](#remote),\n[`status`](#status),\n[`sync`](#sync),\n[`unarchive`](#unarchive),\n[`use`](#use)\n\n```text\nUsage:\n  nb notebooks [<name> | <query>] [--ar | --archived] [--global] [--local]\n               [--names] [--paths] [--unar | --unarchived]\n  nb notebooks add ([<name>] [<remote-url> [<branch>... | --all]]) [--author]\n                   [--email <email>] [--name <name>]\n  nb notebooks (archive | open | peek | status | unarchive) [<name>]\n  nb notebooks author [<name> | <path>] [--email <email>] [--name <name>]\n  nb notebooks current [--path | --selected | --filename [<filename>]]\n                       [--global | --local]\n  nb notebooks delete <name> [-f | --force]\n  nb notebooks (export <name> [<path>] | import <path>)\n  nb notebooks init [<path> [<remote-url> [<branch>]]] [--author]\n                    [--email <email>] [--name <name>]\n  nb notebooks rename <old-name> <new-name>\n  nb notebooks select <selector>\n  nb notebooks show (<name> | <path> | <selector>) [--ar | --archived]\n                    [--escaped | --name | --path | --filename [<filename>]]\n  nb notebooks use <name>\n\nOptions:\n  --all                    Add notebooks from all remote branches.\n  --ar, --archived         List archived notebooks, or return archival status\n                           with `show`.\n  --author                 Set the notebook's commit author email and name.\n  --email <email>          Set the notebook's commit author email to <email>.\n  --escaped                Print the notebook name with spaces escaped.\n  --filename [<filename>]  Print an available filename for the notebooks. When\n                           <filename> is provided, check for an existing file\n                           and provide a filename with an appended sequence\n                           number for uniqueness.\n  -f, --force              Skip the confirmation prompt.\n  --global                 List global notebooks or the notebook set globally\n                           with `use`.\n  --local                  Exit with 0 if current within a local notebook,\n                           otherwise exit with 1.\n  --name, --names          Print the notebook name.\n  --name <name>            Set the notebook's commit author name to <name>.\n  --path, --paths          Print the notebook path.\n  --selected               Exit with 0 if the current notebook differs from\n                           the current global notebook, otherwise exit with 1.\n  --unar, --unarchived     Only list unarchived notebooks.\n\nSubcommands:\n  (default)  List notebooks.\n  add        Create a new global notebook. When <remote-url> is specified,\n             create one or more new global notebook by cloning selected\n             or specified <branch>es from <remote-url>.\n             Aliases: `nb notebooks create`, `nb notebooks new`\n  archive    Set the current notebook or notebook <name> to \"archived\" status.\n  author     Configure the commit author email and name for the notebook.\n  current    Print the current notebook name or path.\n  delete     Delete a notebook.\n  export     Export the notebook <name> to the current directory or <path>,\n             making it usable as a local notebook.\n  import     Import the local notebook at <path> to make it global.\n  init       Create a new local notebook. Specify a <path> or omit to\n             initialize the current working directory as a local notebook.\n             Specify <remote-url> to clone an existing notebook.\n  open       Open the current notebook directory or notebook <name> in the\n             file browser, explorer, or finder.\n             Shortcut Alias: `o`\n  peek       Open the current notebook directory or notebook <name> in the\n             first tool found in the following list:\n             `ranger` [1], `mc` [2], `vifm` [3], `joshuto` [4], `lsd` [5],\n             `eza` [6], or `ls`.\n             Shortcut Alias: `p`\n  rename     Rename a notebook. Aliases: `move`, `mv`\n  select     Set the current notebook from a colon-prefixed selector.\n             Not persisted. Selection format: <notebook>:<identifier>\n  status     Print the archival status of the current notebook or\n             notebook <name>.\n  show       Show and return information about a specified notebook.\n  unarchive  Remove \"archived\" status from the current notebook or notebook <name>.\n  use        Switch to a notebook.\n\n    1. https://ranger.github.io/\n    2. https://en.wikipedia.org/wiki/Midnight_Commander\n    3. https://vifm.info/\n    4. https://github.com/kamiyaa/joshuto\n    5. https://github.com/lsd-rs/lsd\n    6. https://github.com/eza-community/eza\n\nDescription:\n  Manage notebooks.\n\nRead More:\n  https://github.com/xwmx/nb#-notebooks\n\nSee Also:\n  nb help archive\n  nb help history\n  nb help move\n  nb help remote\n  nb help status\n  nb help sync\n  nb help unarchive\n  nb help use\n\nExamples:\n  nb notebooks --names\n  nb notebooks add sample\n  nb notebooks add example https://github.com/example/example.git\n  nb nb current --path\n  nb nb archive example\n\nShortcut Aliases:\n  nb n\n  nb nb\n```\n\n#### `open`\n\n[↑](#-help) · See also:\n[Viewing Bookmarks](#viewing-bookmarks),\n[Images](#-images),\n[`bookmark`](#bookmark),\n[`browse`](#browse),\n[`peek`](#peek),\n[`show`](#show)\n\n```text\nUsage:\n  nb open ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nDescription:\n  Open an item or notebook. When the item is a bookmark, open the bookmarked\n  page in your system's primary web browser. When the item is in a text format\n  or any other file type, `open` is the equivalent of `edit`. `open`\n  with a notebook opens the notebook folder in the system's file browser.\n\nRead More:\n  https://github.com/xwmx/nb#viewing-bookmarks\n\nSee also:\n  nb help bookmark\n  nb help browse\n  nb help peek\n  nb help show\n\nExamples:\n  nb open 3\n  nb open example.bookmark.md\n  nb 3 open\n  nb example:open 12\n  nb open example:12\n  nb example:12 open\n  nb o 3\n  nb 3 o\n  nb o example:12\n  nb example:12 o\n\nShortcut Alias:\n  nb o\n```\n\n#### `peek`\n\n[↑](#-help) · See also:\n[Viewing Bookmarks](#viewing-bookmarks),\n[`bookmark`](#bookmark),\n[`browse`](#browse),\n[`open`](#open),\n[`show`](#show)\n\n```text\nUsage:\n  nb peek ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nDescription:\n  View an item or notebook in the terminal. When the item is a bookmark, view\n  the bookmarked page in your terminal web browser. When the note is in a text\n  format or any other file type, `peek` is the equivalent of `show`. When\n  used with a notebook, `peek` opens the notebook folder first tool found in\n  the following list: `ranger` [1], `mc` [2], `vifm` [3], `joshuto` [4],\n  `lsd` [5], eza` [6], or `ls`.\n\n    1. https://ranger.github.io/\n    2. https://en.wikipedia.org/wiki/Midnight_Commander\n    3. https://vifm.info/\n    4. https://github.com/kamiyaa/joshuto\n    5. https://github.com/lsd-rs/lsd\n    6. https://github.com/eza-community/eza\n\nRead More:\n  https://github.com/xwmx/nb#viewing-bookmarks\n\nSee also:\n  nb help bookmark\n  nb help browse\n  nb help open\n  nb help show\n\nExamples:\n  nb peek 3\n  nb peek example.bookmark.md\n  nb 3 peek\n  nb example:peek 12\n  nb peek example:12\n  nb example:12 peek\n  nb p 3\n  nb 3 p\n  nb p example:12\n  nb example:12 p\n\nAlias:\n  nb preview\n\nShortcut Alias:\n  nb p\n```\n\n#### `pin`\n\n[↑](#-help) · See also:\n[Pinning](#-pinning),\n[`browse`](#browse),\n[`list`](#list),\n[`ls`](#ls),\n[`unpin`](#unpin)\n\n```text\nUsage:\n  nb pin ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nDescription:\n  Pin an item so it appears first in lists.\n\nRead More:\n  https://github.com/xwmx/nb#-pinning\n\nSee Also:\n  nb help browse\n  nb help list\n  nb help ls\n  nb help unpin\n\nExamples:\n  nb pin 123\n  nb pin example:sample/321\n```\n\n#### `plugins`\n\n[↑](#-help) · See also:\n[Plugins](#-plugins),\n[Plugin Help](#plugin-help),\n[`subcommands`](#subcommands-1)\n\n```text\nUsage:\n  nb plugins [<name>] [--paths] [--force]\n  nb plugins install [<path> | <url>] [--force]\n  nb plugins uninstall <name>\n\nOptions:\n  --paths  Print the full path to each plugin.\n\nSubcommands:\n  (default)  List plugins.\n  install    Install a plugin from a <path> or <url>.\n  uninstall  Uninstall the specified plugin.\n\nDescription:\n  Manage plugins and themes.\n\nRead More:\n  https://github.com/xwmx/nb#-plugins\n\nPlugin Extensions:\n  .nb-theme   Plugins defining color themes.\n  .nb-plugin  Plugins defining new subcommands and functionality.\n\nSee Also:\n  nb help subcommands\n\nAlias:\n  nb plugin\n```\n\n#### `remote`\n\n[↑](#-help) · See also:\n[Git Sync](#-git-sync),\n[History](#-revision-history),\n[`history`](#history),\n[`notebooks`](#notebooks),\n[`status`](#status),\n[`sync`](#sync)\n\n```text\nUsage:\n  nb remote\n  nb remote branches [<url>]\n  nb remote delete <branch-name>\n  nb remote remove\n  nb remote rename [<branch-name>] <name>\n  nb remote reset <branch-name>\n  nb remote set <url> [<branch-name>]\n\nSubcommands:\n  (default)  Print the remote URL and branch for the notebook.\n  branches   List branches on the current or given remote.\n  delete     Delete <branch-name> from the remote.\n             Caveat: only orphan branches can be deleted.\n  remove     Remove the remote URL from the notebook.\n             Alias: `unset`\n  rename     Rename the current orphan branch or <branch-name> to <name>.\n             Caveat: only orphan branches can be renamed.\n  reset      Reset <branch-name> on the remote to a blank initial state.\n  set        Set the remote URL and branch for the notebook.\n\nDescription:\n  Configure the remote repository URL and branch for the current notebook.\n\nRead More:\n  https://github.com/xwmx/nb#-git-sync\n  https://github.com/xwmx/nb#-revision-history\n\nSee Also:\n  nb help history\n  nb help notebooks\n  nb help status\n  nb help sync\n\nExamples:\n  nb remote set https://github.com/example/example.git\n  nb remote remove\n  nb example-notebook:remote set https://github.com/example/example.git\n```\n\n#### `run`\n\n[↑](#-help) · See also: [`git`](#git), [`shell`](#shell)\n\n```text\nUsage:\n  nb run <command> [<arguments>...]\n\nDescription:\n  Run shell commands within the current notebook directory.\n\nSee Also:\n  nb help git\n  nb help shell\n\nExamples:\n  nb run ls -la\n  nb run find . -name 'example*'\n  nb run rg example\n```\n\n#### `search`\n\n[↑](#-help) · See also:\n[Search](#-search),\n[`browse`](#browse),\n[`list`](#list),\n[`ls`](#ls)\n\n```text\nUsage:\n  nb search ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <query>... [-a | --all] [--and <query>] [--not <query>] [--or <query>]\n            [-l | --list] [--path] [-t <tag1>,<tag2>... | --tag <tag1>,<tag2>...]\n            [-t | --tags] [--type <type> | --<type>] [--utility <name>]\n\nOptions:\n  -a, --all                     Search all unarchived notebooks.\n  --and <query>                 Add a AND query.\n  -l, --list                    Print the id, filename, and title listing for\n                                each matching file, without the excerpt.\n  --not <query>                 Add a NOT query.\n  --or  <query>                 Add an OR query.\n  --path                        Print the full path for each matching file.\n  -t, --tag <tag1>,<tag2>...    A comma-separated list of tags.\n  -t, --tags                    List all tags found in the notebook.\n  --type <type>, --<type>       Search items of <type>. <type> can be a file\n                                extension or one of the following types:\n                                archive, audio, book, bookmark, document,\n                                folder, image, note, text, video\n  --utility <name>              The name of the search utility to search with.\n\nDescription:\n  Perform a full text search.\n\n  Multiple query arguments are treated as AND queries, returning items that\n  match all queries. AND queries can also be specified with the --and <query>\n  option. The --or <query> option can be used to specify an OR query,\n  returning items that match at least one of the queries. --not <query>\n  excludes items matching <query>.\n\n  `nb search` is powered by Git's built-in `git grep` tool. `nb` also\n  supports performing searches with alternative search tools using the\n  --utility <name> option.\n\n  Supported alternative search tools:\n    1. `rga`   https://github.com/phiresky/ripgrep-all\n    2. `rg`    https://github.com/BurntSushi/ripgrep\n    3. `ag`    https://github.com/ggreer/the_silver_searcher\n    4. `ack`   https://beyondgrep.com/\n    5. `grep`  https://en.wikipedia.org/wiki/Grep\n\nRead More:\n  https://github.com/xwmx/nb#-search\n\nSee Also:\n  nb help browse\n  nb help list\n  nb help ls\n\nExamples:\n  # search current notebook for \"example query\"\n  nb search \"example query\"\n\n  # search the notebook \"example\" for \"example query\"\n  nb search example: \"example query\"\n\n  # search all notebooks for \"example query\" and list matching items\n  nb search \"example query\" --all --list\n\n  # search for items matching \"Example\" AND \"Demo\"\n  nb search \"Example\" \"Demo\"\n  nb search \"Example\" --and \"Demo\"\n\n  # search for items matching \"Example\" OR \"Sample\"\n  nb search \"Example|Sample\"\n  nb search \"Example\" --or \"Sample\"\n\n  # search for items matching both \"Example\" AND \"Sample\", and NOT \"Demo\"\n  nb search \"Example\" --and \"Sample\" --not \"Demo\"\n\n  # search with a regular expression\n  nb search \"\\d\\d\\d-\\d\\d\\d\\d\"\n\n  # search for tags\n  nb search --tag tag1 -t tag2\n\n  # search the current notebook for \"example query\"\n  nb q \"example query\"\n\n  # search all notebooks for \"example query\" and list matching items\n  nb q -la \"example query\"\n\nShortcut Alias:\n  nb q\n```\n\n#### `settings`\n\n[↑](#-help) · See also:\n[`set` & `settings`](#%EF%B8%8F-set--settings),\n[Variables](#-variables),\n[`unset`](#unset)\n\n```text\nUsage:\n  nb set [<name> [<value>] | <number> [<value>]]\n  nb settings colors [<number> | themes]\n  nb settings edit\n  nb settings get   (<name> | <number>)\n  nb settings list  [--long]\n  nb settings set   (<name> | <number>) <value>\n  nb settings show  (<name> | <number>)\n  nb settings unset (<name> | <number>)\n\nSubcommands:\n  (default)  Open the settings prompt, to <name> or <number>, if present.\n             When <value> is also present, assign <value> to the setting.\n  colors     Print a table of available colors and their xterm color numbers.\n             When <number> is provided, print the number in its color.\n             `settings colors themes` prints a list of installed themes.\n  edit       Open the `nb` configuration file in `$EDITOR`.\n  get        Print the value of a setting.\n  list       List information about available settings.\n  set        Assign <value> to a setting.\n  show       Print the help information and current value of a setting.\n  unset      Unset a setting, returning it to the default value.\n\nDescription:\n  Configure `nb`. Use `nb settings set` to customize a setting and\n  `nb settings unset` to restore the default for a setting.\n\n  Use the `nb set` alias to quickly assign values to settings:\n\n    nb set color_theme blacklight\n    nb set limit 40\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-set--settings\n\nSee Also:\n  nb help unset\n\nExamples:\n  nb settings\n  nb set 5 \"org\"\n  nb set color_primary 105\n  nb set unset color_primary\n  nb set color_secondary unset\n  nb settings colors\n  nb settings colors 105\n  nb set limit 15\n\nAlias:\n  nb set\n```\n\n##### `auto_sync`\n\n[↑](#-help) · See also: [Git Sync](#-git-sync)\n\n```text\n[1]  auto_sync\n     ---------\n     By default, operations that trigger a git commit like `add`, `edit`,\n     and `delete` will sync notebook changes to the remote repository, if\n     the notebook's remote is set. To disable this behavior, set this to \"0\".\n\n     • Default Value: 1\n```\n\n##### `color_primary`\n\n[↑](#-help) · See also: [Color Themes](#-color-themes), [Custom Color Themes](#custom-color-themes)\n\n```text\n[2]  color_primary\n     -------------\n     The primary color used to highlight identifiers and messages.\n\n     • Supported Values: xterm color numbers 0 through 255.\n     • Default Value:    68 (blue) for 256 color terminals,\n                         4  (blue) for  8  color terminals.\n```\n\n##### `color_secondary`\n\n[↑](#-help) · See also: [Color Themes](#-color-themes), [Custom Color Themes](#custom-color-themes)\n\n```text\n[3]  color_secondary\n     ---------------\n     The color used for lines and footer elements.\n\n     • Supported Values: xterm color numbers 0 through 255.\n     • Default Value:    8\n```\n\n##### `color_theme`\n\n[↑](#-help) · See also: [Color Themes](#-color-themes)\n\n```text\n[4]  color_theme\n     -----------\n     The color theme.\n\n     To view screenshots of the built-in themes, visit:\n\n         https://git.io/nb-docs-color-themes\n\n     `nb` supports custom, user-defined themes. To learn more, run:\n\n         nb help --colors\n\n     To change the syntax highlighting theme, use:\n\n         nb set syntax_theme\n\n     • Available themes:\n\n         blacklight\n         console\n         desert\n         electro\n         forest\n         nb\n         ocean\n         raspberry\n         smoke\n         unicorn\n         utility\n\n     • Default Value: nb\n```\n\n##### `default_extension`\n\n[↑](#-help) · See also: [Adding](#adding)\n\n```text\n[5]  default_extension\n     -----------------\n     The default extension to use for note files. Change to \"org\" for\n     Org files, \"rst\" for reStructuredText, \"txt\" for plain text, or\n     whatever you prefer.\n\n     • Default Value: md\n```\n\n##### `editor`\n\n[↑](#-help) · See also: [Editing](#editing), [Adding](#adding)\n\n```text\n[6]  editor\n     ------\n     The command line text editor used by `nb`.\n\n     • Example Values:\n\n         atom\n         code\n         emacs\n         hx\n         macdown\n         mate\n         micro\n         nano\n         pico\n         subl\n         vi\n         vim\n```\n\n##### `encryption_tool`\n\n[↑](#-help) · See also: [Password-Protected Encrypted Notes and Bookmarks](#password-protected-encrypted-notes-and-bookmarks)\n\n```text\n[7]  encryption_tool\n     ---------------\n     The tool used for encrypting notes.\n\n     • Supported Values: openssl, gpg\n     • Default Value:    openssl\n```\n\n##### `footer`\n\n[↑](#-help) · See also: [Listing & Filtering](#listing--filtering)\n\n```text\n[8]  footer\n     ------\n     By default, `nb` and `nb ls` include a footer with example commands.\n     To hide this footer, set this to \"0\".\n\n     • Default Value: 1\n```\n\n##### `header`\n\n[↑](#-help) · See also: [Listing & Filtering](#listing--filtering)\n\n```text\n[9]  header\n     ------\n     By default, `nb` and `nb ls` include a header listing available notebooks.\n     Set the alignment, or hide the header with \"0\".\n\n     • Supported Values:\n\n         0  Hide Header\n         1  Dynamic Alignment\n              - Left justified when list is shorter than terminal width.\n              - Center aligned when list is longer than terminal width.\n         2  Center Aligned (default)\n         3  Left Justified\n\n     • Default Value: 1\n```\n\n##### `limit`\n\n[↑](#-help) · See also: [Listing & Filtering](#listing--filtering)\n\n```text\n[10] limit\n     -----\n     The maximum number of items included in the `nb` and `nb ls` lists.\n     Set to `auto` to automatically limit output to the current terminal height.\n     Set a maximum auto limit with `auto^<max>`, e.g., `auto^15`.\n     Subtract an auto limit offset for multiline prompts with `auto-<offset>`.\n     Add an auto limit offet with `auto+<offset>`.\n     Combine both modifiers with `auto-<offset>^<max>` or `auto+<offset>^<max>`.\n\n     • Example Values:\n\n       15\n       auto\n       auto^15\n       auto-2\n       auto+2\n       auto-2^15\n       auto+2^15\n\n     • Default Value: 15\n```\n\n##### `nb_dir`\n\n[↑&nbsp;](#-help)\n\n```text\n[11] nb_dir\n     ------\n     The location of the directory that contains the notebooks.\n\n     For example, to sync all notebooks with Dropbox, create a folder at\n     `~/Dropbox/Notes` and run: `nb settings set nb_dir ~/Dropbox/Notes`\n\n     • Default Value: ~/.nb\n```\n\n##### `syntax_theme`\n\n[↑](#-help) · See also: [Terminal Syntax Highlighting](#terminal-syntax-highlighting-theme)\n\n```text\n[12] syntax_theme\n     ------------\n     The syntax highlighting theme. View examples with:\n\n         bat --list-themes\n\n     • Available themes:\n\n         1337\n         DarkNeon\n         Dracula\n         GitHub\n         Monokai Extended\n         Monokai Extended Bright\n         Monokai Extended Light\n         Monokai Extended Origin\n         Nord\n         OneHalfDark\n         OneHalfLight\n         Solarized (dark)\n         Solarized (light)\n         Sublime Snazzy\n         TwoDark\n         ansi-dark\n         ansi-light\n         base16\n         base16-256\n         gruvbox\n         gruvbox-light\n         gruvbox-white\n         zenburn\n\n     • Default Value: base16\n```\n\n#### `shell`\n\n[↑](#-help) · See also:\n[Interactive Shell](#-interactive-shell),\n[`run`](#run)\n\n```text\nUsage:\n  nb shell [<subcommand> [<options>...] | --clear-history]\n\nOptions:\n  --clear-history  Clear the `nb` shell history.\n\nDescription:\n  Start the `nb` interactive shell. Type \"exit\" to exit.\n\n  `nb shell` recognizes all `nb` subcommands and options, providing\n  a streamlined, distraction-free approach for working with `nb`.\n\n  When <subcommand> is present, the command will run as the shell is opened.\n\nRead More:\n  https://github.com/xwmx/nb#-interactive-shell\n\nSee Also:\n  nb help run\n\nExample:\n  $ nb shell\n  nb> ls 3\n  [3] Example\n\n  nb> edit 3 --content \"New content.\"\n  Updated: [3] Example\n\n  nb> notebook\n  home\n\n  nb> exit\n  $\n```\n\n#### `show`\n\n[↑](#-help) · See also:\n[Viewing](#viewing),\n[Images](#-images),\n[`browse`](#browse),\n[`open`](#open),\n[`peek`](#peek)\n\n```text\nUsage:\n  nb show ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[-a | --added] | [--authors] | [-b | --browse] | --filename | --id |\n          --info-line | --path | [-p | --print] | --relative-path | [-r |\n          --render] | --title | --type [<type>] | [-u | --updated]] [--no-color]\n  nb show <notebook>\n\nOptions:\n  -a, --added      Print the date and time when the item was added.\n  --authors        List the git commit authors of an item.\n  -b, --browse     Open the item with `nb browse`.\n  --filename       Print the filename of the item.\n  --id             Print the id number of the item.\n  --info-line      Print the id, filename, and title of the item.\n  --no-color       Show without syntax highlighting.\n  --path           Print the full path of the item.\n  -p, --print      Print to standard output / terminal.\n  --relative-path  Print the item's path relative within the notebook.\n  -r, --render     Use `pandoc` [1] to render the file to HTML and display\n                   in the terminal web browser. If either `pandoc` or a\n                   browser are unavailable, `-r` / `--render` is ignored.\n  --title          Print the title of the note.\n  --type [<type>]  Print the file extension or, when <type> is specified,\n                   return true if the item matches <type>. <type> can be a\n                   file extension or one of the following types:\n                   archive, audio, bookmark, document, folder, image,\n                   text, video\n  -u, --updated    Print the date and time of the last recorded change.\n\nDescription:\n  Show an item or notebook. Notes in text file formats can be rendered or\n  printed to standard output. Non-text files are opened in your system's\n  preferred app or program for that file type.\n\n  By default, the item is opened using `less` or the program configured\n  in the `$PAGER` environment variable. Use the following keys to navigate\n  in `less` (see `man less` for more information):\n\n    Key               Function\n    ---               --------\n    mouse scroll      Scroll up or down\n    arrow up or down  Scroll one line up or down\n    f                 Jump forward one window\n    b                 Jump back one window\n    d                 Jump down one half window\n    u                 Jump up one half window\n    /<query>          Search for <query>\n    n                 Jump to next <query> match\n    q                 Quit\n\n  To skip the pager and print to standard output, use the `-p` / `--print`\n  option.\n\n  `-r` / `--render` automatically uses either `w3m` [2] or `links` [3].\n  To specify a preferred browser, set the `$BROWSER` environment variable\n  in your .bashrc, .zshrc, or equivalent, e.g.: export BROWSER=\"links\"\n\n  If `bat` [4], `highlight` [5], or Pygments [6] is installed, notes are\n  printed with syntax highlighting.\n\n    1. https://pandoc.org/\n    2. https://en.wikipedia.org/wiki/W3m\n    3. https://en.wikipedia.org/wiki/Links_(web_browser)\n    4. https://github.com/sharkdp/bat\n    5. http://www.andre-simon.de/doku/highlight/en/highlight.php\n    6. https://pygments.org/\n\nRead More:\n  https://github.com/xwmx/nb#viewing\n\nSee Also:\n  nb help browse\n  nb help open\n  nb help peek\n\nExamples:\n  nb show 1\n  nb show example.md --render\n  nb show \"A Document Title\" --print --no-color\n  nb 1 show\n  nb example:show 12\n  nb show example:12\n  nb example:12 show\n  nb s 1\n  nb 1 s\n  nb s example:12\n  nb example:12 s\n\nAlias:\n  nb view\n\nShortcut Alias:\n  nb s\n```\n\n#### `status`\n\n[↑](#-help) · See also:\n[Git Sync](#-git-sync),\n[History](#-revision-history),\n[`archive`](#archive),\n[`history`](#history),\n[`notebooks`](#notebooks),\n[`remote`](#remote),\n[`sync`](#sync),\n[`unarchive`](#unarchive)\n\n```text\nUsage:\n  nb status [<notebook>]\n\nDescription:\n  Print archival, git, and remote status for the current notebook or <notebook>.\n\nRead More:\n  https://github.com/xwmx/nb#-git-sync\n  https://github.com/xwmx/nb#-revision-history\n\nSee Also:\n  nb help archive\n  nb help history\n  nb help notebooks\n  nb help remote\n  nb help sync\n  nb help unarchive\n\nExamples:\n  nb status\n  nb status example\n\nShortcut Alias:\n  nb st\n```\n\n#### `subcommands`\n\n[↑](#-help) · See also:\n[Plugins](#-plugins),\n[`plugins`](#plugins)\n\n```text\nUsage:\n  nb subcommands [add <name>...] [alias <name> <alias>]\n                 [describe <name> <usage>]\n\nSubcommands:\n  add       Add a new subcommand.\n  alias     Create an <alias> of a given subcommand <name>, with linked help.\n            Note that aliases must also be added with `subcommands add`.\n  describe  Set the usage text displayed with `nb help <subcommand>`.\n            This can be assigned as a heredoc, which is recommended, or\n            as a string argument.\n\nDescription:\n  List, add, alias, and describe subcommands. New subcommands, aliases, and\n  descriptions are not persisted, so `add`, `alias`, `describe` are\n  primarily for plugins.\n\nRead More:\n  https://github.com/xwmx/nb#-plugins\n\nSee Also:\n  nb help plugins\n```\n\n#### `sync`\n\n[↑](#-help) · See also:\n[Git Sync](#-git-sync),\n[History](#-revision-history),\n[`history`](#history),\n[`notebooks`](#notebooks),\n[`remote`](#remote),\n[`status`](#status)\n\n```text\nUsage:\n  nb sync [-a | --all]\n\nOptions:\n  -a, --all   Sync all unarchived notebooks.\n\nDescription:\n  Sync the current notebook with its remote.\n\nPrivate Repositories and Git Credentials:\n  Syncing with private repositories requires configuring git to not prompt\n  for credentials.\n\n  For repositories cloned over HTTPS, credentials can be cached with git.\n  For repositories cloned over SSH, keys can be added to the ssh-agent.\n\n  More Information:\n    https://github.com/xwmx/nb#private-repositories-and-git-credentials\n\nSync Conflict Resolution:\n  When `nb sync` encounters a conflict in a text file and can't merge\n  overlapping local and remote changes, both versions are saved in the\n  file, separated by git conflict markers. Use `nb edit` to remove the\n  conflict markers and delete any unwanted text.\n\n  When `nb sync` encounters a conflict in a binary file, such as an\n  encrypted note or bookmark, both versions of the file are saved in the\n  notebook as individual files, one with `--conflicted-copy` appended to\n  the filename.\n\n  More Information:\n    https://github.com/xwmx/nb#sync-conflict-resolution\n\nRead More:\n  https://github.com/xwmx/nb#-git-sync\n  https://github.com/xwmx/nb#-revision-history\n\nSee Also:\n  nb help history\n  nb help notebooks\n  nb help remote\n  nb help status\n\nExamples:\n  nb sync\n  nb sync --all\n```\n\n#### `tasks`\n\n[↑](#-help) · See also:\n[Tasks](#%EF%B8%8F-tasks),\n[Todos](#-todos),\n[`do`](#do),\n[`todo`](#todo),\n[`undo`](#undo)\n\n```text\nUsage:\n  nb tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n           [open | closed] [--pager]\n\nOptions:\n  --pager  Display output in the pager.\n\nDescription:\n  List tasks in todos, notebooks, folders, and other items.\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-tasks\n  https://github.com/xwmx/nb#-todos\n\nSee Also:\n  nb help do\n  nb help todo\n  nb help undo\n\nExamples:\n  nb tasks\n  nb tasks open\n  nb tasks closed\n  nb tasks 123\n  nb example:tasks open\n  nb tasks closed sample/\n  nb tasks closed demo:456\n\nShortcut Alias:\n  nb t\n```\n\n#### `todo`\n\n[↑](#-help) · See also:\n[Todos](#-todos),\n[`do`](#do),\n[`tasks`](#tasks),\n[`undo`](#undo)\n\n```text\nUsage:\n  nb todo add [<notebook>:][<folder-path>/][<filename>] <title>\n              [--description <description>] [--due <date>]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]\n              [--tags <tag1>,<tag2>...] [--task <title>...]\n  nb todo delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb todo do   ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  nb todo undo ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  nb todos [<notebook>:][<folder-path>/] [open | closed] [--pager]\n               [--tags <tag1>,<tag2>...]\n  nb todos tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n                 [open | closed] [--pager]\n\nOptions:\n  --description <description>         Description for the todo.\n  --due <date>                        Due date and / or time for the todo.\n  --pager                             Display output in the pager.\n  -r, --related (<url> | <selector>)  Related URL or selector.\n  --tags <tag1>,<tag2>...             Comma-separated list of tags.\n  --task <title>                      Task to add to the tasklist.\n\nSubcommands:\n  (default)   List todos.\n  add         Add a new todo.\n              Shortcut Aliases: `nb todo a`, `nb todo +`\n  delete      Delete a todo.\n              Shortcut Aliases: `nb todo -`\n  do          Mark a todo or task as done.\n  tasks       List tasks in todos, notebooks, folders, and other item.\n  undo        Unmark a todo or task as done.\n\nDescription:\n  Manage todos and tasks.\n\nRead More::\n  https://github.com/xwmx/nb#-todos\n\nSee Also:\n  nb help do\n  nb help tasks\n  nb help undo\n\nExamples:\n  nb todo add \"Example todo title.\"\n  nb todo add Example todo title.\n  nb todo add \"Sample title.\" --tags tag1,tag2 --related demo:567\n  nb todos\n  nb todos open\n  nb todos closed\n  nb example:todos open\n  nb todos closed sample/\n\nAlias:\n  nb todos\n\nShortcut Alias:\n  nb to\n```\n\n#### `unarchive`\n\n[↑](#-help) · See also:\n[Archiving Notebooks](#archiving-notebooks),\n[`archive`](#archive),\n[`notebooks`](#notebooks),\n[`status`](#status)\n\n```text\nUsage:\n  nb unarchive [<name>]\n\nDescription:\n  Remove \"archived\" status from the current notebook or notebook <name>.\n\n  This is an alias for `nb notebooks unarchive`.\n\nRead More:\n  https://github.com/xwmx/nb#archiving-notebooks\n\nSee Also:\n  nb help archive\n  nb help notebooks\n  nb help status\n\nExamples:\n  nb unarchive\n  nb unarchive example\n\nShortcut Alias:\n  nb unar\n```\n\n#### `undo`\n\n[↑](#-help) · See also:\n[Todos](#-todos),\n[Tasks](#%EF%B8%8F-tasks),\n[`do`](#do),\n[`tasks`](#tasks),\n[`todo`](#todo)\n\n```text\nUsage:\n  nb undo ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [<task-number>]\n\nDescription:\n  Mark a todo or task as not done.\n\nRead More:\n  https://github.com/xwmx/nb#-todos\n\nSee Also:\n  nb help do\n  nb help tasks\n  nb help todo\n\nExamples:\n  nb undo 123\n  nb undo example:sample/321\n  nb undo 543 7\n```\n\n#### `unpin`\n\n[↑](#-help) · See also:\n[Pinning](#-pinning),\n[`browse`](#browse),\n[`list`](#list),\n[`ls`](#ls),\n[`pin`](#pin)\n\n```text\nUsage:\n  nb unpin ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nDescription:\n  Unpin a pinned item.\n\nRead More:\n  https://github.com/xwmx/nb#-pinning\n\nSee Also:\n  nb help browse\n  nb help list\n  nb help ls\n  nb help pin\n\nExamples:\n  nb unpin 123\n  nb unpin example:sample/321\n```\n\n#### `unset`\n\n[↑](#-help) · See also:\n[`set` & `settings`](#%EF%B8%8F-set--settings),\n[`settings`](#settings)\n\n```text\nUsage:\n  nb unset (<name> | <number>)\n\nDescription:\n  Unset a setting, returning it to the default value.\n\n  This is an alias for `nb settings unset`.\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-set--settings\n\nSee Also:\n  nb help settings\n\nExamples:\n  nb unset color_primary\n  nb unset 2\n\nAlias:\n  nb reset\n```\n\n#### `update`\n\n[↑](#-help) · See also:\n[Installation](#installation),\n[`env`](#env),\n[`version`](#version)\n\n```text\nUsage:\n  nb update\n\nDescription:\n  Update `nb` to the latest version. You will be prompted for\n  your password if administrator privileges are required.\n\n  If `nb` was installed using a package manager like npm or\n  Homebrew, use the package manager's upgrade functionality instead\n  of this command.\n\nRead More:\n  https://github.com/xwmx/nb#installation\n\nSee Also:\n  nb help env\n  nb help version\n```\n\n#### `use`\n\n[↑](#-help) · See also:\n[Notebooks](#-notebooks),\n[`notebooks`](#notebooks)\n\n```text\nUsage:\n  nb use <notebook>\n\nDescription:\n  Switch to the specified notebook. Shortcut for `nb notebooks use`.\n\nRead More:\n  https://github.com/xwmx/nb#-notebooks\n\nSee Also:\n  nb help notebooks\n\nExample:\n  nb use example\n\nShortcut Alias:\n  nb u\n```\n\n#### `version`\n\n[↑](#-help) · See also:\n[Installation](#installation),\n[`env`](#env),\n[`update`](#update)\n\n```text\nUsage:\n  nb version\n\nDescription:\n  Display version information.\n\nSee Also:\n  nb help env\n  nb help update\n```\n\n### Plugin Help\n\n<p>\n  <sup>\n    <a href=\"#-help\">↑</a> ·\n    <a href=\"#-plugins\">Plugins</a>,\n    <a href=\"#plugins\"><code>nb plugins</code></a>\n  </sup>\n</p>\n\n<div align=\"center\">\n  <a href=\"#backlink\">backlink</a>&nbsp;·\n  <a href=\"#bump\">bump</a>&nbsp;·\n  <a href=\"#clip\">clip</a>&nbsp;·\n  <a href=\"#daily\">daily</a>&nbsp;·\n  <a href=\"#ebook\">ebook</a>&nbsp;·\n  <a href=\"#example\">example</a>&nbsp;·\n  <a href=\"#weather\">weather</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#-help\">&nbsp;↑&nbsp;</a>\n</div>\n\n#### `backlink`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/backlink.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb backlink [--force]\n\nDescription:\n  Add backlinks to notes. Crawl notes in a notebook for [[wiki-style links]]\n  and append a \"Backlinks\" section to each linked file that lists passages\n  referencing the note.\n\n  To link to a note from within another note, surround the title of the\n  target note in double square brackets:\n\n      Example with link to [[Target Note Title]] in content.\n\n  Depends on note-link-janitor:\n    https://github.com/andymatuschak/note-link-janitor\n\n    Requirement: every note in the notebook must have a title.\n```\n\n#### `bump`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/bump.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb bump [<notebook>:][<folder-path>/][<id>][<filename>][<title>]\n\nDescription:\n  Bump an item to the top of the list.\n\n  `bump` updates the item's modification timestamp without editing the item\n  or creating a new commit.\n\nExamples:\n  nb bump 123\n  nb bump example:sample/456\n\nAlias:\n  nb touch\n```\n\n#### `clip`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/clip.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb clip [<notebook>:][<id> | <filename> | <path> | <title> | <extension>]\n\nDescription:\n  Save the clipboard contents and copy contents of text or markdown items to\n  the clipboard.\n\n  When called with no arguments or when no matching file is found, the text\n  content on the clipboard is saved to a new file, pending a prompt.\n\nExamples:\n  # copy the content of item 123 to the clipboard\n  nb clip 123\n\n  # save the clipboard contents to a new file with a `.js` file extension\n  nb clip .js\n\n  # save the clipboard contents as a new `.cr` file in the \"snippets\" notebook\n  nb snippets:clip .cr\n```\n\n#### `daily`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/daily.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb daily [<content>] [--prev [<number>]]\n\nOptions:\n  --prev [<number>]   List previous days and show day by previous <number>.\n\nDescription:\n  Add notes to a daily log. When called without arguments, the current day's\n  log is displayed. When passed `<content>`, a new timestamped entry is added\n  to the current day's log, which is created if it doesn't yet exist.\n\n  Previous day's logs can be listed with the `--prev` option. View a previous\n  day's log by passing its `<number>` in the list.\n\nExamples:\n  nb daily \"Example note content.\"\n  nb daily\n  nb daily --prev\n  nb daily --prev 3\n```\n\n#### `ebook`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/ebook.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb ebook new <name>\n  nb ebook publish\n\nSubcommands:\n  ebook new      Create a new notebook initialized with placeholder files for\n                 authoring an ebook.\n  ebook publish  Generate a .epub file using the current notebook contents.\n\nDescription:\n  Ebook authoring with `nb`.\n\n  `nb ebook new` creates a notebook populated with initial placeholder files\n  for creating an ebook. Edit the title page and chapters using normal `nb`\n  commands, then use `nb ebook publish` to generate an epub file.\n\n  Chapters are expected to be markdown files with sequential numeric\n  filename prefixes for ordering:\n\n    01-example.md\n    02-sample.md\n    03-demo.md\n\n  Create new chapters with `nb add`:\n\n    nb add --filename \"04-chapter4.md\"\n\n  title.txt contains the book metadata in a YAML block. For more information\n  about the fields for this file, visit:\n\n    https://pandoc.org/MANUAL.html#epub-metadata\n\n  stylesheet.css contains base styling for the generated ebook. It can be used\n  as it is and can also be edited using `nb edit`.\n\n  As with all `nb` notebooks, changes are recorded automatically in git,\n  providing automatic version control for all ebook content, source, and\n  metadata files.\n\n  Generated epub files are saved in the notebook and can be previewed in the\n  terminal with `nb show`. Export a generated epub file with `nb export`:\n\n    nb export 12 .\n\nMore info:\n  https://pandoc.org/epub.html\n```\n\n#### `example`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/example.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb example\n\nDescription:\n  Print \"Hello, World!\"\n```\n\n#### `weather`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/weather.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb weather [<option>...]\n\nDescription:\n  Display weather information from wttr.in.\n\nMore Info:\n  https://github.com/chubin/wttr.in\n  https://wttr.in\n\nExamples:\n  nb weather\n  nb weather Tokyo\n  nb weather lax\n\nShortcut Alias:\n  nb w\n```\n\n### `$` Variables\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#%EF%B8%8F-set--settings\"><code>set</code>&<code>settings</code></a>,\n    <a href=\"#settings\"><code>nb settings</code></a>\n  </sup>\n</p>\n\n<div align=\"center\">\n  <sup>\n    <a href=\"#editor-1\"><code>$EDITOR</code></a>&nbsp;·\n    <a href=\"#nb_ace_enabled\"><code>$NB_ACE_ENABLED</code></a>&nbsp;·\n    <a href=\"#nb_ace_md_gutter\"><code>$NB_ACE_MD_GUTTER</code></a>&nbsp;·\n    <a href=\"#nb_ace_relative_line_numbers\"><code>$NB_ACE_RELATIVE_LINE_NUMBERS</code></a>&nbsp;·\n    <a href=\"#nb_ace_soft_tabs\"><code>$NB_ACE_SOFT_TABS</code></a>&nbsp;·\n    <a href=\"#nb_ace_keyboard\"><code>$NB_ACE_KEYBOARD</code></a>&nbsp;·\n    <a href=\"#nb_audio_tool\"><code>$NB_AUDIO_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_auto_sync\"><code>$NB_AUTO_SYNC</code></a>&nbsp;·\n    <a href=\"#nb_auto_sync_seconds\"><code>$NB_AUTO_SYNC_SECONDS</code></a>&nbsp;·\n    <a href=\"#nb_bookmark_content_cleanup_tool\"><code>$NB_BOOKMARK_CONTENT_CLEANUP_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_bookmark_content_conversion_tool\"><code>$NB_BOOKMARK_CONTENT_CONVERSION_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_browse_markdown_reader\"><code>$NB_BROWSE_MARKDOWN_READER</code></a>&nbsp;·\n    <a href=\"#nb_browse_server_tool\"><code>$NB_BROWSE_SERVER_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_browse_support_links\"><code>$NB_BROWSE_SUPPORT_LINKS</code></a>&nbsp;·\n    <a href=\"#nb_browser\"><code>$NB_BROWSER</code></a>&nbsp;·\n    <a href=\"#nb_color_primary\"><code>$NB_COLOR_PRIMARY</code></a>&nbsp;·\n    <a href=\"#nb_color_secondary\"><code>$NB_COLOR_SECONDARY</code></a>&nbsp;·\n    <a href=\"#nb_color_theme\"><code>$NB_COLOR_THEME</code></a>&nbsp;·\n    <a href=\"#nb_custom_css\"><code>$NB_CUSTOM_CSS</code></a>&nbsp;·\n    <a href=\"#nb_custom_css_url\"><code>$NB_CUSTOM_CSS_URL</code></a>&nbsp;·\n    <a href=\"#nb_custom_javascript\"><code>$NB_CUSTOM_JAVASCRIPT</code></a>&nbsp;·\n    <a href=\"#nb_custom_javascript_url\"><code>$NB_CUSTOM_JAVASCRIPT_URL</code></a>&nbsp;·\n    <a href=\"#nb_data_tool\"><code>$NB_DATA_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_default_extension\"><code>$NB_DEFAULT_EXTENSION</code></a>&nbsp;·\n    <a href=\"#nb_default_template\"><code>$NB_DEFAULT_TEMPLATE</code></a>&nbsp;·\n    <a href=\"#nb_dir-1\"><code>$NB_DIR</code></a>&nbsp;·\n    <a href=\"#nb_directory_tool\"><code>$NB_DIRECTORY_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_editor\"><code>$NB_EDITOR</code></a>&nbsp;·\n    <a href=\"#nb_encryption_tool\"><code>$NB_ENCRYPTION_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_folders_first\"><code>$NB_FOLDERS_FIRST</code></a>&nbsp;·\n    <a href=\"#nb_footer\"><code>$NB_FOOTER</code></a>&nbsp;·\n    <a href=\"#nb_gui_browser\"><code>$NB_GUI_BROWSER</code></a>&nbsp;·\n    <a href=\"#nb_header\"><code>$NB_HEADER</code></a>&nbsp;·\n    <a href=\"#nb_image_tool\"><code>$NB_IMAGE_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_indicator_audio\"><code>$NB_INDICATOR_AUDIO</code></a>&nbsp;·\n    <a href=\"#nb_indicator_bookmark\"><code>$NB_INDICATOR_BOOKMARK</code></a>&nbsp;·\n    <a href=\"#nb_indicator_document\"><code>$NB_INDICATOR_DOCUMENT</code></a>&nbsp;·\n    <a href=\"#nb_indicator_ebook\"><code>$NB_INDICATOR_EBOOK</code></a>&nbsp;·\n    <a href=\"#nb_indicator_encrypted\"><code>$NB_INDICATOR_ENCRYPTED</code></a>&nbsp;·\n    <a href=\"#nb_indicator_folder\"><code>$NB_INDICATOR_FOLDER</code></a>&nbsp;·\n    <a href=\"#nb_indicator_image\"><code>$NB_INDICATOR_IMAGE</code></a>&nbsp;·\n    <a href=\"#nb_indicator_pinned\"><code>$NB_INDICATOR_PINNED</code></a>&nbsp;·\n    <a href=\"#nb_indicator_todo\"><code>$NB_INDICATOR_TODO</code></a>&nbsp;·\n    <a href=\"#nb_indicator_todo_done\"><code>$NB_INDICATOR_TODO_DONE</code></a>&nbsp;·\n    <a href=\"#nb_indicator_video\"><code>$NB_INDICATOR_VIDEO</code></a>&nbsp;·\n    <a href=\"#nb_limit\"><code>$NB_LIMIT</code></a>&nbsp;·\n    <a href=\"#nb_mathjax_enabled\"><code>$NB_MATHJAX_ENABLED</code></a>&nbsp;·\n    <a href=\"#nb_markdown_tool\"><code>$NB_MARKDOWN_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_pinned_pattern\"><code>$NB_PINNED_PATTERN</code></a>&nbsp;·\n    <a href=\"#nb_server_host\"><code>$NB_SERVER_HOST</code></a>&nbsp;·\n    <a href=\"#nb_server_port\"><code>$NB_SERVER_PORT</code></a>&nbsp;·\n    <a href=\"#nb_syntax_theme\"><code>$NB_SYNTAX_THEME</code></a>&nbsp;·\n    <a href=\"#nb_user_agent\"><code>$NB_USER_AGENT</code></a>&nbsp;·\n    <a href=\"#nbrc_path\"><code>$NBRC_PATH</code></a>\n    </sup>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#overview\">&nbsp;↑&nbsp;</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n[Settings](#%EF%B8%8F-set--settings) are set in the `~/.nbrc` configuration\nfile using environment variables. Settings can be set through `nb`\nusing [`set` & `settings`](#%EF%B8%8F-set--settings) or by\nassigning a value to the variable directly in the `~/.nbrc` file, which\ncan be opened in your `$EDITOR` with [`nb settings edit`](#settings).\n\nExample assignment:\n\n```bash\nexport NB_INDICATOR_PINNED=\"🔮\"\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$EDITOR`\n\n```text\nThe terminal editor command for editing items.\n\nSee also: `$NB_EDITOR`\n\nExample Values: 'code', 'emacs', 'hx', 'vim'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_ENABLED`\n\n```text\nDefault: '0'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_MD_GUTTER`\n\n```text\nDefault: '1'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_RELATIVE_LINE_NUMBERS`\n\n```text\nDefault: '0'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_SOFT_TABS`\n\n```text\nDefault: '0'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_KEYBOARD`\n\n```text\nDefault: 'ace'\n\nExample Values: 'emacs', 'sublime', 'vim', 'vscode'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_AUDIO_TOOL`\n\n```text\nDefault: '' (first available)\n\nExample Values: 'mplayer', 'afplay'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_AUTO_SYNC`\n\n```text\nDefault: '1'\n\nWhen set to '1', each `_git checkpoint()` call will automativally run\n`$_ME sync`. To disable this behavior, set the value to '0'.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_AUTO_SYNC_SECONDS`\n\n```text\nDefault: '60'\n\nThe minimum number of seconds between automatic Git sync operations when\n`$NB_AUTO_SYNC` is enabled.\n\nSupported Values: '0' or any positive integer\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BOOKMARK_CONTENT_CLEANUP_TOOL`\n\n```text\nDefault: 'readability'\n\nThe tool used to clean up HTML content before conversion to markdown\nwhen creating bookmarks.\n\nSupported Tools:\n\n- https://www.npmjs.com/package/readability-cli\n- https://github.com/eafer/rdrview\n\nSupported Values: '', 'rdrview', 'readability'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BOOKMARK_CONTENT_CONVERSION_TOOL`\n\n```text\nDefault: 'pandoc'\n\nThe tool used to convert HTML content to markdown when creating\nbookmarks.\n\nSupported Tools:\n\n- https://github.com/JohannesKaufmann/html-to-markdown\n- https://github.com/microsoft/markitdown\n- https://pandoc.org\n\nSupported Values: '', 'html-to-markdown', 'markitdown', 'pandoc'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BROWSE_MARKDOWN_READER`\n\n```text\n$NB_BROWSE_MARKDOWN_READER\n\nDefault: 'markdown+emoji+raw_html+east_asian_line_breaks'\n\nThe Pandoc reader, including extensions, to use for converting Markdown to\nHTML in `nb browse`.\n\nMore information:\n  https://pandoc.org/MANUAL.html#extensions\n  https://pandoc.org/MANUAL.html#general-options-1\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BROWSE_SERVER_TOOL`\n\n```text\nDefault: first available: 'ncat', 'socat', 'netcat', 'bash' (5.2+ only), ''\n\nThe tool used to listen on the server host and port and respond to\nincoming requests.\n\nSupported Values: 'accept', 'bash', 'nc', 'ncat', netcat', 'socat'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BROWSE_SUPPORT_LINKS`\n\n```text\nDefault: '1'\n\nSet to '0' to hide the 'Donate' and 'Sponsor' links in `nb browse`.\n\nSupported Values: '0' '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BROWSER`\n\n```text\nDefault: value of $BROWSER\n\nExample Values: 'links', 'w3m'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_COLOR_PRIMARY`\n\n```text\nDefault: Value depends on terminal capabilities.\n\nSet highlighting color. This should be set to an xterm color number, usually\na value between 1 and 256. For a table of common colors and their numbers\nrun:\n\n  nb settings colors\n\nSupported Values: [0..255+]\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_COLOR_SECONDARY`\n\n```text\nDefault: '8'\n\nColor for lines and other accents. This should be set to an xterm color\nnumber, usually a value between 1 and 256. For a table of common colors and\ntheir numbers, run:\n\n  nb settings colors\n\nSupported Values: [0..255+]\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_COLOR_THEME`\n\n```text\nDefault: 'nb'\n\nThe color theme.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_CUSTOM_CSS`\n\n```text\nDefault: ''\n\nA style sheet to be included inline in a `<style>` element on pages\nrendered by `nb browse`.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_CUSTOM_CSS_URL`\n\n```text\nDefault: ''\n\nA URL to a style sheet to be included in a `<link rel=\"stylesheet\">`\nelement on pages rendered by `nb browse`.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_CUSTOM_JAVASCRIPT`\n\n```text\nDefault: ''\n\nA block of JavaScript code to be included inline in a `<script>` element\non pages rendered by `nb browse`.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_CUSTOM_JAVASCRIPT_URL`\n\n```text\nDefault: ''\n\nA URL to a JavaScript file to be included in a `<script src=//url>`\nelement on pages rendered by `nb browse`.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DATA_TOOL`\n\n```text\nDefault: '' (first available)\n\nExample Values: 'visidata', 'sc-im'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DEFAULT_EXTENSION`\n\n```text\nDefault: 'md'\n\nExample Values: 'md' 'org'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DEFAULT_TEMPLATE`\n\n```text\nDefault: ''\n\nA string template or a path to a template file.\n\nExample Values: '/path/to/template/file' '# {{title}} {{content}}'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DIR`\n\n```text\nDefault: `$HOME/.nb`\n\nThe location of the directory that contains the notebooks.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DIRECTORY_TOOL`\n\n```text\nDefault: '' (nb browse)\n\nExample Values: 'ranger', 'mc'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_EDITOR`\n\n```text\nDefault: the value of `$EDITOR`\n\nThe terminal editor command for editing items. Overrides the value of\n`$EDITOR` in the environment.\n\nSee also: `$EDITOR`\n\nExample Values: 'code', 'emacs', 'hx', 'vim'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ENCRYPTION_TOOL`\n\n```text\nDefault: 'openssl'\n\nSupported Values: 'gpg' 'openssl'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_FOLDERS_FIRST`\n\n```text\nDefault: '0'\n\nWhen set to '1', folders are printed before other items in `nb`, `nb ls`,\nand `nb browse`.\n\nSupported Values: '0' '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_FOOTER`\n\n```text\nDefault: '1'\n\nSupported Values: '0' '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_GUI_BROWSER`\n\n```text\nDefault: ''\n\nExample Value: 'firefox'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_HEADER`\n\n```text\nDefault: '2'\n\nSupported Values: '0' '1' '2' '3'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_IMAGE_TOOL`\n\n```text\nDefault: '' (first available)\n\nExample Values: 'imgcat', 'catimg'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_AUDIO`\n\n```text\nDefault: 🔉\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_BOOKMARK`\n\n```text\nDefault: 🔖\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_DOCUMENT`\n\n```text\nDefault: 📄\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_EBOOK`\n\n```text\nDefault: 📖\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_ENCRYPTED`\n\n```text\nDefault: 🔒\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_FOLDER`\n\n```text\nDefault: 📂\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_IMAGE`\n\n```text\nDefault: 🌄\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_PINNED`\n\n```text\nDefault: 📌\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_TODO`\n\n```text\nDefault: ✔️\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_TODO_DONE`\n\n```text\nDefault: ✅\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_VIDEO`\n\n```text\nDefault: 📹\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_LIMIT`\n\n```text\nDefault: '15'\n\nSet to a positive number to limit the output of `nb` and `nb ls` to that value.\nSet to \"auto\" to automatically limit output to the current terminal height.\nSet a maximum auto limit with `auto^<max>`, e.g., `auto^15`.\nSubtract an auto limit offset for multiline prompts with `auto-<offset>`.\nAdd an auto limit offet with `auto+<offset>`.\nCombine both modifiers with `auto-<offset>^<max>` or `auto+<offset>^<max>`.\n\nSupported Values:\n  - <max>\n  - auto\n  - auto^<max>\n  - auto-<offset>\n  - auto+<offset>\n  - auto-<offset>^<max>\n  - auto+<offset>^<max>\n\nExample Values:\n  - 15\n  - auto\n  - auto^15\n  - auto-2\n  - auto+2\n  - auto-2^15\n  - auto+2^15\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_MATHJAX_ENABLED`\n\n```text\nDefault: '0'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_MARKDOWN_TOOL`\n\n```text\nDefault: '' (default pager)\n\nSupported Values: 'bat', 'glow', 'lowdown', 'mdcat', 'mdless', 'mdv'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_PINNED_PATTERN`\n\n```text\nExample Value: '#pinned'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_SERVER_HOST`\n\n```text\nDefault: 'localhost'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_SERVER_PORT`\n\n```text\nDefault: '6789'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_SYNTAX_THEME`\n\n```text\nDefault: 'base16'\n\nSupported Values: Theme names listed with `bat --list-themes`\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_USER_AGENT`\n\n```text\nDefault: '' (`curl` or `wget` default user agent)\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NBRC_PATH`\n\n```text\nDefault: `$HOME/.nbrc`\n\nThe location of the .nbrc configuration file.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n## Specifications\n\n<div align=\"center\">\n  <a href=\"#nb-markdown-bookmark-file-format\">Bookmark File Format</a>&nbsp;·\n  <a href=\"#nb-markdown-todo-file-format\">Todo File Format</a>&nbsp;·\n  <a href=\"#nb-notebook-specification\">Notebook Specification</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#-help\">&nbsp;↑&nbsp;</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n### `nb` Markdown Bookmark File Format\n\n<p>\n  <sup>\n    <a href=\"#specifications\">↑</a> ·\n    <a href=\"#-bookmarks\">Bookmarks</a>,\n    <a href=\"#bookmark\"><code>nb bookmark</code></a>\n  </sup>\n</p>\n\n#### Extension\n\n`.bookmark.md`\n\n#### Description\n\n`nb` bookmarks are Markdown documents created using a combination of\nuser input and data from the bookmarked page. The `nb` bookmark format\nis intended to be readable, editable, convertible, renderable, and\nclearly organized for greatest accessibility.\n\nBookmarks are identified by a `.bookmark.md` file extension. The\nbookmark URL is the first URL in the file within `<` and `>` characters.\nTo create a minimally valid bookmark file with [`nb add`](#add):\n\n```bash\nnb add example.bookmark.md --content \"<https://example.com>\"\n```\n\nThis creates a file with the name `example.bookmark.md` containing:\n\n```markdown\n<https://example.com>\n```\n\nIn a full bookmark, information is separated into sections,\nwith each bookmark section indicated by a Markdown `h2` heading.\n\n#### Example\n\n````markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Quote\n\n> Example quote line one.\n>\n> Example quote line two.\n\n## Comment\n\nExample comment.\n\n## Related\n\n- <https://example.net>\n- <https://example.org>\n- [[example:123]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n\n## Source\n\n```html\n<!doctype html>\n<html>\n  <head>\n    <title>Example Title</title>\n    <meta name=\"description\" content=\"Example description.\" />\n  </head>\n\n  <body>\n    <h1>Example Title</h1>\n    <p>\n      This domain is for use in illustrative examples in documents. You may\n      use this domain in literature without prior coordination or asking for\n      permission.\n    </p>\n    <p>\n      <a href=\"https://www.iana.org/domains/example\">More information...</a>\n    </p>\n  </body>\n</html>\n```\n````\n\n#### Elements\n\n##### Title\n\n`Optional`\n\nA [Markdown atx-style `h1` heading\n](https://daringfireball.net/projects/markdown/syntax#header)\ncontaining the content of the bookmarked page's\nHTML `<title>` or [`og:title`](https://ogp.me/) tag, if present, followed by\nthe domain within parentheses.\n\n###### Examples\n\n```markdown\n# Example Title (example.com)\n```\n```markdown\n# (example.com)\n```\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### URL\n\n`Required`\n\nThe URL of the bookmarked resource, with surrounding angle brackets\n(`<`, `>`).\n\nThis is the only required element.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Description`\n\n`Optional`\n\nA text element containing the content of the bookmarked page's meta description\nor [`og:description`](https://ogp.me/) tag, if present.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Quote`\n\n`Optional`\n\nA markdown quote block containing a user-specified excerpt from the bookmarked\nresource.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Comment`\n\n`Optional`\n\nA text element containing a comment written by the user.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Related`\n\n`Optional`\n\nA Markdown list of\nangle bracketed (`<`, `>`) URLs and\n[[[wiki-style links]]](#-linking)\nthat are related to the bookmarked resource.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Tags`\n\n`Optional`\n\nA list of [#tags](#-tagging)\nrepresented as `#hashtags`\nseparated by individual spaces.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Content`\n\n`Optional`\n\nThe full content of the bookmarked page, converted to Markdown.\n\nThe `## Content` section makes the page content available locally for\nfull-text search and viewing of page content. The source HTML is converted\nto inline Markdown to reduce the amount of markup, make it more readable,\nand make page content easily viewable in the terminal as markdown and\nstreamlined HTML in web browsers.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Source`\n\n`Optional`\n\nA fenced code block with `html` language identifier containing the source HTML\nfrom the bookmarked page.\n\n`nb` does not save the page source by default. `nb` uses this section to save\nthe source HTML page content when `pandoc` is not available to convert it to\nMarkdown.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n### `nb` Markdown Todo File Format\n\n<p>\n  <sup>\n    <a href=\"#specifications\">↑</a> ·\n    <a href=\"#-todos\">Todos</a>,\n    <a href=\"#todo\"><code>nb todo</code></a>\n  </sup>\n</p>\n\n#### Extension\n\n`.todo.md`\n\n#### Description\n\n`nb` todos are Markdown documents identified by a `.todo.md` file extension.\nTodos contain a Markdown `h1` heading\nstarting with a Markdown checkbox (`[ ]` / `[x]`) indicating\nthe todo completion state, followed by the todo title.\n\n#### Example\n\n```markdown\n# [x] Example todo title.\n\n## Due\n\n2100-01-01\n\n## Description\n\nExample description.\n\n## Tasks\n\n- [ ] One\n- [x] Two\n- [ ] Three\n\n## Related\n\n- [[example:123]]\n- <https://example.org>\n\n## Tags\n\n#tag1 #tag2\n```\n\n#### Elements\n\n##### Title\n\n`Required`\n\nA [Markdown atx-style `h1` heading\n](https://daringfireball.net/projects/markdown/syntax#header)\ncontaining a Markdown checkbox followed by the todo title.\nAn `x` within the checkbox (`[ ]`) indicates that the todo is done.\n\n###### Examples\n\n```markdown\n# [ ] Example undone / open todo title.\n```\n```markdown\n# [x] Example done / closed todo title.\n```\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Due`\n\n`Optional`\n\nA text element containing a value referencing\na due date and / or time for the todo.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Description`\n\n`Optional`\n\nA text element containing a description for the todo.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Tasks`\n\n`Optional`\n\nA markdown tasklist containing sub-tasks for the todo.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Related`\n\n`Optional`\n\nA Markdown list of\nangle bracketed (`<`, `>`) URLs and\n[[[wiki-style links]]](#-linking)\nthat are related to the todo.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Tags`\n\n`Optional`\n\nA list of [#tags](#-tagging)\nrepresented as `#hashtags`\nseparated by individual spaces.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n### `nb` Notebook Specification\n\n<p>\n  <sup>\n    <a href=\"#specifications\">↑</a> ·\n    <a href=\"#-notebooks\">Notebooks</a>,\n    <a href=\"#notebooks\"><code>nb notebooks</code></a>\n  </sup>\n</p>\n\nAn `nb` notebook is a directory that contains a valid `.git` directory,\nindicating that it has been initialized as a git repository, and a `.index`\nfile in the root directory.\n\n#### `.index` Files\n\nA notebook folder index is a text file named `.index` in any folder\nwithin the notebook directory. `.index` contains a list of visible\nfilenames within the folder, one per line, and the line number of each\nfilename represents the id. `.index` files are included in the git repository\nso ids are preserved across systems.\n\n##### Operations\n\n<dl>\n  <dt><code>add</code></dt>\n  <dd>Append a new line containing the filename to <code>.index</code>.</dd>\n  <dt><code>update</code></dt>\n  <dd>Overwrite the existing filename in <code>.index</code> with the new filename.</dd>\n  <dt><code>delete</code></dt>\n  <dd>Delete the filename, preserving the newline, leaving the line blank.</dd>\n  <dt><code>reconcile</code></dt>\n  <dd>Remove duplicate lines, preserving existing blank lines, <code>add</code> entries for new files, and <code>delete</code> entries for deleted files.</dd>\n  <dt><code>rebuild</code></dt>\n  <dd>Delete and rebuild <code>.index</code>, listing files by most recently modified, reversed.</dd>\n</dl>\n\n##### `index` Subcommand\n\n`nb` manages the `.index` of each folder within a notebook using an internal\n`index` subcommand.\n\n###### `nb help index`\n\n```text\nUsage:\n  nb index add <filename>\n  nb index delete <filename>\n  nb index edit\n  nb index get_basename <id>\n  nb index get_id <filename>\n  nb index get_max_id\n  nb index rebuild [--ancestors]\n  nb index reconcile [--ancestors] [--commit]\n  nb index show\n  nb index update <existing-filename> <new-filename>\n  nb index verify\n  nb index <subcommand> <options>... [<folder-path>]\n\nOptions:\n  --ancestors   Perform the action on all folders within the notebook that\n                are ancestors of the current folder.\n  --commit      Commit changes to git.\n\nSubcommands:\n  add           Add <filename> to the index.\n  delete        Delete <filename> from the index.\n  edit          Open the index file in `$EDITOR`.\n  get_basename  Print the filename / basename at the specified <id>.\n  get_id        Get the id for <filename>.\n  get_max_id    Get the maximum id for the folder.\n  rebuild       Rebuild the index, listing files by last modified, reversed.\n                Some ids will change. Prefer `nb index reconcile`.\n  reconcile     Remove duplicates and update index for added and deleted files.\n  show          Print the index.\n  update        Overwrite the <existing-filename> entry with <new-filename>.\n  verify        Verify that the index matches the folder contents.\n\nDescription:\n  Manage the index for the current folder or the folder at <folder-path>,\n  which can be passed as the final argument to any `index` subcommand.\n\n  `index` is used internally by `nb` and using it manually will\n  probably corrupt the index. If something goes wrong with an index,\n  fix it with `nb index reconcile`.\n\n  An index is a text file named '.index' in any folder within a notebook.\n  .index contains a list of filenames and the line number of each filename\n  represents the id. .index files are included in the git repository so\n  ids are preserved across systems.\n```\n\n<p>\n  <sup>\n    <a href=\"#nb-notebook-specification\">↑</a>\n  </sup>\n</p>\n\n#### `.pindex` Files\n\nAny folder may contain an optional plain text file named `.pindex`\ncontaining a list of basenames from that folder, one per line, that should\nbe treated as [pinned](#-pinning), meaning they appear first in some\nlist operations, including `nb` and [`nb ls`](#ls). Entries are added to a\n`.pindex` file with [`nb pin`](#pin) and removed with [`nb unpin`](#unpin).\n\n<p>\n  <sup>\n    <a href=\"#nb-notebook-specification\">↑</a>\n  </sup>\n</p>\n\n#### Archived Notebooks\n\nA notebook is considered [archived](#archiving-notebooks)\nwhen it contains a file named `.archived`\nat the root level of the notebook directory.\n\n<p>\n  <sup>\n    <a href=\"#nb-notebook-specification\">↑</a>\n  </sup>\n</p>\n\n## Tests\n\nWith more than 2,200 tests spanning tens of thousands of lines,\n`nb` is really mostly a\n[test suite](https://github.com/xwmx/nb/tree/master/test).\nTests run continuously [via GitHub Actions](https://github.com/xwmx/nb/actions)\non recent versions of both Ubuntu and macOS to account for differences between\nBSD and GNU tools and Bash versions.\nTo run the tests locally, install\n[Bats](https://github.com/bats-core/bats-core)\nand the [recommended dependencies](#optional),\nthen run `bats test` within the project root directory. Run groups of\ntests with globbing, e.g., `bats test/browse*` and `bats test/folders*`.\n\n<div align=\"center\">\n  <span>\n  <a href=\"#overview\">&nbsp;↑&nbsp;</a>\n  </span>\n\n  <br/>\n</div>\n\n---\n\n<div align=\"center\">\n  <span>\n  Copyright (c) 2015-present ·\n  <a href=\"https://www.williammelody.com/\">William Melody</a> ·\n  <a href=\"https://github.com/xwmx/nb/blob/master/LICENSE\">AGPLv3</a>\n  </span>\n\n  <br/>\n  <br/>\n</div>\n\n<div align=\"center\">\n  <span>\n  <a href=\"https://xwmx.github.io/nb\">xwmx.github.io/nb</a>&nbsp;·\n  <a href=\"https://github.com/xwmx/nb\">github.com/xwmx/nb</a>\n  </span>\n\n  <br/>\n  <br/>\n</div>\n\n<div align=\"center\">\n  <span>\n  📝🔖🔒🔍📔\n  </span>\n\n  <br/>\n  <br/>\n</div>\n\n<div align=\"center\">\n  <span>\n  <a href=\"#top\">&nbsp;↑&nbsp;</a>\n  </span>\n</div>\n"
  },
  {
    "path": "bin/bookmark",
    "content": "#!/usr/bin/env bash\n###############################################################################\n#     __                __                        __\n#    / /_  ____  ____  / /______ ___  ____ ______/ /__\n#   / __ \\/ __ \\/ __ \\/ //_/ __ `__ \\/ __ `/ ___/ //_/\n#  / /_/ / /_/ / /_/ / ,< / / / / / / /_/ / /  / ,<\n# /_.___/\\____/\\____/_/|_/_/ /_/ /_/\\__,_/_/  /_/|_|\n#\n# bookmark -- Command line bookmarking with tagging, encryption,\n# full-text page content search with regular expression support,\n# GUI and terminal browser support, and data stored in plain text\n# Markdown files with Git-backed versioning and syncing.\n#\n# Part of:\n# __          _\n# \\ \\   _ __ | |__\n#  \\ \\ | '_ \\| '_ \\\n#  / / | | | | |_) |\n# /_/  |_| |_|_.__/\n#\n# [nb] Command line and local web note-taking, bookmarking, and archiving with\n# plain text data storage, encryption, filtering and search, pinning, #tagging,\n# Git-backed versioning and syncing, Pandoc-backed conversion, global and local\n# notebooks, customizable color themes, [[wiki-style linking]], plugins, and\n# more in a single portable, user-friendly script.\n#\n# https://github.com/xwmx/nb\n#\n# Based on Bash Boilerplate: https://github.com/xwmx/bash-boilerplate\n#\n# Copyright (c) 2015-present William Melody • hi@williammelody.com\n# AGPLv3 • See LICENSE for details.\n###############################################################################\n\nexport _NB_PATH=\"${_NB_PATH:-}\"\n\nif [[ -z \"${_NB_PATH:-}\" ]]\nthen\n  _NB_PATH=\"$(command -v nb)\"\nfi\n\nif [[ -z \"${_NB_PATH:-}\" ]]\nthen\n  cat <<HEREDOC\n\\`bookmark\\` is part of \\`nb\\`. To install \\`nb\\`, see:\n  https://github.com/xwmx/nb\nHEREDOC\nfi\n\n_main() {\n  if [[ -z \"${1:-}\" ]]\n  then\n    local _count=0\n    while IFS= read -r __line\n    do\n      _count=$((_count+1))\n\n      if [[ \"${_count}\" == 1 ]] ||\n         [[ \"${_count}\" == 6 ]] ||\n         [[ \"${_count}\" == 8 ]]\n      then\n        printf \"%s\\\\n\" \"${__line}\"                      \\\n          | sed -e 's/nb help bookmark/bookmark help/'  \\\n          | sed -e 's/nb/bookmark/'\n      elif [[ \"${_count}\" == 2 ]]\n      then\n        printf \"%s\\\\n\" \"${__line}\"                      \\\n          | sed -e 's/-------------------------/----------------------------/'\n      else\n        printf \"%s\\\\n\" \"${__line}\"\n      fi\n    done < <(\"${_NB_PATH:-}\" bookmark)\n  elif [[   \"${1:-}\" =~ ^-h$|^--help$|^h$|^help$  ]] || {\n         [[ \"${1:-}\" =~ ^q$|^search$              ]] &&\n         [[ -z \"${2:-}\"                           ]]\n\n       }\n  then\n    {\n      cat <<HEREDOC\n    __                __                        __\n   / /_  ____  ____  / /______ ___  ____ ______/ /__\n  / __ \\\\/ __ \\\\/ __ \\\\/ //_/ __ \\`__ \\\\/ __ \\`/ ___/ //_/\n / /_/ / /_/ / /_/ / ,< / / / / / / /_/ / /  / ,<\n/_.___/\\\\____/\\\\____/_/|_/_/ /_/ /_/\\\\__,_/_/  /_/|_|\n\nbookmark -- Command line bookmarking with tagging, encryption,\nfull-text page content search with regular expression support,\nGUI and terminal browser support, and data stored in plain text\nMarkdown files with Git-backed versioning and syncing.\n\nHEREDOC\n      \"${_NB_PATH:-}\" help bookmark                 \\\n        | sed -e \"/  nb example/d\"                  \\\n        | sed -e \"s/  nb https/  bookmark https/g\"  \\\n        | sed -e \"s/  nb bookmark/  bookmark/g\"     \\\n        | sed -e \"/  nb b$/d\"                       \\\n        | sed -e \"/  nb bk$/d\"                      \\\n        | sed -e \"/  nb bm$/d\"                      \\\n        | sed -e \"s/Shortcut Alias: \\`b\\`//\"        \\\n        | sed -e \"s/Shortcut Alias: \\`bk\\`//\"       \\\n        | sed -e \"s/Shortcut Aliases.*//\"           \\\n        | sed -e '$ d'\n\n      cat <<HEREDOC\n------------------------------------------\nPart of \\`nb\\` (https://github.com/xwmx/nb).\nFor more information, see: \\`nb help\\`.\nHEREDOC\n    } | if [[ -n \"${PAGER:-}\" ]] && [[ ! \"${PAGER:-}\" =~ less ]]\n        then\n          \"${PAGER}\"\n        elif hash \"less\" 2>/dev/null\n        then\n          less -R           \\\n            --CLEAR-SCREEN  \\\n            --prompt=\"> scroll for more, h for help, or q to quit\"\n        else\n          cat\n        fi\n  else\n    \"${_NB_PATH}\" bookmark \"${@:-}\"\n  fi\n} && _main \"${@:-}\"\n"
  },
  {
    "path": "bin/notes",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# __                _\n# \\ \\   _ __   ___ | |_ ___  ___\n#  \\ \\ | '_ \\ / _ \\| __/ _ \\/ __|\n#  / / | | | | (_) | ||  __/\\__ \\\n# /_/  |_| |_|\\___/ \\__\\___||___/\n#\n# `notes`\n#\n# Part of:\n# __          _\n# \\ \\   _ __ | |__\n#  \\ \\ | '_ \\| '_ \\\n#  / / | | | | |_) |\n# /_/  |_| |_|_.__/\n#\n# [nb] Command line and local web note-taking, bookmarking, and archiving with\n# plain text data storage, encryption, filtering and search, pinning, #tagging,\n# Git-backed versioning and syncing, Pandoc-backed conversion, global and local\n# notebooks, customizable color themes, [[wiki-style linking]], plugins, and\n# more in a single portable, user-friendly script.\n#\n# https://github.com/xwmx/nb\n#\n# Based on Bash Boilerplate: https://github.com/xwmx/bash-boilerplate\n#\n# Copyright (c) 2015-present William Melody • hi@williammelody.com\n# AGPLv3 • See LICENSE for details.\n###############################################################################\n\nexport _NB_PATH=\"${_NB_PATH:-}\"\n\nif [[ -z \"${_NB_PATH:-}\" ]]\nthen\n  _NB_PATH=\"$(command -v nb)\"\nfi\n\nif [[ -z \"${_NB_PATH:-}\" ]]\nthen\n  cat <<HEREDOC\n\\`notes\\` is part of \\`nb\\`. To install \\`nb\\`, see:\n  https://github.com/xwmx/nb\nHEREDOC\nfi\n\n_main() {\n  if [[ \"${1:-}\" =~ ^-h$|^--help$|^h$|^help$ ]] ||\n     {\n       [[ \"${1:-}\" =~ ^q$|^search$ ]] && [[ -z \"${2:-}\" ]]\n     }\n  then\n    {\n\n      shift\n\n      {\n        if [[ -n \"${*:-}\" ]]\n        then\n          \"${_NB_PATH:-}\" help \"${@}\"\n        else\n          cat <<HEREDOC\n  __                _\n  \\ \\   _ __   ___ | |_ ___  ___\n   \\ \\ | '_ \\ / _ \\| __/ _ \\/ __|\n   / / | | | | (_) | ||  __/\\__ \\\\\n  /_/  |_| |_|\\___/ \\__\\___||___/\n\n Part of [nb]\nHEREDOC\n          \"${_NB_PATH:-}\" help | sed -e '1,6d'\n\n        fi\n      } | sed -e \"s/^  nb$/  notes/g\"         \\\n        | sed -e \"s/  nb /  notes /g\"         \\\n        | sed -e \"s/\\`nb/\\`notes/g\"           \\\n        | sed -e \"s/^\\`notes\\`/\\`nb\\`/g\"      \\\n        | sed -E \"s/nb(.*Command)/notes\\1/g\"  \\\n        | sed -e '$ d'\n\n      cat <<HEREDOC\n------------------------------------------\nPart of \\`nb\\` (https://github.com/xwmx/nb).\nFor more information, see: \\`nb help\\`.\nHEREDOC\n    } | if [[ -n \"${PAGER:-}\" ]] && [[ ! \"${PAGER:-}\" =~ less ]]\n        then\n          \"${PAGER}\"\n        elif hash \"less\" 2>/dev/null\n        then\n          less              \\\n            --CLEAR-SCREEN  \\\n            --prompt=\"> scroll for more, h for help, or q to quit\"\n        else\n          cat\n        fi\n  else\n    \"${_NB_PATH}\" \"${@:-}\"\n  fi\n} && _main \"${@:-}\"\n"
  },
  {
    "path": "docs/.gitignore",
    "content": "_site\n.sass-cache\n.jekyll-cache\n.jekyll-metadata\nvendor\n"
  },
  {
    "path": "docs/.rubocop.yml",
    "content": "inherit_from: .rubocop_todo.yml\n"
  },
  {
    "path": "docs/.rubocop_todo.yml",
    "content": "# This configuration was generated by\n# `rubocop --auto-gen-config`\n# on 2020-09-25 20:07:34 UTC using RuboCop version 0.92.0.\n# The point is for the user to remove these configuration records\n# one by one as the offenses are removed from the code base.\n# Note that changes in the inspected code, or installation of new\n# versions of RuboCop, may require this file to be generated again.\n\n# Offense count: 1\n# Cop supports --auto-correct.\n# Configuration parameters: EnforcedStyle.\n# SupportedStyles: final_newline, final_blank_line\nLayout/TrailingEmptyLines:\n  Exclude:\n    - 'Gemfile'\n\n# Offense count: 1\n# Cop supports --auto-correct.\n# Configuration parameters: EnforcedStyle.\n# SupportedStyles: always, always_true, never\nStyle/FrozenStringLiteralComment:\n  Exclude:\n    - 'Gemfile'\n\n# Offense count: 1\n# Cop supports --auto-correct.\n# Configuration parameters: UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.\n# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys\nStyle/HashSyntax:\n  EnforcedStyle: hash_rockets\n\n# Offense count: 12\n# Cop supports --auto-correct.\n# Configuration parameters: ConsistentQuotesInMultiline.\n# SupportedStyles: single_quotes, double_quotes\nStyle/StringLiterals:\n  EnforcedStyle: double_quotes\n\n# Offense count: 1\n# Cop supports --auto-correct.\n# Configuration parameters: MinSize.\n# SupportedStyles: percent, brackets\nStyle/SymbolArray:\n  EnforcedStyle: brackets\n"
  },
  {
    "path": "docs/.ruby-version",
    "content": "3.4.8\n"
  },
  {
    "path": "docs/.tool-versions",
    "content": "ruby 3.4.8\n"
  },
  {
    "path": "docs/404.html",
    "content": "---\npermalink: /404.html\nlayout: default\n---\n\n<style type=\"text/css\" media=\"screen\">\n  .container {\n    margin: 10px auto;\n    max-width: 600px;\n    text-align: center;\n  }\n  h1 {\n    margin: 30px 0;\n    font-size: 4em;\n    line-height: 1;\n    letter-spacing: -1px;\n  }\n</style>\n\n<div class=\"container\">\n  <h1>404</h1>\n\n  <p><strong>Page not found :(</strong></p>\n  <p>The requested page could not be found.</p>\n</div>\n"
  },
  {
    "path": "docs/Gemfile",
    "content": "source \"https://rubygems.org\"\nruby \"3.4.8\"\n# Hello! This is where you manage which Jekyll version is used to run.\n# When you want to use a different version, change it below, save the\n# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:\n#\n#     bundle exec jekyll serve\n#\n# This will help ensure the proper Jekyll version is running.\n# Happy Jekylling!\n# gem \"jekyll\", \"~> 4.1.1\"\n# This is the default theme for new Jekyll sites. You may change this to anything you like.\ngem \"minima\", \">= 2.5\"\n# If you want to use GitHub Pages, remove the \"gem \"jekyll\"\" above and\n# uncomment the line below. To upgrade, run `bundle update github-pages`.\ngem \"github-pages\", group: :jekyll_plugins\n# If you have any plugins, put them here!\n# group :jekyll_plugins do\n#   gem \"jekyll-feed\", \"~> 0.12\"\n# end\n\n# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem\n# and associated library.\nplatforms :mingw, :x64_mingw, :mswin, :jruby do\n  gem \"tzinfo\", \">= 1.2\"\n  gem \"tzinfo-data\"\nend\n\n# Performance-booster for watching directories on Windows\ngem \"wdm\", \">= 0.1.1\", :platforms => [:mingw, :x64_mingw, :mswin]\n\n# Just the Docs\n#\n# A Jekyll theme.\n#\n# https://pmarsceill.github.io/just-the-docs/\ngem \"just-the-docs\"\n"
  },
  {
    "path": "docs/_config.yml",
    "content": "# Welcome to Jekyll!\n#\n# This config file is meant for settings that affect your whole blog, values\n# which you are expected to set up once and rarely edit after that. If you find\n# yourself editing this file very often, consider using Jekyll's data files\n# feature for the data you need to update frequently.\n#\n# For technical reasons, this file is *NOT* reloaded automatically when you use\n# 'bundle exec jekyll serve'. If you change this file, please restart the server process.\n#\n# If you need help with YAML syntax, here are some quick references for you:\n# https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml\n# https://learnxinyminutes.com/docs/yaml/\n#\n# Site settings\n# These are used to personalize your new site. If you look in the HTML files,\n# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.\n# You can create any custom variable you would like, and they will be accessible\n# in the templates via {{ site.myvariable }}.\n\n###############################################################################\n# Just the Docs\n#\n# https://github.com/pmarsceill/just-the-docs\n# https://pmarsceill.github.io/just-the-docs/docs/configuration/\n\nremote_theme: pmarsceill/just-the-docs\n\n# Aux links for the upper right navigation\naux_links:\n  \"<code>&lt;code&gt;</code>\":\n    - \"//github.com/xwmx/nb\"\n\ncolor_scheme: \"light\"\n\nga_tracking: \"UA-190590-18\"\n\nlogo: \"/assets/images/nb.png\"\n\nsearch_enabled: true\n\nsearch:\n  heading_level: 3\n  preview_words_after: 5\n  preview_words_before: 5\n\ntoc_list: true\n\ntitle: nb\nemail: hi@williammelody.com\ndescription: >- # this means to ignore newlines until \"baseurl:\"\n  A CLI and local web plain text\n  note-taking, bookmarking, archiving,\n  and knowledge base application.\n# the subpath of your site, e.g. /blog\nbaseurl: \"/nb\"\n# the base hostname & protocol for your site, e.g. http://example.com\nurl: \"https://xwmx.github.io\"\n\n# twitter_username: jekyllrb\n# github_username:  jekyll\n\n# Build settings\n# theme: minima\n# plugins:\n#   - jekyll-feed\n#   - jekyll-seo-tag\n\n# Exclude from processing.\n# The following items will not be processed, by default.\n# Any item listed under the `exclude:` key here will be automatically added to\n# the internal \"default list\".\n#\n# Excluded items can be processed by explicitly listing the directories or\n# their entries' file path in the `include:` list.\n#\n# exclude:\n#   - .sass-cache/\n#   - .jekyll-cache/\n#   - gemfiles/\n#   - Gemfile\n#   - Gemfile.lock\n#   - node_modules/\n#   - vendor/bundle/\n#   - vendor/cache/\n#   - vendor/gems/\n#   - vendor/ruby/\n\nexclude:\n  - color-themes.md\n"
  },
  {
    "path": "docs/_includes/favicon.html",
    "content": "<!-- <link rel=\"shortcut icon\" href=\"{{ 'favicon.ico' | relative_url }}\" type=\"image/x-icon\"> -->\n\n<link rel=\"icon\" type=\"image/x-icon\" href=\"data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAACQWAAAkFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAon8IB59/AlSegwFunYgCVJ+RBhGdlAFcnZkAbp2eAkqcpwMxm6sBaJuxAzCbtwJim7wChZrAAlCaxgUHmsQEAKN+CQafgQJqnYUB2p6JA2WfkQYPnpYDdp2aAdmengNXnKgEMZutAsCbsgHNm7cCiZu9AnGZwwG8mMcCbo6pAACehgIAnYYCIJ2HAbeeigMYnpUFAJ6cBSednQK1nqAEE5irAACbsQKTm7MBlp++DwKZxgIAmccCPZjKAbuZzQQXnogCAJ2IAiCdigG8no0EHZ6XBQCenwUnnZ8CtZ6iBBOZrgAAm7MCkZu1AmqatAAAmcsEAJnLAx2YzQG9mc8EKJ2LAgCdigIenY0B152RAlqdlwAAnqEEL52iAbaepQQQmLAAAJu2ApObuAGbncQKBJjLAQCZzQJBmM8BupnRBBafiQUOnYsBep2OAdOdlAKsnZoChZ2gAaidowKVoKwOA5a3AACbuAKQm7sC0ZrCApCYyAF8mM0Bv5jPAmeTxgAAn4oGDJ6MA1WekANJnpcEIp2cAmudoAJsnaQDGp2jAgCVuwAAm7sCkJu9A3GZxAJUmcgCe5nNAkaa0QUGmdAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKjBJwCZuwAAnLkFFZu9AqSbvwNkmr4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACowSYAl7sAAJu6A1iavQGym8EDQprAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqcMpAJu9AACcvAUEnMAECJ3ECAKcwwcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAAABAAAAAQAAiIgAAIiYAACIiAAAAIEAAAGBAAD/HwAA/x8AAP8fAAD//wAA//8AAA==\">\n"
  },
  {
    "path": "docs/_includes/head.html",
    "content": "<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">\n\n  {% unless site.plugins contains \"jekyll-seo-tag\" %}\n    <title>{{ page.title or site.title }}</title>\n\n    {% if page.description %}\n      <meta name=\"Description\" content=\"{{ page.description }}\">\n    {% endif %}\n  {% endunless %}\n\n  {% include favicon.html %}\n\n  <link rel=\"stylesheet\" href=\"{{ '/assets/css/just-the-docs-default.css' | relative_url }}\">\n\n  {% if site.ga_tracking != nil %}\n    <script async src=\"https://www.googletagmanager.com/gtag/js?id={{ site.ga_tracking }}\"></script>\n    <script>\n      window.dataLayer = window.dataLayer || [];\n      function gtag(){dataLayer.push(arguments);}\n      gtag('js', new Date());\n\n      gtag('config', '{{ site.ga_tracking }}'{% unless site.ga_tracking_anonymize_ip == nil %}, { 'anonymize_ip': true }{% endunless %});\n    </script>\n\n  {% endif %}\n\n  {% if site.search_enabled != false %}\n    <script type=\"text/javascript\" src=\"{{ '/assets/js/vendor/lunr.min.js' | relative_url }}\"></script>\n  {% endif %}\n\n  {% if site.mermaid %}\n    <script src=\"https://cdn.jsdelivr.net/npm/mermaid@{{ site.mermaid.version }}/dist/mermaid.min.js\"></script>\n  {% endif %}\n\n  <script type=\"text/javascript\" src=\"{{ '/assets/js/just-the-docs.js' | relative_url }}\"></script>\n\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n  {% seo %}\n\n  {% include head_custom.html %}\n\n</head>\n"
  },
  {
    "path": "docs/_includes/js/custom.js",
    "content": ""
  },
  {
    "path": "docs/_includes/nav.html",
    "content": "{% comment %}{% include toc.html html=content class=\"navigation-list\" h_max=3 %}{% endcomment %}\n\n<ul class=\"nav-list\">\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#home\">\n      ❯\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <!-- <li class=\"nav-list-item\"> -->\n  <!--   <a class=\"nav-list-link\" href=\"#nb\"> -->\n  <!--     <code class=\"language-plaintext highlighter-rouge\">nb</code> -->\n  <!--   </a><span class=\"nav-separator\">&nbsp;·</span> -->\n  <!-- </li> -->\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#installation\">\n      Installation\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#overview\">\n      Overview\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-notes\">\n      📝 Notes\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-bookmarks\">\n      🔖 Bookmarks\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-todos\">\n      ✅ Todos\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#%EF%B8%8F-tasks\">\n      ✔️ Tasks\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-tagging\">\n      🏷 Tagging\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-linking\">\n      🔗 Linking\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-browsing\">\n      🌍 Browsing\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-images\">\n      🌄 Images\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-zettelkasten\">\n      🗂 Zettelkasten\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-folders\">\n      📂 Folders\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-pinning\">\n      📌 Pinning\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-search\">\n      🔍 Search\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-moving--renaming\">\n      ↔ Moving & Renaming\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-revision-history\">\n      🗒 Revision History\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-notebooks\">\n      📚 Notebooks\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-git-sync\">\n      🔄 Git Sync\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#%EF%B8%8F-import--export\">\n      ↕️ Import / Export\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item nav-settings\">\n    <a class=\"nav-list-link\" href=\"#%EF%B8%8F-set--settings\">\n      ⚙️ <code class=\"language-plaintext highlighter-rouge\">set</code>\n      &amp;\n      <code class=\"language-plaintext highlighter-rouge\">settings</code>\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-color-themes\">\n      🎨 Color Themes\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-plugins\">\n      🔌 Plugins\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-selectors\">\n      <code>:/</code> Selectors\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#01-metadata\">\n      <code>01</code> Metadata\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-interactive-shell\">\n      <code>❯</code> Shell\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#shortcut-aliases\">\n      Shortcut Aliases\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-help\">\n      <code>?</code> Help / Usage\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#subcommands\">\n      Subcommands\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#plugin-help\">\n      Plugin Help\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#-variables\">\n      <code>$</code> Variables\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#specifications\">\n      Specifications\n    </a><span class=\"nav-separator\">&nbsp;·</span>\n  </li>\n  <li class=\"nav-list-item\">\n    <a class=\"nav-list-link\" href=\"#tests\">\n      Tests\n    </a>\n  </li>\n</ul>\n\n<script\n  src=\"https://code.jquery.com/jquery-3.5.1.min.js\"\n  integrity=\"sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=\"\n  crossorigin=\"anonymous\"></script>\n<script src=\"./assets/js/link-img-elements.js\"></script>\n<script src=\"./assets/js/scroll-highlight.js\"></script>\n\n<script>\n  $(document).ready(function() {\n    $(\"td:contains(\\u00a0)\").css('padding', '0');\n  });\n</script>\n\n<link href=\"https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap\" rel=\"stylesheet\">\n"
  },
  {
    "path": "docs/_includes/toc.html",
    "content": "{% capture tocWorkspace %}\n    {% comment %}\n        Copyright (c) 2017 Vladimir \"allejo\" Jimenez\n\n        Permission is hereby granted, free of charge, to any person\n        obtaining a copy of this software and associated documentation\n        files (the \"Software\"), to deal in the Software without\n        restriction, including without limitation the rights to use,\n        copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the\n        Software is furnished to do so, subject to the following\n        conditions:\n\n        The above copyright notice and this permission notice shall be\n        included in all copies or substantial portions of the Software.\n\n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n        EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n        OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n        NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n        HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n        WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n        FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n        OTHER DEALINGS IN THE SOFTWARE.\n    {% endcomment %}\n    {% comment %}\n        Version 1.0.14\n          https://github.com/allejo/jekyll-toc\n\n        \"...like all things liquid - where there's a will, and ~36 hours to spare, there's usually a/some way\" ~jaybe\n\n        Usage:\n            {% include toc.html html=content sanitize=true class=\"inline_toc\" id=\"my_toc\" h_min=2 h_max=3 %}\n\n        Parameters:\n            * html         (string) - the HTML of compiled markdown generated by kramdown in Jekyll\n\n        Optional Parameters:\n            * sanitize      (bool)   : false  - when set to true, the headers will be stripped of any HTML in the TOC\n            * class         (string) :   ''   - a CSS class assigned to the TOC\n            * id            (string) :   ''   - an ID to assigned to the TOC\n            * h_min         (int)    :   1    - the minimum TOC header level to use; any header lower than this value will be ignored\n            * h_max         (int)    :   6    - the maximum TOC header level to use; any header greater than this value will be ignored\n            * ordered       (bool)   : false  - when set to true, an ordered list will be outputted instead of an unordered list\n            * item_class    (string) :   ''   - add custom class(es) for each list item; has support for '%level%' placeholder, which is the current heading level\n            * submenu_class (string) :   ''   - add custom class(es) for each child group of headings; has support for '%level%' placeholder which is the current \"submenu\" heading level\n            * baseurl       (string) :   ''   - add a base url to the TOC links for when your TOC is on another page than the actual content\n            * anchor_class  (string) :   ''   - add custom class(es) for each anchor element\n            * skipNoIDs     (bool)   : false  - skip headers that do not have an `id` attribute\n\n        Output:\n            An ordered or unordered list representing the table of contents of a markdown block. This snippet will only\n            generate the table of contents and will NOT output the markdown given to it\n    {% endcomment %}\n\n    {% capture my_toc %}{% endcapture %}\n    {% assign orderedList = include.ordered | default: false %}\n    {% assign skipNoIDs = include.skipNoIDs | default: false %}\n    {% assign minHeader = include.h_min | default: 1 %}\n    {% assign maxHeader = include.h_max | default: 6 %}\n    {% assign nodes = include.html | split: '<h' %}\n    {% assign firstHeader = true %}\n    {% assign previousLevel = 0 %}\n\n    {% capture listModifier %}{% if orderedList %}1.{% else %}-{% endif %}{% endcapture %}\n\n    {% for node in nodes %}\n        {% if node == \"\" %}\n            {% continue %}\n        {% endif %}\n\n        {% assign headerLevel = node | replace: '\"', '' | slice: 0, 1 | times: 1 %}\n\n        {% if headerLevel < minHeader or headerLevel > maxHeader %}\n            {% continue %}\n        {% endif %}\n\n        {% assign _workspace = node | split: '</h' %}\n\n        {% assign _idWorkspace = _workspace[0] | split: 'id=\"' %}\n        {% assign _idWorkspace = _idWorkspace[1] | split: '\"' %}\n        {% assign html_id = _idWorkspace[0] %}\n\n        {% assign _classWorkspace = _workspace[0] | split: 'class=\"' %}\n        {% assign _classWorkspace = _classWorkspace[1] | split: '\"' %}\n        {% assign html_class = _classWorkspace[0] %}\n\n        {% if html_class contains \"no_toc\" %}\n            {% continue %}\n        {% endif %}\n\n        {% if firstHeader %}\n            {% assign firstHeader = false %}\n            {% assign minHeader = headerLevel %}\n        {% endif %}\n\n        {% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %}\n        {% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}\n\n        {% assign indentAmount = headerLevel | minus: minHeader %}\n        {% assign space = '' %}\n        {% for i in (1..indentAmount) %}\n            {% assign space = space | prepend: '    ' %}\n        {% endfor %}\n\n        {% if include.item_class and include.item_class != blank %}\n            {% capture listItemClass %}{:.{{ include.item_class | replace: '%level%', headerLevel }}}{% endcapture %}\n        {% endif %}\n\n        {% capture anchor_body %}{% if include.sanitize %}{{ header | strip_html }}{% else %}{{ header }}{% endif %}{% endcapture %}\n        {% capture anchor_body %}{{ anchor_body | replace: \"|\", \"\\|\" }}{% endcapture %}\n\n        {% if html_id %}\n            {% capture list_item %}[{{ anchor_body }}]({% if include.baseurl %}{{ include.baseurl }}{% endif %}#{{ html_id }}){% endcapture %}\n        {% elsif skipNoIDs == true %}\n            {% continue %}\n        {% else %}\n            {% capture list_item %}{{ anchor_body }}{% endcapture %}\n        {% endif %}\n\n        <!--\n        If we have a submenu class and we're unindenting, then we need to add a \"closing\" class to this group of bullet\n        points\n        -->\n        {% if include.submenu_class and previousLevel > indentAmount %}\n            <!--\n            `space` is the current indentation, so we if want to close off the previous grouping, we need to add one\n            more level of indentation \n            -->\n            {% assign submenuIndentation = space | prepend: '    ' %}\n\n            {% capture my_toc %}{{ my_toc }}\n{{ submenuIndentation }}{:.{{ include.submenu_class | replace: '%level%', previousLevel }}}{% endcapture %}\n        {% endif %}\n\n        {% capture my_toc %}{{ my_toc }}\n{{ space }}{{ listModifier }} {{ listItemClass }} {{ list_item }}{% if include.anchor_class %}{:.{{ include.anchor_class }}}{% endif %}{% endcapture %}\n\n        {% assign previousLevel = indentAmount %}\n    {% endfor %}\n\n    {% if include.class and include.class != blank %}\n        {% capture my_toc %}{:.{{ include.class }}}\n{{ my_toc | lstrip }}{% endcapture %}\n    {% endif %}\n\n    {% if include.id %}\n        {% capture my_toc %}{: #{{ include.id }}}\n{{ my_toc | lstrip }}{% endcapture %}\n    {% endif %}\n\n    <!--\n    If we have a submenu class, we need to close off all the remaining list item groups so that submenu classes are\n    applied correctly to them\n    -->\n    {% if include.submenu_class != blank %}\n        <!-- The last level of indentation that we were at, we need to work backwards from there closing each group -->\n        {% for i in (1..previousLevel) %}\n            {% assign lvl = previousLevel | plus: 1 | minus: i %} <!-- Invert the indent level based on `i` -->\n            {% assign closingSpace = '' %}\n\n            {% for i in (1..lvl) %}\n                {% assign closingSpace = closingSpace | prepend: '    ' %}\n            {% endfor %}\n\n            {% capture my_toc %}{{ my_toc }}\n{{ closingSpace }}{:.{{ include.submenu_class | replace: '%level%', lvl }}}{% endcapture %}\n        {% endfor %}\n    {% endif %}\n{% endcapture %}{% assign tocWorkspace = '' %}{{ my_toc | markdownify | strip }}\n"
  },
  {
    "path": "docs/_layouts/default.html",
    "content": "---\nlayout: table_wrappers\n---\n\n<!DOCTYPE html>\n\n<html lang=\"{{ site.lang | default: 'en-US' }}\">\n{% include head.html %}\n<body>\n  <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none;\">\n    <symbol id=\"svg-link\" viewBox=\"0 0 24 24\">\n      <title>Link</title>\n      <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-link\">\n        <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"></path><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"></path>\n      </svg>\n    </symbol>\n    <symbol id=\"svg-search\" viewBox=\"0 0 24 24\">\n      <title>Search</title>\n      <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-search\">\n        <circle cx=\"11\" cy=\"11\" r=\"8\"></circle><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n      </svg>\n    </symbol>\n    <symbol id=\"svg-menu\" viewBox=\"0 0 24 24\">\n      <title>Menu</title>\n      <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-menu\">\n        <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line><line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n      </svg>\n    </symbol>\n    <symbol id=\"svg-arrow-right\" viewBox=\"0 0 24 24\">\n      <title>Expand</title>\n      <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-chevron-right\">\n        <polyline points=\"9 18 15 12 9 6\"></polyline>\n      </svg>\n    </symbol>\n    <symbol id=\"svg-doc\" viewBox=\"0 0 24 24\">\n      <title>Document</title>\n      <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-file\">\n        <path d=\"M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z\"></path><polyline points=\"13 2 13 9 20 9\"></polyline>\n      </svg>\n    </symbol>\n  </svg>\n\n  <div class=\"side-bar\">\n    <div class=\"site-header\">\n      <a href=\"{{ '/' | absolute_url }}\" class=\"site-title lh-tight\">{% include title.html %}</a>\n      <a href=\"#\" id=\"menu-button\" class=\"site-button\">\n        <svg viewBox=\"0 0 24 24\" class=\"icon\"><use xlink:href=\"#svg-menu\"></use></svg>\n        <!-- source: https://icons.getbootstrap.com/icons/x-lg/ -->\n        <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\">\n          <path d=\"M1.293 1.293a1 1 0 0 1 1.414 0L8 6.586l5.293-5.293a1 1 0 1 1 1.414 1.414L9.414 8l5.293 5.293a1 1 0 0 1-1.414 1.414L8 9.414l-5.293 5.293a1 1 0 0 1-1.414-1.414L6.586 8 1.293 2.707a1 1 0 0 1 0-1.414z\"/>\n        </svg>\n      </a>\n    </div>\n    <nav role=\"navigation\" aria-label=\"Main\" id=\"site-nav\" class=\"site-nav\">\n      {% if site.just_the_docs.collections %}\n        {% assign collections_size = site.just_the_docs.collections | size %}\n        {% for collection_entry in site.just_the_docs.collections %}\n          {% assign collection_key = collection_entry[0] %}\n          {% assign collection_value = collection_entry[1] %}\n          {% assign collection = site[collection_key] %}\n          {% if collection_value.nav_exclude != true %}\n            {% if collections_size > 1 %}\n              <div class=\"nav-category\">{{ collection_value.name }}</div>\n            {% endif %}\n            {% include nav.html pages=collection %}\n          {% endif %}\n        {% endfor %}\n      {% else %}\n        {% include nav.html pages=site.html_pages %}\n      {% endif %}\n    </nav>\n  </div>\n  <div class=\"main\">\n    <div id=\"home\"></div>\n    <div id=\"main-header\" class=\"main-header\">\n      {% if site.search_enabled != false %}\n        <div class=\"search\">\n          <div class=\"search-input-wrap\">\n            <input type=\"text\" id=\"search-input\" class=\"search-input\" tabindex=\"0\" placeholder=\"Search\" aria-label=\"Search\" autocomplete=\"off\">\n            <label for=\"search-input\" class=\"search-label\"><svg viewBox=\"0 0 24 24\" class=\"search-icon\"><use xlink:href=\"#svg-search\"></use></svg></label>\n          </div>\n          <div id=\"search-results\" class=\"search-results\"></div>\n        </div>\n      {% endif %}\n      {% include header_custom.html %}\n      {% if site.aux_links %}\n        <nav aria-label=\"Auxiliary\" class=\"aux-nav\">\n          <ul class=\"aux-nav-list\">\n            {% for link in site.aux_links %}\n              <li class=\"aux-nav-list-item\">\n                <a href=\"{{ link.last }}\" class=\"site-button\"\n                  {% if site.aux_links_new_tab %}\n                  target=\"_blank\" rel=\"noopener noreferrer\"\n                  {% endif %}\n                >\n                  {{ link.first }}\n                </a>\n              </li>\n            {% endfor %}\n          </ul>\n        </nav>\n      {% endif %}\n    </div>\n    <div id=\"main-content-wrap\" class=\"main-content-wrap\">\n      {% unless page.url == \"/\" %}\n        {% if page.parent %}\n          {%- for node in pages_list -%}\n            {%- if node.parent == nil -%}\n              {%- if page.parent == node.title or page.grand_parent == node.title -%}\n                {%- assign first_level_url = node.url | absolute_url -%}\n              {%- endif -%}\n              {%- if node.has_children -%}\n                {%- assign children_list = pages_list | where: \"parent\", node.title -%}\n                {%- for child in children_list -%}\n                  {%- if page.url == child.url or page.parent == child.title -%}\n                    {%- assign second_level_url = child.url | absolute_url -%}\n                  {%- endif -%}\n                {%- endfor -%}\n              {%- endif -%}\n            {%- endif -%}\n          {%- endfor -%}\n          <nav aria-label=\"Breadcrumb\" class=\"breadcrumb-nav\">\n            <ol class=\"breadcrumb-nav-list\">\n              {% if page.grand_parent %}\n                <li class=\"breadcrumb-nav-list-item\"><a href=\"{{ first_level_url }}\">{{ page.grand_parent }}</a></li>\n                <li class=\"breadcrumb-nav-list-item\"><a href=\"{{ second_level_url }}\">{{ page.parent }}</a></li>\n              {% else %}\n                <li class=\"breadcrumb-nav-list-item\"><a href=\"{{ first_level_url }}\">{{ page.parent }}</a></li>\n              {% endif %}\n              <li class=\"breadcrumb-nav-list-item\"><span>{{ page.title }}</span></li>\n            </ol>\n          </nav>\n        {% endif %}\n      {% endunless %}\n      <div id=\"main-content\" class=\"main-content\" role=\"main\">\n        {% if site.heading_anchors != false %}\n          {% include vendor/anchor_headings.html html=content beforeHeading=\"true\" anchorBody=\"<svg viewBox=\\\"0 0 16 16\\\" aria-hidden=\\\"true\\\"><use xlink:href=\\\"#svg-link\\\"></use></svg>\" anchorClass=\"anchor-heading\" anchorAttrs=\"aria-labelledby=\\\"%html_id%\\\"\" %}\n        {% else %}\n          {{ content }}\n        {% endif %}\n\n        {% if page.has_children == true and page.has_toc != false %}\n          <hr>\n          <h2 class=\"text-delta\">Table of contents</h2>\n          <ul>\n            {%- assign children_list = pages_list | where: \"parent\", page.title | where: \"grand_parent\", page.parent -%}\n            {% for child in children_list %}\n              <li>\n                <a href=\"{{ child.url | absolute_url }}\">{{ child.title }}</a>{% if child.summary %} - {{ child.summary }}{% endif %}\n              </li>\n            {% endfor %}\n          </ul>\n        {% endif %}\n\n        {% capture footer_custom %}\n          {%- include footer_custom.html -%}\n        {% endcapture %}\n        {% if footer_custom != \"\" or site.last_edit_timestamp or site.gh_edit_link %}\n          <hr>\n          <footer>\n            {% if site.back_to_top %}\n              <p><a href=\"#top\" id=\"back-to-top\">{{ site.back_to_top_text }}</a></p>\n            {% endif %}\n\n            {{ footer_custom }}\n\n            {% if site.last_edit_timestamp or site.gh_edit_link %}\n              <div class=\"d-flex mt-2\">\n                {% if site.last_edit_timestamp and site.last_edit_time_format and page.last_modified_date %}\n                  <p class=\"text-small text-grey-dk-000 mb-0 mr-2\">\n                    Page last modified: <span class=\"d-inline-block\">{{ page.last_modified_date | date: site.last_edit_time_format }}</span>.\n                  </p>\n                {% endif %}\n                {% if\n                  site.gh_edit_link and\n                  site.gh_edit_link_text and\n                  site.gh_edit_repository and\n                  site.gh_edit_branch and\n                  site.gh_edit_view_mode\n                %}\n                  <p class=\"text-small text-grey-dk-000 mb-0\">\n                    <a href=\"{{ site.gh_edit_repository }}/{{ site.gh_edit_view_mode }}/{{ site.gh_edit_branch }}{% if site.gh_edit_source %}/{{ site.gh_edit_source }}{% endif %}/{{ page.path }}\" id=\"edit-this-page\">{{ site.gh_edit_link_text }}</a>\n                  </p>\n                {% endif %}\n              </div>\n            {% endif %}\n          </footer>\n        {% endif %}\n\n      </div>\n    </div>\n\n    <footer class=\"site-footer\">\n      <p>\n        Enhanced ✨ with <a href=\"https://github.com/pmarsceill/just-the-docs\">Just the Docs</a>\n      </p>\n      <div class=\"up-arrow\">\n        <a href=\"#top\">↑</a>\n      </div>\n    </footer>\n\n    {% if site.search_enabled != false %}\n      {% if site.search.button %}\n        <a href=\"#\" id=\"search-button\" class=\"search-button\">\n          <svg viewBox=\"0 0 24 24\" class=\"icon\"><use xlink:href=\"#svg-search\"></use></svg>\n        </a>\n      {% endif %}\n\n      <div class=\"search-overlay\"></div>\n    {% endif %}\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "docs/_sass/custom/custom.scss",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// docs/_sass/custom/custom.scss\n//\n// Custom styles for Just the Docs.\n//\n// More info:\n//   https://pmarsceill.github.io/just-the-docs/docs/customization/\n///////////////////////////////////////////////////////////////////////////////\n\n///////////////////////////////////////////////////////////////////////////////\n// Colors\n\n/* #1a1a1a #1b1b1b #1e1f25 #4da6dc #65bcfb #6cb2b5 #222327 #232529 */\n\n$body-background-color:         #15181d;\n$body-color:                    #c5c7cf;\n$code-block-background-color:   #1c1f25;\n$code-inline-background-color:  #2a303b;\n$muted-color:                   #636363;\n$hr-color:                      lighten($body-background-color, 10%);\n$link-color:                    #5e8bd0;\n$side-bar-background-color:     #0f1217;\n\n///////////////////////////////////////////////////////////////////////////////\n// Styles\n\n::placeholder {\n  color:                    $muted-color;\n}\n\n::selection {\n  background-color:         #393f67;\n}\n\na,\na code {\n  color:                    $link-color !important;\n}\n\na:not([class]),\na:not([class]):hover {\n  background:               none;\n}\n\na:not([class]) {\n  text-decoration:          none;\n}\n\na:not([class]):hover {\n  text-decoration:          underline;\n}\n\nbody,\nhtml {\n  font-size:                16px !important;\n}\n\nbody {\n  background-color:         $body-background-color;\n  color:                    $body-color;\n  padding-bottom:           2rem;\n}\n\n// NOTE:\n//   `code.highlighter-rouge`:        inline code\n//   `code`, `div.highlighter-rouge`: code blocks\ncode {\n  border-radius:            6px;\n\n  &,\n  a &,\n  a:visited & {\n    border:                 1px solid #1b2027;\n    color:                  #cbcbd6;\n    font-family:            ui-monospace,\n                            SFMono-Regular,\n                            SF Mono,\n                            Menlo,\n                            Consolas,\n                            Liberation Mono,\n                            monospace;\n    font-size:              0.9rem;\n    line-height:            1.4;\n    padding:                0.2rem 0.4rem;\n\n    @media (min-width: 50rem) {\n      font-size:            0.85rem;\n    }\n  }\n\n  a & {\n    white-space:            nowrap;\n  }\n\n  a &,\n  a:visited &,\n  dl &,\n  h1 &,\n  sup &,\n  ul &,\n  &.highlighter-rouge {\n    background-color:       $code-inline-background-color;\n    border:                 0;\n    font-size:              0.85em;\n    vertical-align:         middle;\n  }\n\n  sup & {\n    font-size:              0.85em;\n  }\n\n  &.highlighter-rouge {\n    white-space:            nowrap;\n\n    h1 &, h2 &, h3 &, h4 &, h5 &, h6 &,\n    li & {\n      white-space:          normal;\n    }\n  }\n}\n\ncode.highlighter-rouge {\n  background-color:         $code-inline-background-color !important;\n  border:                   none;\n}\n\ndiv.highlighter-rouge {\n  // &,\n  // code,\n  // pre {\n  & {\n    background-color:       $code-block-background-color;\n    border:                 none;\n    padding:                1rem;\n\n    button {\n      // TODO\n      display:              none;\n    }\n  } // &, code, pre\n} // code, div.highlighter-rouge\n\ndiv.highlighter-rouge,\ndiv.listingblock {\n  div.highlight {\n    border:                 none;\n    padding:                0;\n  }\n}\n\nh1, h2, h3, h4, h5, h6 {\n  color:                    $body-color !important;\n}\n\nh1, h1 code {\n  font-size:                2rem        !important;\n}\n\nh2 {\n  font-size:                1.35rem     !important;\n}\n\nh3 {\n  font-size:                1.25rem     !important;\n}\n\nhr {\n  background-color:         $hr-color;\n}\n\ninput[type='text'] {\n  background-color:         $body-background-color;\n}\n\np {\n  margin-bottom:            1rem;\n  margin-top:               0;\n}\n\npre {\n  font-size:                1.2rem;\n  line-height:              1rem;\n}\n\nth,\nthead th,\ntd {\n  background-color:         transparent;\n  border-bottom:            1px solid lighten($body-background-color, 5%);\n  border-left:              1px solid lighten($body-background-color, 5%);\n  font-size:                0.95rem !important;\n}\n\nth {\n  padding:                  0.5rem 0 0.5rem 0.45rem;\n\n  @media (min-width: 50rem) {\n    padding-left:           0.75rem;\n  }\n}\n\n.aux-nav .aux-nav-list {\n  font-size:                0.95rem !important;\n\n  @media (max-width: 50rem) {\n    display:                block;\n    text-align:             center;\n  }\n\n  code {\n    background-color:       $code-block-background-color;\n  }\n}\n\n.highlight,\n.highlight pre,\npre.highlight {\n  background:               none;\n}\n\n.highlight {\n  .c  {\n    color:                  #7c7992;\n  }\n\n  .cp {\n    color:                  #008b99;\n  }\n\n  .gh {\n    color:                  #9ea6d0;\n  }\n\n  .gu {\n    color:                  #7178d4;\n  }\n\n  .k  {\n    color:                  #d6d3a9;\n  }\n\n  .na {\n    color:                  #af62ac;\n  }\n\n  .nb {\n    color:                  #a29eab;\n  }\n\n  .nl {\n    color:                  #a0e0bd;\n  }\n\n  .no {\n    color:                  #b8bd65;\n  }\n\n  .nt {\n    color:                  #89b1f3;\n  }\n\n  .nv {\n    color:                  #6590bf;\n  }\n\n  .o  {\n    color:                  $body-color;\n  }\n\n  .s  {\n    color:                  #66afa9;\n  }\n\n  .s2 {\n    color:                  #ada7e0;\n  }\n\n  .se {\n    color:                  #e281d7;\n  }\n\n  .sx {\n    color:                  #99b7b6;\n  }\n} // .highlight\n\n.main-content {\n  padding:                  1rem 2rem 0;\n\n  @media (min-width: 50rem) {\n    padding:                1rem 2.5rem 0;\n  }\n\n  a {\n    white-space:            normal;\n  }\n\n  dl {\n    display:                block;\n\n    dt {\n      font-size:            1rem;\n      font-style:           italic;\n      font-weight:          600;\n      margin-top:           1rem;\n      padding:              0;\n      text-align:           left;\n\n      &::after {\n        content:            \"\";\n      }\n\n      code {\n        font-weight:        bold;\n      }\n    }\n  }\n\n  h1 {\n    border-bottom:          1px solid $hr-color;\n    margin-bottom:          1rem;\n    padding-bottom:         1rem;\n  }\n\n  h1, h2, h3, h4, h5 {\n    font-weight:            bold;\n\n    code {\n      font-weight:          bold;\n      padding:              0.1rem 0.4rem;\n    }\n  }\n\n  h1, h2, h3, h4, h5, h6 {\n    padding-top:            1rem      !important;\n  }\n\n  h2, h3, h4, h5, h6 {\n    margin-bottom:          1rem      !important;\n  }\n\n  h2, h3, h4, h5, h6 {\n    margin-top:             -0.6rem;\n    text-transform:         none;\n  }\n\n  h2, h3 {\n    margin-top:             -1rem     !important;\n  }\n\n  h4 {\n    font-size:              1rem      !important;\n  }\n\n  h4,\n  h5,\n  h6 {\n    code {\n      font-size:            0.93em    !important;\n    }\n  }\n\n  h5,\n  h6,\n  .text-zeta {\n    font-size:              1rem      !important;\n  }\n\n  p:last-child {\n    display:                none;\n  }\n\n  p:nth-last-child(2),\n  p:nth-last-child(6) {\n    margin:                 2rem 0 1rem;\n  }\n\n  // override theme list styles\n  ul > li::before {\n    color:                  inherit;\n    content:                none;\n    margin-left:            inherit;\n    position:               inherit;\n  }\n\n  ul {\n    list-style-type:        disc;\n  }\n\n  .anchor-heading {\n    height:                 auto;\n    left:                   -1.25rem;\n    padding:                0;\n    vertical-align:         middle;\n    width:                  1rem;\n\n    svg {\n      color:                $link-color;\n    }\n  }\n\n  .highlighter-rouge {\n    margin-bottom:          1.15rem;\n  }\n}\n\n.main-content-wrap {\n  padding:                  0;\n}\n\n.main-header,\n.side-bar + .main .main-header {\n  background-color:         $body-background-color;\n  border:                   0;\n\n  @media (max-width: 50rem) {\n    background-color:       $body-background-color;\n  }\n}\n\n.nav-list {\n  @media (max-width: 50rem) {\n    text-align:             center;\n  }\n\n  .nav-list-item {\n    @media (max-width: 50rem) {\n      display:              inline-block;\n      font-size:            1rem    !important;\n    }\n\n    &:first-child .nav-list-link.active {\n      background:           0;\n      background-color:     $side-bar-background-color;\n\n      @media (max-width: 50rem) {\n        background-color:   $body-background-color;\n      }\n\n      &:hover {\n        background-color:   $body-background-color;\n      }\n    }\n\n    code,\n    &.nav-settings code {\n      padding:              0.1em 0.25em 0.17em;\n\n      @media (max-width: 50rem) {\n        padding:            0.1rem 0.3rem;\n      }\n    }\n\n    .nav-list-link {\n      @media only screen and (min-width: 50rem) {\n        line-height:        1rem    !important;\n        padding-left:       1.25rem !important;\n      }\n\n      @media (max-width: 50rem) {\n        display:            inline-block;\n        padding:            0.2rem;\n      }\n\n      line-height:          1.5rem  !important;\n      min-height:           auto;\n\n      &:hover,\n      &.active {\n        background:         0;\n        background-color:   $body-background-color;\n      }\n    }\n\n    .nav-separator {\n      color:                $muted-color;\n\n      @media (min-width: 50rem) {\n        display:            none;\n      }\n    }\n  }\n}\n\n.search-active .search-input,\n.search-input,\n.search-results,\n.search-result-previews {\n  background-color:         #1e1f25;\n  color:                    #c7c5ce;\n}\n\n.search-input:focus + .search-label .search-icon,\n.search-result-doc .search-result-icon {\n  color:                    lighten($body-color, 1%);\n}\n\n.search-input-wrap {\n  @media (max-width: 50rem) {\n    border-bottom:          1px solid lighten($body-background-color, 5%);\n    box-shadow:             0 3px 10px rgba(0, 0, 0, 0.08);\n  }\n}\n\n.search-result:hover,\n.search-result.active {\n  background:               none;\n  background-color:         #16181b;\n\n  & .search-result-previews {\n    background-color:       #16181b;\n  }\n}\n\n.search-result-doc.search-result-doc-parent {\n  display:                  none;\n}\n\n.search-result-previews {\n  border-left-color:        #3a3a3a;\n}\n\n.side-bar {\n  background-color:         $side-bar-background-color;\n  border:                   0;\n}\n\n.site-button {\n  &:hover {\n    background:             none;\n    background-color:       darken($body-background-color, 2%);\n    border-radius:          0 0 5px 5px;\n\n    @media (max-width: 50rem) {\n      background-color:     $body-background-color;\n    }\n  }\n\n  &,\n  .icon,\n  .bi-x-lg {\n    color:                  $body-color;\n  }\n\n  .bi-x-lg {\n    display:                none;\n  }\n\n  &.nav-open {\n    .icon {\n      display:              none;\n    }\n\n    .bi-x-lg {\n      display:              block;\n      margin-left:          0.2rem;\n    }\n  }\n\n  text-align:               center;\n}\n\n.site-footer {\n  font-size:                0.85rem     !important;\n  padding:                  0;\n  position:                 relative;\n  text-align:               center;\n  text-transform:           lowercase;\n  width:                    100%        !important;\n\n  p {\n    margin:                 0;\n  }\n\n\n  .up-arrow {\n    padding-top:            2rem;\n  }\n}\n\n.site-header {\n  border:                   0;\n\n  @media (max-width: 50rem) {\n    background-color:       $body-background-color;\n  }\n\n  @media (min-width: 50rem) {\n    display:                none;\n  }\n}\n\n.site-nav {\n  padding:                  0 1rem;\n\n  @media (max-width: 50rem) {\n    background-color:       $body-background-color;\n    margin-top:             -0.5rem;\n  }\n\n  @media (min-width: 50rem) {\n    padding:                0;\n    padding-top:            1rem;\n  }\n\n  code {\n    font-size:              0.8rem;\n    padding:                0;\n  }\n}\n\n.site-nav,\n.site-header,\n.site-footer {\n  @media (min-width: 66.5rem) {\n    width:                  14rem;\n  }\n}\n\n.site-title {\n  padding-left:             1.5rem;\n\n  @media (max-width: 50rem) {\n    display:                none;\n  }\n}\n\n.site-title:hover {\n  background:               0;\n  background-color:         darken($side-bar-background-color, 2%);\n}\n\n.table-wrapper {\n  box-shadow:               none;\n}\n\n#console,\n#desert,\n#electro,\n#forest,\n#nb-default,\n#ocean,\n#raspberry,\n#smoke,\n#unicorn,\n#utility {\n  margin-top:               -1rem;\n}\n"
  },
  {
    "path": "docs/assets/js/link-img-elements.js",
    "content": "(function linkImgElements($, window, document) {\n  $(document).ready(function() {\n    $('img').each(function() {\n      $(this).wrap(function() {\n        return '\\\n<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"' + $(this).attr('src') + '\"></a>';\n      })\n    })\n  });\n}(jQuery, window, document));\n"
  },
  {
    "path": "docs/assets/js/scroll-highlight.js",
    "content": "$(function() {\n  $(window).scroll(function() {\n    $(\"#home, h2, h3\").each(function() {\n      if ($(window).scrollTop() >= $(this).offset().top - 200) {\n        var id = $(this).attr('id');\n\n        if (id.indexOf(\"-import--export\") !== -1) {\n          id = '%EF%B8%8F-import--export';\n        }\n\n        if (id.indexOf(\"-set--settings\")  !== -1) {\n          id = '%EF%B8%8F-set--settings';\n        }\n\n        if (id.indexOf(\"-tasks\")          !== -1) {\n          id = '%EF%B8%8F-tasks';\n        }\n\n        if (\n            id.indexOf(\"nb-markdown-bookmark-file-format\")  !== -1 ||\n            id.indexOf(\"nb-markdown-todo-file-format\")      !== -1 ||\n            id.indexOf(\"nb-notebook-specification\")         !== -1\n        ) {\n          id = 'specifications';\n        }\n\n        $('.nav-list a').removeClass('active');\n        $('.nav-list a[href=\"#' + id + '\"]').addClass('active');\n      } else if($(window).scrollTop() + $(window).height() == $(document).height()) {\n        $('.nav-list a').removeClass('active');\n        $('.nav-list a[href=\"#tests\"').addClass('active');\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "docs/color-themes.md",
    "content": "# `nb` Color Themes\n\n`nb` includes several built-in color themes. The colors for built-in themes can be overridden with [`nb settings color_primary`](https://github.com/xwmx/nb#settings-list---long) and [`nb settings color_secondary`](https://github.com/xwmx/nb#settings-list---long).\n\n`nb` also supports user-defined themes. For more information, see [`nb settings color_theme`](https://github.com/xwmx/nb#settings-list---long).\n\n## Built-in Themes\n\n### `blacklight`\n\n| ![blacklight](https://xwmx.github.io/misc/nb/images/nb-theme-blacklight-home.png) | ![blacklight](https://xwmx.github.io/misc/nb/images/nb-theme-blacklight-web.png)  |\n|:--:|:--:|\n|    |    |\n\n##### `console`\n\n| ![console](https://xwmx.github.io/misc/nb/images/nb-theme-console-home.png)       | ![console](https://xwmx.github.io/misc/nb/images/nb-theme-console-web.png)        |\n|:--:|:--:|\n|    |    |\n\n##### `desert`\n\n| ![desert](https://xwmx.github.io/misc/nb/images/nb-theme-desert-home.png)         | ![desert](https://xwmx.github.io/misc/nb/images/nb-theme-desert-web.png)          |\n|:--:|:--:|\n|    |    |\n\n##### `electro`\n\n| ![electro](https://xwmx.github.io/misc/nb/images/nb-theme-electro-home.png)       | ![electro](https://xwmx.github.io/misc/nb/images/nb-theme-electro-web.png)        |\n|:--:|:--:|\n|    |    |\n\n##### `forest`\n\n| ![forest](https://xwmx.github.io/misc/nb/images/nb-theme-forest-home.png)         | ![forest](https://xwmx.github.io/misc/nb/images/nb-theme-forest-web.png)          |\n|:--:|:--:|\n|    |    |\n\n##### `nb` (default)\n\n| ![nb](https://xwmx.github.io/misc/nb/images/nb-theme-nb-home.png)                 | ![nb](https://xwmx.github.io/misc/nb/images/nb-theme-nb-web.png)                  |\n|:--:|:--:|\n|    |    |\n\n##### `ocean`\n\n| ![ocean](https://xwmx.github.io/misc/nb/images/nb-theme-ocean-home.png)           | ![ocean](https://xwmx.github.io/misc/nb/images/nb-theme-ocean-web.png)            |\n|:--:|:--:|\n|    |    |\n\n##### `raspberry`\n\n| ![raspberry](https://xwmx.github.io/misc/nb/images/nb-theme-raspberry-home.png)   | ![raspberry](https://xwmx.github.io/misc/nb/images/nb-theme-raspberry-web.png)    |\n|:--:|:--:|\n|    |    |\n\n##### `smoke`\n\n| ![smoke](https://xwmx.github.io/misc/nb/images/nb-theme-monochrome-home.png)      | ![smoke](https://xwmx.github.io/misc/nb/images/nb-theme-smoke-web.png)            |\n|:--:|:--:|\n|    |    |\n\n##### `unicorn`\n\n| ![unicorn](https://xwmx.github.io/misc/nb/images/nb-theme-unicorn-home.png)       | ![unicorn](https://xwmx.github.io/misc/nb/images/nb-theme-unicorn-web.png)        |\n|:--:|:--:|\n|    |    |\n\n##### `utility`\n\n| ![utility](https://xwmx.github.io/misc/nb/images/nb-theme-utility-home.png)       | ![utility](https://xwmx.github.io/misc/nb/images/nb-theme-utility-web.png)        |\n|:--:|:--:|\n|    |    |\n"
  },
  {
    "path": "docs/index.markdown",
    "content": "---\nlayout: home\ntitle: nb · command line and local web plain text note-taking, bookmarking, archiving, and knowledge base application\npermalink: /\n---\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <img  src=\"https://raw.githubusercontent.com/xwmx/nb/master/docs/assets/images/nb.png\"\n        alt=\"nb\"\n        width=\"200\">\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"https://github.com/xwmx/nb/actions\" rel=\"nofollow\">\n    <img  src=\"https://img.shields.io/github/actions/workflow/status/xwmx/nb/tests.yml?branch=master\"\n          alt=\"Build Status\"\n          style=\"max-width:100%;\">\n  </a>\n</div>\n\n<div align=\"center\">&nbsp;</div><!-- spacer -->\n<br/>\n\n`nb` is a command line and local web\nnote‑taking, bookmarking, archiving,\nand knowledge base application\nwith:\n\n- plain text data storage,\n- [encryption](#password-protected-encrypted-notes-and-bookmarks),\n- [filtering](#listing--filtering), [pinning](#-pinning), [#tagging](#-tagging), and [search](#-search),\n- [Git](https://git-scm.com/)-backed [versioning](#-revision-history) and [syncing](#-git-sync),\n- [Pandoc](https://pandoc.org/)-backed [conversion](#%EF%B8%8F-import--export),\n- <a href=\"#-linking\">[[wiki-style linking]]</a>,\n- terminal and GUI web [browsing](#-browsing),\n- inline [images](#-images),\n- [todos](#-todos) with [tasks](#%EF%B8%8F-tasks),\n- global and local [notebooks](#-notebooks),\n- organization with [folders](#-folders),\n- customizable [color themes](#-color-themes),\n- extensibility through [plugins](#-plugins),\n\nand more, in a single portable script.\n\n`nb` creates notes in text-based formats like\n[Markdown](https://en.wikipedia.org/wiki/Markdown),\n[Org](https://orgmode.org/),\n[LaTeX](https://www.latex-project.org/),\nand [AsciiDoc](https://asciidoc.org/),\ncan work with files in any format,\ncan import and export notes to many document formats,\nand can create private, password-protected encrypted notes and bookmarks.\nWith `nb`, you can write notes using\nVim,\nEmacs,\nVS Code,\nSublime Text,\nand any other text editor you like,\nas well as terminal and GUI web browsers.\n`nb` works in any standard Linux / Unix environment,\nincluding macOS and Windows via WSL, MSYS, and Cygwin.\n[Optional dependencies](#optional) can be installed to enhance functionality,\nbut `nb` works great without them.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-theme-nb-home.png\"\n        alt=\"home\"\n        width=\"450\">\n</div>\n\n`nb` is also a powerful [bookmarking](#-bookmarks) system featuring:\n\n- locally-served, text-centric, distraction-free bookmark [browsing](#-browsing)\n  in terminal and GUI web browsers,\n- local full-text search of cached page content with regular expression support,\n- convenient filtering and listing,\n- [Internet Archive Wayback Machine](https://archive.org/web/) snapshot lookup\n  for broken links,\n- tagging, pinning, linking, and full integration with other `nb` features.\n\nPage information is\ndownloaded,\ncleaned up,\nstructured,\nand saved\ninto normal Markdown documents made for humans,\nso bookmarks are easy to view and edit just like any other note.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/gui-terminal-browse.png\"\n        alt=\"nb browse\"\n        width=\"500\">\n</div>\n\n`nb` uses [Git](https://git-scm.com/) in the background to\nautomatically record changes and sync notebooks with remote repositories.\n`nb` can also be configured to\nsync notebooks using a general purpose syncing utility like Dropbox\nso notes can be edited in other apps on any device.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/terminal-empty.png\"\n        alt=\"nb list empty\"\n        width=\"450\">\n</div>\n\n`nb` is designed to be portable, future-focused, and vendor independent,\nproviding a full-featured and intuitive experience within\na highly composable multimodal user-centric text interface.\nThe entire program is contained within\na single [well-tested](#tests) shell script\nthat can be\ninstalled, copied, or `curl`ed almost anywhere and just work,\nusing a strategy inspired by\n[progressive enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement)\nfor various experience improvements in more capable environments.\n`nb` works great whether you have one notebook with just a few notes\nor dozens of notebooks containing thousands of notes, bookmarks, and other items.\n`nb` makes it easy to incorporate other tools, writing apps, and workflows.\n`nb` can be used a little, a lot, once in a while, or for just a subset of features.\n`nb` is flexible.\n\n<div align=\"center\">&nbsp;</div><!-- spacer -->\n\n<div align=\"center\">\n  <sub>\n  📝\n  🔖\n  🔍\n  🌍\n  🔒\n  ✅\n  🔄\n  🎨\n  📚\n  📌\n  📂\n  🌄\n  </sub>\n</div>\n\n<p align=\"center\">&nbsp;</p><!-- spacer -->\n\n<div align=\"center\">\n  <h1 align=\"center\" id=\"nb\"><code>nb</code></h1>\n</div>\n\n<div align=\"center\">\n  <a href=\"#installation\">Installation</a>&nbsp;·\n  <a href=\"#overview\">Overview</a>&nbsp;&nbsp;\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#-help\">Help</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#top\">&nbsp;↑&nbsp;</a>\n</div>\n\n### Installation\n\n#### Dependencies\n\n##### Required\n\n- [Bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell))\n  - `nb` works perfectly with Zsh, fish, and any other shell\n    set as your primary login shell,\n    the system just needs to have Bash available on it.\n- [Git](https://git-scm.com/)\n- A text editor with command line support, such as:\n  - [Vim](https://en.wikipedia.org/wiki/Vim_\\(text_editor\\)),\n  - [Emacs](https://en.wikipedia.org/wiki/Emacs),\n  - [Visual Studio Code](https://code.visualstudio.com/),\n  - [Sublime Text](https://www.sublimetext.com/),\n  - [Helix](https://helix-editor.com/),\n  - [micro](https://github.com/zyedidia/micro),\n  - [nano](https://en.wikipedia.org/wiki/GNU_nano),\n  - [Atom](https://atom.io/),\n  - [TextMate](https://macromates.com/),\n  - [MacDown](https://macdown.uranusjr.com/),\n  - [some of these](https://github.com/topics/text-editor),\n  - [and many of these.](https://en.wikipedia.org/wiki/List_of_text_editors)\n\n##### Optional\n\n`nb` leverages standard command line tools\nand works in standard Linux / Unix environments.\n`nb` also checks the environment for some additional optional tools and\nuses them to enhance the experience whenever they are available.\n\nRecommended:\n\n- [`bat`](https://github.com/sharkdp/bat)\n- [`ncat`](https://nmap.org/ncat/) or [`socat`](https://www.kali.org/tools/socat/)\n- [`pandoc`](https://pandoc.org/)\n- [`rg`](https://github.com/BurntSushi/ripgrep)\n- [`tig`](https://github.com/jonas/tig)\n- [`w3m`](https://en.wikipedia.org/wiki/W3m)\n\nAlso supported for various enhancements:\n\n[Ack](https://beyondgrep.com/),\n[`afplay`](https://ss64.com/osx/afplay.html),\n[`asciidoctor`](https://asciidoctor.org/),\n[The Silver Searcher (`ag`)](https://github.com/ggreer/the_silver_searcher),\n[`catimg`](https://github.com/posva/catimg),\n[Chafa](https://github.com/hpjansson/chafa),\n[Chromium](https://www.chromium.org) / [Chrome](https://www.google.com/chrome/),\n[`eza`](https://github.com/eza-community/eza),\n[`ffplay`](https://ffmpeg.org/ffplay.html),\n[ImageMagick](https://imagemagick.org/),\n[`glow`](https://github.com/charmbracelet/glow),\n[GnuPG](https://en.wikipedia.org/wiki/GNU_Privacy_Guard),\n[`highlight`](http://www.andre-simon.de/doku/highlight/en/highlight.php),\n[`imgcat`](https://www.iterm2.com/documentation-images.html),\n[`joshuto`](https://github.com/kamiyaa/joshuto),\n[kitty's `icat` kitten](https://sw.kovidgoyal.net/kitty/kittens/icat.html),\n[`lowdown`](https://kristaps.bsd.lv/lowdown),\n[`lsd`](https://github.com/lsd-rs/lsd),\n[Links](https://en.wikipedia.org/wiki/Links_(web_browser)),\n[Lynx](https://en.wikipedia.org/wiki/Lynx_(web_browser)),\n[`mdcat`](https://github.com/swsnr/mdcat),\n[`mdless`](https://github.com/ttscoff/mdless),\n[`mdv`](https://github.com/axiros/terminal_markdown_viewer),\n[Midnight Commander (`mc`)](https://en.wikipedia.org/wiki/Midnight_Commander),\n[`mpg123`](https://en.wikipedia.org/wiki/Mpg123),\n[MPlayer](https://en.wikipedia.org/wiki/MPlayer),\n[`ncat`](https://nmap.org/ncat/),\n[`netcat`](https://netcat.sourceforge.net/),\n[note-link-janitor](https://github.com/andymatuschak/note-link-janitor)\n(via [plugin](https://github.com/xwmx/nb/blob/master/plugins/backlink.nb-plugin)),\n[`pdftotext`](https://en.wikipedia.org/wiki/Pdftotext),\n[Pygments](https://pygments.org/),\n[Ranger](https://ranger.github.io/),\n[readability-cli](https://gitlab.com/gardenappl/readability-cli),\n[`rga` / ripgrep-all](https://github.com/phiresky/ripgrep-all),\n[`sc-im`](https://github.com/andmarti1424/sc-im),\n[`socat`](https://www.kali.org/tools/socat/),\n[`termvisage`](https://github.com/AnonymouX47/termvisage),\n[`termpdf.py`](https://github.com/dsanson/termpdf.py),\n[Tidy-Viewer (`tv`)](https://github.com/alexhallam/tv),\n[`timg`](https://github.com/hzeller/timg),\n[vifm](https://vifm.info/),\n[`viu`](https://github.com/atanunq/viu),\n[VisiData](https://www.visidata.org/)\n\n#### macOS / Homebrew\n\n```bash\nbrew install xwmx/taps/nb\n```\n\nInstalling `nb` with Homebrew also installs\nthe recommended dependencies above\nand completion scripts for Bash, Zsh, and Fish.\n\nInstall the latest development version from the repository with:\n\n```bash\nbrew install xwmx/taps/nb --head\n```\n\n`nb` is also available in\n[homebrew-core](https://github.com/Homebrew/homebrew-core).\nInstalling it together with the `bash` formula is recommended:\n\n```bash\nbrew install nb bash\n```\n\n#### Ubuntu, Windows, and others\n\n##### npm\n\n```bash\nnpm install -g nb.sh\n```\n\nAfter `npm` installation completes, run\n`sudo \"$(which nb)\" completions install`\nto install Bash and Zsh completion scripts (recommended).\n\nOn Ubuntu and WSL, you can\nrun [`sudo \"$(which nb)\" env install`](#env)\nto install the optional dependencies.\n\nWhen `nb` is installed on Windows,\n`socat` ([MSYS](https://packages.msys2.org/package/socat),\n[Cygwin](https://cygwin.com/packages/summary/socat.html)) is recommended.\n\n*`nb` is also available under its original package name,\n[notes.sh](https://www.npmjs.com/package/notes.sh),\nwhich comes with an extra `notes` executable wrapping `nb`.*\n\n##### Download and Install\n\nTo install as an administrator,\ncopy and paste one of the following multi-line commands:\n\n```bash\n# install using wget\nsudo wget https://raw.github.com/xwmx/nb/master/nb -O /usr/local/bin/nb &&\n  sudo chmod +x /usr/local/bin/nb &&\n  sudo nb completions install --download\n\n# install using curl\nsudo curl -L https://raw.github.com/xwmx/nb/master/nb -o /usr/local/bin/nb &&\n  sudo chmod +x /usr/local/bin/nb &&\n  sudo nb completions install --download\n```\n\nOn Ubuntu and WSL, you can\nrun [`sudo nb env install`](#env) to install the optional dependencies.\n\n###### User-only Installation\n\nTo install with just user permissions, simply\nadd the `nb` script to your `$PATH`.\nIf you already have a `~/bin` directory, for example, you can\nuse one of the following commands:\n\n```bash\n# download with wget\nwget https://raw.github.com/xwmx/nb/master/nb -O ~/bin/nb && chmod +x ~/bin/nb\n\n# download with curl\ncurl -L https://raw.github.com/xwmx/nb/master/nb -o ~/bin/nb && chmod +x ~/bin/nb\n```\n\nInstalling with just user permissions doesn't include\nthe optional dependencies or completions,\nbut `nb` core functionality works without them.\nIf you have `sudo` access and want\nto install the completion scripts and dependencies, run the following command:\n\n```bash\nsudo nb env install\n```\n\n##### Make\n\nTo install with [Make](https://en.wikipedia.org/wiki/Make_(software)),\nclone this repository, navigate to the clone's root directory, and run:\n\n```bash\nsudo make install\n```\n\nThis will also install the completion scripts on all systems and\nthe recommended dependencies on Ubuntu and WSL.\n\n##### bpkg\n\nTo install with [bpkg](https://github.com/bpkg/bpkg):\n\n```bash\nbpkg install xwmx/nb\n```\n\n##### basher\n\nTo install with [basher](https://www.basher.it/):\n\n```bash\nbasher install xwmx/nb\n```\n\n#### Tab Completion\n\nBash, Fish, and Zsh tab completion should be enabled\nwhen `nb` is installed using the methods above,\nassuming you have the appropriate system permissions or installed with `sudo`.\nIf completion isn't working after installing `nb`, see the\n[completion installation instructions](https://github.com/xwmx/nb/tree/master/etc).\n\n#### Updating\n\nWhen `nb` is installed using a package manager like npm or Homebrew,\nuse the package manager's upgrade functionality to update `nb` to\nthe latest version.\nWhen installed via other methods,\n`nb` can be updated to the latest version using\nthe [`nb update`](#update) subcommand.\n\n## Overview\n\n<div align=\"center\">\n  <a href=\"#-notes\"><code>📝</code>&nbsp;Notes</a>&nbsp;·\n  <a href=\"#adding\">Adding</a>&nbsp;·\n  <a href=\"#listing--filtering\">Listing</a>&nbsp;·\n  <a href=\"#editing\">Editing</a>&nbsp;·\n  <a href=\"#viewing\">Viewing</a>&nbsp;·\n  <a href=\"#deleting\">Deleting</a>&nbsp;·\n  <a href=\"#-bookmarks\"><code>🔖</code>&nbsp;Bookmarks</a>&nbsp;·\n  <a href=\"#-todos\"><code>✅</code>&nbsp;Todos</a>&nbsp;·\n  <a href=\"#%EF%B8%8F-tasks\"><code>✔️</code>&nbsp;Tasks</a>&nbsp;·\n  <a href=\"#-tagging\"><code>🏷</code>&nbsp;Tagging</a>&nbsp;·\n  <a href=\"#-linking\"><code>🔗</code>&nbsp;Linking</a>&nbsp;·\n  <a href=\"#-browsing\"><code>🌍</code>&nbsp;Browsing</a>&nbsp;·\n  <a href=\"#-images\"><code>🌄</code>&nbsp;Images</a>&nbsp;·\n  <a href=\"#-zettelkasten\"><code>🗂</code>&nbsp;Zettelkasten</a>&nbsp;·\n  <a href=\"#-folders\"><code>📂</code>&nbsp;Folders</a>&nbsp;·\n  <a href=\"#-pinning\"><code>📌</code>&nbsp;Pinning</a>&nbsp;·\n  <a href=\"#-search\"><code>🔍</code>&nbsp;Search</a>&nbsp;·\n  <a href=\"#-moving--renaming\"><code>↔</code>&nbsp;Moving&nbsp;&&nbsp;Renaming</a>&nbsp;·\n  <a href=\"#-revision-history\"><code>🗒</code>&nbsp;History</a>&nbsp;·\n  <a href=\"#-notebooks\"><code>📚</code>&nbsp;Notebooks</a>&nbsp;·\n  <a href=\"#-git-sync\"><code>🔄</code>&nbsp;Git&nbsp;Sync</a>&nbsp;·\n  <a href=\"#%EF%B8%8F-import--export\"><code>↕️</code>&nbsp;Import&nbsp;/&nbsp;Export</a>&nbsp;·\n  <a href=\"#%EF%B8%8F-set--settings\"><code>⚙️</code><code>set</code>&<code>settings</code></a>&nbsp;·\n  <a href=\"#-color-themes\"><code>🎨</code>&nbsp;Color&nbsp;Themes</a>&nbsp;·\n  <a href=\"#-plugins\"><code>🔌</code>&nbsp;Plugins</a>&nbsp;·\n  <a href=\"#-selectors\"><code>:/</code>&nbsp;Selectors</a>&nbsp;·\n  <a href=\"#01-metadata\"><code>01</code>&nbsp;Metadata</a>&nbsp;·\n  <a href=\"#-interactive-shell\"><code>❯</code>&nbsp;Shell</a>&nbsp;·\n  <a href=\"#shortcut-aliases\">Shortcuts</a>&nbsp;·\n  <a href=\"#-help\"><code>?</code>&nbsp;Help</a>&nbsp;·\n  <a href=\"#-variables\"><code>$</code>&nbsp;Variables</a>&nbsp;·\n  <a href=\"#specifications\">Specifications</a>&nbsp;·\n  <a href=\"#tests\">Tests</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#nb\">&nbsp;↑&nbsp;</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\nTo get started, simply run:\n\n```bash\nnb\n```\n\n`nb` sets up your initial `home` notebook the first time it runs.\n\nBy default, notebooks and notes are global (at `~/.nb`),\nso they are always available to `nb`\nregardless of the current working directory.\n`nb` also supports [local notebooks](#global-and-local-notebooks).\n\n### 📝 Notes\n\n#### Adding\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#add\"><code>nb add</code></a>,\n    <a href=\"#browse\"><code>nb browse add</code></a>\n  </sup>\n</p>\n\nUse [`nb add`](#add) (shortcuts: [`nb a`](#add), [`nb +`](#add))\nto create new notes:\n\n```bash\n# create a new note in your text editor\nnb add\n\n# create a new note with the filename \"example.md\"\nnb add example.md\n\n# create a new note containing \"This is a note.\"\nnb add \"This is a note.\"\n\n# create a new note with piped content\necho \"Note content.\" | nb add\n\n# create a new password-protected, encrypted note titled \"Secret Document\"\nnb add --title \"Secret Document\" --encrypt\n\n# create a new note in the notebook named \"example\"\nnb example:add \"This is a note.\"\n\n# create a new note in the folder named \"sample\"\nnb add sample/\n```\n\n[`nb add`](#add) with no arguments or input will open the new, blank note\nin your environment's preferred text editor.\nYou can change your editor using\nthe `$EDITOR` environment variable\nor [`nb set editor`](#editor).\n\n`nb` files are [Markdown](https://daringfireball.net/projects/markdown/)\nfiles by default. The default file type can be changed to\nwhatever you like\nusing [`nb set default_extension`](#default_extension).\n\n[`nb add`](#add) has intelligent argument parsing\nand behaves differently depending on the types of arguments it receives.\nWhen a filename with extension is specified,\na new note with that filename is opened in the editor:\n\n```bash\nnb add example.md\n```\n\nWhen a string is specified, a new note is immediately created\nwith that string as the content and without opening the editor:\n\n```bash\n❯ nb add \"This is a note.\"\nAdded: [1] 20200101000000.md\n```\n\n[`nb add <string>`](#add) is useful for quickly jotting down notes directly\nvia the command line. Quoting content is optional, but recommended.\n\nWhen no filename is specified, [`nb add`](#add) uses the current datetime as\nthe filename.\n\n[`nb add`](#add) can also receive piped content, which behaves the same as\n[`nb add <string>`](#add):\n\n```bash\n# create a new note containing \"Note content.\"\n❯ echo \"Note content.\" | nb add\nAdded: [6] 20200101000100.md\n\n# create a new note containing the clipboard contents on macOS\n❯ pbpaste | nb add\nAdded: [7] 20200101000200.md\n\n# create a new note containing the clipboard contents using xclip\n❯ xclip -o | nb add\nAdded: [8] 20200101000300.md\n```\n\nContent can be passed with the [`--content <content>`](#add) option,\nwhich also creates a new note without opening the editor:\n\n```bash\nnb add --content \"Note content.\"\n```\n\nWhen content is piped,\nspecified with [`--content <content>`](#add),\nor passed as a string argument,\nuse the [`--edit`](#add) flag to open the file in the editor\nbefore the change is committed.\n\nThe title, filename, and content can also be specified with long and\nshort options:\n\n```bash\n❯ nb add --filename \"example.md\" -t \"Example Title\" -c \"Example content.\"\nAdded: [9] example.md \"Example Title\"\n```\n\nThe [`-t <title>`](#add) / [`--title <title>`](#add) option also\nsets the filename to the title,\nlowercased with spaces and non-filename characters replaced with underscores:\n\n```bash\n❯ nb add --title \"Example Title\" \"Example content.\"\nAdded: [10] example_title.md \"Example Title\"\n```\n\nTags can be added with the [`--tags <tag1>,<tag2>...`](#add) option, which\ntakes a comma separated list of tags,\nconverts them to [#hashtags](#-tagging),\nand inserts them between the title and content:\n\n```bash\n❯ nb add \"Example content.\" --title \"Tagged Example\" --tags tag1,tag2\nAdded: [11] tagged_example.md \"Tagged Example\"\n\n❯ nb show 11 --print\n# Tagged Example\n\n#tag1 #tag2\n\nExample content.\n```\n\n[Search](#-search) for tagged items with\n[`nb search`](#search) / [`nb q`](#search):\n\n```bash\n# search for items tagged with \"#tag1\"\nnb search --tag tag1\n\n# search for items tagged with \"#tag1\" AND \"#tag2\", short options\nnb q -t tag1 -t tag2\n\n# search for items tagged with \"#tag1\" OR \"#tag2\", arguments\nnb q \\#tag1 --or \\#tag2\n```\n\nFiles can be created with any file type by specifying the extension either\nin the filename (`example.md`),\nthe extension by itself (`.md`),\nor via the [`--type <type>`](#add) option (`--type md`):\n\n```bash\n# open a new Org file in the editor\nnb add example.org\n\n# open a new reStructuredText file in the editor\nnb add --type rst\n\n# open a new JavaScript file in the editor\nnb add .js\n```\n\nCombining a type argument with piped clipboard content provides\na very convenient way to save code snippets using a clipboard utility such as\n`pbpaste`,\n`xclip`,\nor [`pb`](https://github.com/xwmx/pb):\n\n```bash\n# save the clipboard contents as a JavaScript file in the current notebook\npb | nb add .js\n\n# save the clipboard contents as a Rust file in the \"rust\" notebook\n# using the shortcut alias `nb a`\npb | nb a rust: .rs\n\n# save the clipboard contents as a Haskell file named \"example.hs\" in the\n# \"snippets\" notebook using the shortcut alias `nb +`\npb | nb + snippets: example.hs\n```\n\nUse [`nb show`](#show) and [`nb browse`](#browse) to view code snippets\nwith automatic syntax highlighting and\nuse [`nb edit`](#edit) to open in your editor.\n\nThe [`clip` plugin](#clip) can also be used to\ncreate notes from clipboard content.\n\nPiping,\n[`--title <title>`](#add),\n[`--tags <tag-list>`](#add),\n[`--content <content>`](#add),\nand content passed in an argument\ncan be combined as needed\nto create notes with content from multiple input methods and sources\nusing a single command:\n\n```bash\n❯ pb | nb add \"Argument content.\" \\\n    --title   \"Sample Title\"      \\\n    --tags    tag1,tag2           \\\n    --content \"Option content.\"\nAdded: [12] sample_title.md \"Sample Title\"\n\n❯ nb show 12 --print\n# Sample Title\n\n#tag1 #tag2\n\nArgument content.\n\nOption content.\n\nClipboard content.\n```\n\nFor a full list of options available for [`nb add`](#add), run\n[`nb help add`](#add).\n\n##### Password-Protected Encrypted Notes and Bookmarks\n\nPassword-protected notes and [bookmarks](#-bookmarks) are\ncreated with the [`-e`](#add) / [`--encrypt`](#add) flag and\nencrypted with AES-256 using OpenSSL by default.\nGPG is also supported and can be configured with\n[`nb set encryption_tool`](#encryption_tool).\n\nEach protected note and bookmark is\nencrypted individually with its own password.\nWhen an encrypted item is viewed, edited, or opened,\n`nb` will simply prompt for the item's password before proceeding.\nAfter an item is edited,\n`nb` automatically re-encrypts it and saves the new version.\n\nEncrypted notes can be decrypted\nusing the OpenSSL and GPG command line tools directly, so\nyou aren't dependent on `nb` to decrypt your files.\n\n##### Templates\n\nCreate a note based on a template by assigning a template string\nor path to a template file with [`add --template <template>`](#add):\n\n<!-- {% raw %} -->\n```bash\n# create a new note based on a template specified by path\nnb add --template /path/to/example/template\n\n# create a new note based on a template defined as a string\nnb add --template \"{{title}} • {{content}}\"\n```\n<!-- {% endraw %} -->\n\n`nb` template tags are enclosed in double curly brackets.\nSupported tags include:\n\n<dl>\n  <dt><code>&#x007B;{title}}</code></dt>\n  <dd>The note title, as specified with\n  <a href=\"#add\"><code>add --title &#60;title></code></a></dd>\n  <dt><code>&#x007B;&#x007B;tags}}</code></dt>\n  <dd>A list of hashtags, as specified with\n  <a href=\"#add\"><code>add --tags &#60;tag1>,&#60;tag2></code></a></dd>\n  <dt><code>&#x007B;{content}}</code></dt>\n  <dd>The note content, as specified with\n  <a href=\"#add\"><code>add &#60;content></code></a>,\n  <a href=\"#add\"><code>add --content &#60;content></code></a>,\n  and piped content.</dd>\n  <dt><code>&#x007B;{date}}</code></dt>\n  <dd>The ouput of the system's <code>date</code> command. Use the\n  <a href=\"https://man7.org/linux/man-pages/man1/date.1.html\"><code>date</code>\n  command options</a> to control formatting, e.g.,\n  <code>&#x007B;{date +\"%Y-%m-%d\"}}</code>.\n </dd>\n</dl>\n\nAn example complete markdown template could look like the following:\n\n<!-- {% raw %} -->\n```\n# {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n{{tags}}\n\n{{content}}\n```\n<!-- {% endraw %} -->\n\nTemplates are Bash strings processed with `eval`, so you can use\ncommand substitution (`$(echo \"Example command\")`) to include\nthe output from command line tools and shell code.\n\nA default template can be configured by assigning a string or path\nto the [`$NB_DEFAULT_TEMPLATE`](#nb_default_template) variable\nin your `~/.nbrc` file:\n\n<!-- {% raw %} -->\n```bash\n# set the default template to a path\nexport NB_DEFAULT_TEMPLATE=\"/path/to/example/template\"\n\n# set the default template with a string\nexport NB_DEFAULT_TEMPLATE=\"{{title}} • {{content}}\"\n```\n<!-- {% endraw %} -->\n\nUse [`nb add --no-template`](#add) to skip using a template when\none is assigned.\n\n##### Shortcut Aliases: `nb a`, `nb +`\n\n`nb` includes shortcuts for many commands, including\n[`nb a`](#add) and [`nb +`](#add) for [`nb add`](#add):\n\n```bash\n# create a new note in your text editor\nnb a\n\n# create a new note with the filename \"example.md\"\nnb a example.md\n\n# create a new note containing \"This is a note.\"\nnb + \"This is a note.\"\n\n# create a new note containing the clipboard contents with xclip\nxclip -o | nb +\n\n# create a new note in the notebook named \"example\"\nnb example:a\n```\n\n##### Other Aliases: `nb create`, `nb new`\n\n[`nb add`](#add) can also be invoked with\n[`nb create`](#add) and [`nb new`](#add) for convenience:\n\n```bash\n# create a new note containing \"Example note content.\"\nnb new \"Example note content.\"\n\n# create a new note with the title \"Example Note Title\"\nnb create --title \"Example Note Title\"\n```\n\n##### Adding with `nb browse`\n\nItems can also be added within terminal and GUI web browsers using\n[`nb browse add`](#browse) / [`nb b a`](#browse):\n\n```bash\n❯ nb browse add\n❯nb · home : +\n\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n\n[add]\n```\n\nPass a filename, relative path, and / or notebook name to\ncreate a new note at that location:\n\n```bash\n# open the add form in the browser to create the file \"file.md\" in the folder \"example\"\nnb browse add \"example/file.md\"\n```\n\n[`nb browse add`](#browse) includes options for quickly\npre-populating new notes with content:\n\n```bash\n❯ nb browse add --title \"Example Title\" --content \"Example content.\" --tags tag1,tag2\n❯nb · home : +\n\n[# Example Title                                      ]\n[                                                     ]\n[#tag1 #tag2                                          ]\n[                                                     ]\n[Example content.                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n[                                                     ]\n\n[add]\n```\n\n[`nb browse add`](#browse) can also be opened with\n[`nb add --browse`](#add) / [`nb a -b`](#add).\n\nFor more information, see [Browsing](#-browsing).\n\n#### Listing & Filtering\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#ls\"><code>nb ls</code></a>,\n    <a href=\"#list\"><code>nb list</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\nTo list notes and notebooks, run [`nb ls`](#ls) (shortcut alias: `nb`):\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-theme-utility-home.png\"\n        alt=\"nb ls\"\n        width=\"450\">\n</div>\n\nNotebooks are listed above the line,\nwith the current notebook highlighted and/or underlined,\ndepending on terminal capabilities.\n[`nb ls`](#ls) also includes a footer with example commands for easy reference.\nThe notebook header and command footer can be configured or hidden with\n[`nb set header`](#header) and\n[`nb set footer`](#footer).\n\n```bash\n❯ nb ls\nhome\n----\n[3] example.md · \"Example content.\"\n[2] sample.md · \"Sample content.\"\n[1] demo.md · \"- Demo list item one.\"\n```\n\nNotes from the current notebook are listed in the order they were last modified.\nBy default, each note is listed with its\nid, filename, and an excerpt from the first line of the note.\nWhen a note has a title, the title is displayed\ninstead of the filename and first line.\n\nMarkdown titles can be defined within a note using\n[either Markdown `h1` style](https://daringfireball.net/projects/markdown/syntax#header)\nor [YAML front matter](#front-matter):\n\n```markdown\n# Example Title\n```\n\n```markdown\nSample Title\n============\n```\n\n```markdown\n---\ntitle: Demo Title\n---\n```\n\n[Org](https://orgmode.org/),\n[LaTeX](https://www.latex-project.org/),\nand [AsciiDoc](https://asciidoc.org/)\ntitles are recognized in `.org`,`.latex`, and `.asciidoc` / `.adoc` files:\n\n```text\n#+title: Example Org Title\n```\n\n```latex\n\\title{Example LaTeX Title}\n```\n\n```asciidoc\n= Example AsciiDoc Title\n```\n\nOnce defined, titles are displayed in place of the filename and first line\nin the output of [`nb ls`](#ls):\n\n```bash\n❯ nb ls\nhome\n----\n[3] Example Title\n[2] Sample Title\n[1] Demo Title\n```\n\nPass an id, filename, or title to view the listing for that note:\n\n```bash\n❯ nb ls Sample\\ Title\n[2] Sample Title\n\n❯ nb ls 3\n[3] Example Title\n```\n\nIf there is no exact match, `nb` will list items with\ntitles and filenames that fuzzy match the query:\n\n```bash\n❯ nb ls exa\n[3] Example Title\n\n❯ nb ls ample\n[3] Example Title\n[2] Sample Title\n```\n\nMultiple words act like an `OR` filter, listing any\ntitles or filenames that match any of the words:\n\n```bash\n❯ nb ls example demo\n[3] Example Title\n[1] Demo Title\n```\n\nWhen multiple words are quoted, filter titles and filenames for that phrase:\n\n```bash\n❯ nb ls \"example title\"\n[3] Example Title\n```\n\nFor full text search, see [Search](#-search).\n\nTo view excerpts of notes, use the [`--excerpt`](#ls) or [`-e`](#ls) option,\nwhich optionally accepts a length:\n\n```bash\n❯ nb ls 3 --excerpt\n[3] Example Title\n-----------------\n# Example Title\n\nThis is an example excerpt.\n\n❯ nb ls 3 -e 8\n[3] Example Title\n-----------------\n# Example Title\n\nThis is an example excerpt.\n\nMore example content:\n\n- one\n- two\n```\n\nSeveral classes of file types are represented with emoji\n[indicators](#indicators) to make them easily identifiable in lists.\nFor example, bookmarks and encrypted notes are listed with `🔖` and `🔒`:\n\n```bash\n❯ nb ls\nhome\n----\n[4] Example Note\n[3] 🔒 encrypted-note.md.enc\n[2] 🔖 Example Bookmark (example.com)\n[1] 🔖 🔒 encrypted.bookmark.md.enc\n```\n\nFile types include:\n\n```text\n 🔉  Audio\n 📖  Book\n 🔖  Bookmark\n 🔒  Encrypted\n 📂  Folder\n 🌄  Image\n 📄  PDF, Word, or Open Office document\n 📹  Video\n```\n\nBy default, items are listed starting with the most recently modified.\nTo reverse the order, use the [`-r`](#ls) or [`--reverse`](#ls) flag:\n\n```bash\n❯ nb ls\nhome\n----\n[2] Todos\n[3] Example Title\n[1] Ideas\n\n❯ nb ls --reverse\n[1] Ideas\n[3] Example Title\n[2] Todos\n```\n\nNotes can be sorted with the [`-s`](#ls) / [`--sort`](#ls) flag,\nwhich can be combined with [`-r`](#ls) / [`--reverse`](#ls):\n\n```bash\n❯ nb ls\nhome\n----\n[2] Sample Title\n[3] Example Title\n[1] Demo Title\n\n❯ nb ls --sort\n[1] Demo Title\n[2] Sample Title\n[3] Example Title\n\n❯ nb ls --sort --reverse\n[3] Example Title\n[2] Sample Title\n[1] Demo Title\n```\n\n`nb` with no subcommand behaves like an alias for [`nb ls`](#ls),\nso the examples above can be run without the `ls`:\n\n```bash\n❯ nb\nhome\n----\n[2] Sample Title\n[3] Example Title\n[1] Demo Title\n\n❯ nb example\n[3] Example Title\n\n❯ nb 3 --excerpt\n[3] Example Title\n-----------------\n# Example Title\n\nThis is an example excerpt.\n\n❯ nb 3 -e 8\n[3] Example Title\n-----------------\n# Example Title\n\nThis is an example excerpt.\n\nMore example content:\n\n- one\n- two\n\n❯ nb --sort\n[1] Demo Title\n[2] Sample Title\n[3] Example Title\n\n❯ nb --sort --reverse\n[3] Example Title\n[2] Sample Title\n[1] Demo Title\n```\n\nShort options can be combined for brevity:\n\n```bash\n# equivalent to `nb --sort --reverse --excerpt 2` and `nb -s -r -e 2`:\n❯ nb -sre 2\n[3] Example Title\n-----------------\n# Example Title\n\n[2] Sample Title\n----------------\nSample Title\n============\n[1] Demo Title\n--------------\n---\ntitle: Demo Title\n```\n\n`nb` and [`nb ls`](#ls) display the 15 most recently modified items.\nThe default limit can be changed with [`nb set limit <number>`](#limit).\nTo list a different number of items on a per-command basis, use the\n[`-n <limit>`](#ls),\n[`--limit <limit>`](#ls),\n[`--<limit>`](#ls),\n[`-a`](#ls),\nand [`--all`](#ls)\nflags:\n\n```bash\n❯ nb -n 1\nhome\n----\n[5] Example Five\n4 omitted. 5 total.\n\n❯ nb --limit 2\nhome\n----\n[5] Example Five\n[4] Example Four\n3 omitted. 5 total.\n\n❯ nb --3\nhome\n----\n[5] Example Five\n[4] Example Four\n[3] Example Three\n2 omitted. 5 total.\n\n❯ nb --all\nhome\n----\n[5] Example Five\n[4] Example Four\n[3] Example Three\n[2] Example Two\n[1] Example One\n```\n\nLists can be paginated with\n[`-p <number>`](#ls) / [`--page <number>`](#ls),\nwhich paginates by the value of [`nb set limit`](#limit) by\ndefault, or the value of\n[`-n <limit>`](#ls),\n[`--limit <limit>`](#ls),\nor [`--<limit>`](#ls)\nwhen present:\n\n```bash\n❯ nb\nhome\n----\n[6] Example Six\n[5] Example Five\n[4] Example Four\n[3] Example Three\n[2] Example Two\n[1] Example One\n\n❯ nb set limit 3\nNB_LIMIT set to 3\n\n❯ nb --page 1\n[6] Example Six\n[5] Example Five\n[4] Example Four\n\n❯ nb -p 2\n[3] Example Three\n[2] Example Two\n[1] Example One\n\n❯ nb -p 2 --limit 2\n[4] Example Four\n[3] Example Three\n\n❯ nb -p 3 --2\n[2] Example Two\n[1] Example One\n```\n\nList [#tagged](#tagging) items by passing `\\#escaped` or `\"#quoted\"` hashtags\nor tags specified with the [`--tags`](#ls) option. Multiple tags perform an\n`AND` query:\n\n```bash\n# list items in the current notebook tagged with \"#tag1\", escaped\nnb \\#tag1\n\n# list items in the \"example\" notebook tagged with \"#tag2\", quoted\nnb example: \"#tag2\"\n\n# list items in all notebooks tagged with \"#tag1\", long option\nnb \\#tag1 --all\n\n# list items in the current notebook tagged with \"#tag1\" AND \"#tag2\"\nnb \\#tag1 \"#tag2\"\n\n# list items in all notebooks tagged with \"#tag2\" AND \"#tag3\", short option\nnb --tags tag2,tag3 -a\n```\n\n[`nb ls`](#ls) is a combination of\n[`nb notebooks`](#notebooks) and [`nb list`](#list)\nin one view and accepts the same arguments as [`nb list`](#list),\nwhich lists only notes without the notebook list and with no limit by default:\n\n```bash\n❯ nb list\n[100] Example One Hundred\n[99]  Example Ninety-Nine\n[98]  Example Ninety-Eight\n... lists all notes ...\n[2]   Example Two\n[1]   Example One\n```\n\nFor more information about options for listing notes, run\n[`nb help ls`](#ls)\nand\n[`nb help list`](#list).\n\n##### Listing with `browse`\n\nItems can be listed within terminal and GUI web browsers using\n[`nb browse`](#browse) / [`nb b`](#browse):\n\n```bash\n❯ nb browse example:sample/demo/\n❯nb · example : sample / demo / +\n\nsearch: [                    ]\n\n[example:sample/demo/7] Title Seven\n[example:sample/demo/6] Title Six\n[example:sample/demo/5] Title Five\n[example:sample/demo/4] Title Four\n[example:sample/demo/3] Title Three\n\nnext ❯\n```\n\nFor more information, see [Browsing](#-browsing).\n\n#### Editing\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#edit\"><code>nb edit</code></a>,\n    <a href=\"#browse\"><code>nb browse edit</code></a>\n  </sup>\n</p>\n\nYou can edit an item in your editor with\n[`nb edit`](#edit) (shortcut: [`nb e`](#edit)):\n\n```bash\n# edit note by id\nnb edit 3\n\n# edit note by filename\nnb edit example.md\n\n# edit note by title\nnb edit \"A Document Title\"\n\n# edit note 12 in the notebook named \"example\"\nnb edit example:12\n\n# edit note 12 in the notebook named \"example\", alternative\nnb example:12 edit\n\n# edit note 12 in the notebook named \"example\", alternative\nnb example:edit 12\n\n# edit the last modified item\nnb edit --last\n```\n\n[`edit`](#edit) and other subcommands that take an identifier\ncan be called with the identifier and subcommand name reversed:\n\n```bash\n# edit note by id\nnb 3 edit\n```\n\n[`nb edit`](#edit) can also receive piped content, which it\nappends to the specified note without opening the editor:\n\n```bash\necho \"Content to append.\" | nb edit 1\n```\n\nContent can be passed with the [`--content <content>`](#edit) option,\nwhich also appends the content without opening the editor:\n\n```bash\nnb edit 1 --content \"Content to append.\"\n```\n\nUse the [`--overwrite`](#edit) option to overwrite existing file content\nand the [`--prepend`](#edit) option to prepend the new content before existing content.\n\nWhen content is piped or specified with [`--content <content>`](#edit),\nuse the [`--edit`](#edit) flag to open the file in the editor\nbefore the change is committed.\n\nEdit the last modified item with [`--last`](#edit) / [`-l`](#edit):\n\n```bash\n# edit the last modified item\nnb edit --last\n\n# edit the last modified item, short option\nnb edit -l\n```\n\n##### Editing Encrypted Notes\n\nWhen a note is encrypted,\n[`nb edit`](#edit) prompts you for the note password,\nopens the unencrypted content in your editor,\nand then automatically reencrypts the note when you are done editing.\n\n##### Shortcut Alias: `nb e`\n\n[`nb edit`](#edit) can be called by the shortcut alias, [`nb e`](#edit):\n\n```bash\n# edit note by id\nnb e 3\n\n# edit note by filename\nnb e example.md\n\n# edit note by title\nnb e \"A Document Title\"\n\n# edit note by id, alternative\nnb 3 e\n\n# edit note 12 in the notebook named \"example\"\nnb e example:12\n\n# edit note 12 in the notebook named \"example\", alternative\nnb example:12 e\n\n# edit note 12 in the notebook named \"example\", alternative\nnb example:e 12\n\n# edit the last modified item, short option\nnb e -l\n```\n\nFor [`nb edit`](#edit) help information, run [`nb help edit`](#edit).\n\n##### Editing with `browse`\n\nItems can be edited within terminal and GUI web browsers using\n[`nb browse edit`](#browse) / [`nb b e`](#browse):\n\n```bash\n❯ nb browse edit text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · editing · - | +\n\n[# Daring Fireball: Markdown (daringfireball.net)         ]\n[                                                         ]\n[<https://daringfireball.net/projects/markdown/>          ]\n[                                                         ]\n[## Related                                               ]\n[                                                         ]\n[- <https://en.wikipedia.org/wiki/Markdown>               ]\n[                                                         ]\n[## Comments                                              ]\n[                                                         ]\n[See also:                                                ]\n[                                                         ]\n[- [[text:formats/org]]                                   ]\n[- [[cli:apps/nb]]                                        ]\n[                                                         ]\n[## Tags                                                  ]\n[                                                         ]\n\n[save] · last: 2021-01-01 01:00:00\n```\n\nFor more information, see\n[`browse edit`](#browse-edit) and [Browsing](#-browsing).\n\n#### Viewing\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#show\"><code>nb show</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>,\n    <a href=\"#open\"><code>nb open</code></a>,\n    <a href=\"#peek\"><code>nb peek</code></a>\n  </sup>\n</p>\n\nNotes and other items can be viewed using\n[`nb show`](#show) (shortcut: [`nb s`](#show)):\n\n```bash\n# show note by id\nnb show 3\n\n# show note by filename\nnb show example.md\n\n# show note by title\nnb show \"A Document Title\"\n\n# show note by id, alternative\nnb 3 show\n\n# show note 12 in the notebook named \"example\"\nnb show example:12\n\n# show note 12 in the notebook named \"example\", alternative\nnb example:12 show\n\n# show note 12 in the notebook named \"example\", alternative\nnb example:show 12\n```\n\nBy default, [`nb show`](#show) opens notes in\n[`less`](https://linux.die.net/man/1/less),\nwith syntax highlighting if\n[`bat`](https://github.com/sharkdp/bat),\n[`highlight`](http://www.andre-simon.de/doku/highlight/en/highlight.php),\nor\n[Pygments](https://pygments.org/)\nis installed.\nYou can navigate in `less` using the following keys:\n\n```text\nKey               Function\n---               --------\nmouse scroll      Scroll up or down\narrow up or down  Scroll one line up or down\nf                 Jump forward one window\nb                 Jump back one window\nd                 Jump down one half window\nu                 Jump up one half window\n/<query>          Search for <query>\nn                 Jump to next <query> match\nq                 Quit\n```\n\n*If `less` scrolling isn't working in [iTerm2](https://www.iterm2.com/),\ngo to*\n\"Settings\"\n-> \"Advanced\"\n-> \"Scroll wheel sends arrow keys when in alternate screen mode\"\n*and change it to* \"Yes\".\n*[More Info](https://stackoverflow.com/a/37610820)*\n\nUse the [`-p`](#show) / [`--print`](#show) option\nto print to standard output with syntax highlighting:\n\n```bash\n❯ nb show 123 --print\n# Example Title\n\nExample content:\n\n- one\n- two\n- three\n```\n\nUse [`nb show --print --no-color`](#show) to print without syntax highlighting.\n\nWhen [Pandoc](https://pandoc.org/) is available,\nuse the [`-r`](#show) / [`--render`](#show) option to\nrender the note to HTML and open it in your terminal browser:\n\n```bash\nnb show example.md --render\n# opens example.md as an HTML page in w3m, links, or lynx\n```\n\n[`nb show`](#show) also supports previewing other file types in the terminal,\ndepending on the tools available in the environment. To prefer specific tools\nfor certain file types, `nb` provides configuration variables that can be\nset in your `~/.nbrc` file,\nwhich can be opened in your editor with [`nb settings edit`](#settings).\n\nSupported file types and tools include:\n\n- Markdown files ([`$NB_MARKDOWN_TOOL`](#nb_markdown_tool)):\n  - [`bat`](https://github.com/sharkdp/bat)\n  - [`glow`](https://github.com/charmbracelet/glow)\n  - [`lowdown`](https://kristaps.bsd.lv/lowdown)\n  - [`mdcat`](https://github.com/swsnr/mdcat)\n  - [`mdless`](https://github.com/ttscoff/mdless)\n  - [`mdv`](https://github.com/axiros/terminal_markdown_viewer)\n- PDF files:\n  - [`termpdf.py`](https://github.com/dsanson/termpdf.py)\n    with [kitty](https://sw.kovidgoyal.net/kitty/)\n  - [`pdftotext`](https://en.wikipedia.org/wiki/Pdftotext)\n- Audio files ([`$NB_AUDIO_TOOL`](#nb_audio_tool)):\n  - [`mplayer`](https://en.wikipedia.org/wiki/MPlayer)\n  - [`afplay`](https://ss64.com/osx/afplay.html)\n  - [`mpg123`](https://en.wikipedia.org/wiki/Mpg123)\n  - [`ffplay`](https://ffmpeg.org/ffplay.html)\n- [Images](#-images) ([`$NB_IMAGE_TOOL`](#nb_image_tool)):\n  - [`catimg`](https://github.com/posva/catimg)\n  - [Chafa](https://github.com/hpjansson/chafa)\n  - [ImageMagick](https://imagemagick.org/) with a terminal that\n    supports [sixels](https://en.wikipedia.org/wiki/Sixel)\n  - [`imgcat`](https://www.iterm2.com/documentation-images.html) with\n    [iTerm2](https://www.iterm2.com/)\n  - [kitty's `icat` kitten](https://sw.kovidgoyal.net/kitty/kittens/icat.html)\n  - [`termvisage`](https://github.com/AnonymouX47/termvisage)\n  - [`timg`](https://github.com/hzeller/timg)\n  - [`viu`](https://github.com/atanunq/viu)\n- Folders, Directories, Notebooks ([`$NB_DIRECTORY_TOOL`](#nb_directory_tool)):\n  - [`eza`](https://github.com/eza-community/eza)\n  - [`joshuto`](https://github.com/kamiyaa/joshuto)\n  - [`lsd`](https://github.com/lsd-rs/lsd)\n  - [Midnight Commander (`mc`)](https://en.wikipedia.org/wiki/Midnight_Commander)\n  - [`ranger`](https://ranger.github.io/)\n  - [`vifm`](https://vifm.info/)\n- Word Documents:\n  - [Pandoc](https://pandoc.org/) with\n    [`w3m`](https://en.wikipedia.org/wiki/W3m) or\n    [`links`](https://en.wikipedia.org/wiki/Links_(web_browser))\n- Excel, CSV, TSV, and data files ([`$NB_DATA_TOOL`](#nb_data_tool)):\n  - [VisiData](https://www.visidata.org/)\n  - [`sc-im`](https://github.com/andmarti1424/sc-im)\n  - [Tidy-Viewer (`tv`)](https://github.com/alexhallam/tv)\n- EPUB ebooks:\n  - [Pandoc](https://pandoc.org/) with\n    [`w3m`](https://en.wikipedia.org/wiki/W3m) or\n    [`links`](https://en.wikipedia.org/wiki/Links_(web_browser))\n\nWhen using [`nb show`](#show) with other file types or\nif the above tools are not available,\n[`nb show`](#show) opens files in\nyour system's preferred application for each type.\n\n[`nb show`](#show) also provides [options](#show) for\nquerying information about an item. For example, use the\n[`--added`](#show) / [`-a`](#show) and [`--updated`](#show) / [`-u`](#show)\nflags to print the date and time that an item was added or updated:\n\n```bash\n❯ nb show 2 --added\n2020-01-01 01:01:00 -0700\n\n❯ nb show 2 --updated\n2020-02-02 02:02:00 -0700\n```\n\n[`nb show`](#show) is primarily intended for viewing items within the terminal.\nTo view a file in the system's preferred GUI application, use\n[`nb open`](#open).\nTo [browse](#-browsing) rendered items in terminal and GUI web browsers, use\n[`nb browse`](#browse).\n\nFor full [`nb show`](#show) usage information, run [`nb help show`](#show).\n\n##### Shortcut Alias: `nb s`\n\n[`nb show`](#show) can be called using the shortcut alias [`nb s`](#show):\n\n```bash\n# show note by id\nnb s 3\n\n# show note by filename\nnb s example.md\n\n# show note by title\nnb s \"A Document Title\"\n\n# show note by id, alternative\nnb 3 s\n\n# show note 12 in the notebook named \"example\"\nnb s example:12\n\n# show note 12 in the notebook named \"example\", alternative\nnb example:12 s\n\n# show note 12 in the notebook named \"example\", alternative\nnb example:s 12\n```\n\n##### Alias: `nb view`\n\n[`nb show`](#show) can also be invoked with [`nb view`](#show) for convenience:\n\n```bash\n# show note by id\nnb view 3\n\n# show note by filename\nnb view example.md\n\n# show note by title\nnb view \"A Document Title\"\n\n# show note by id, alternative\nnb 3 view\n```\n\n##### Viewing with `browse`\n\nItems can be viewed within terminal and GUI web browsers using\n[`nb browse`](#browse) / [`nb b`](#browse):\n\n```bash\n❯ nb browse text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · edit | +\nDaring Fireball: Markdown (daringfireball.net)\n\nhttps://daringfireball.net/projects/markdown/\n\nRelated\n\n  • https://en.wikipedia.org/wiki/Markdown\n\nComments\n\nSee also:\n\n  • [[text:formats/org]]\n  • [[cli:apps/nb]]\n\nTags\n\n#markup #plain-text\n\nContent\n\nDaring Fireball: Markdown\n\nDownload\n\nMarkdown 1.0.1 (18 KB) — 17 Dec 2004\n\nIntroduction\n\nMarkdown is a text-to-HTML conversion tool for web writers. Markdown allows\nyou to write using an easy-to-read, easy-to-write plain text format, then\nconvert it to structurally valid XHTML (or HTML).\n```\n\nFor more information, see [Browsing](#-browsing).\n\n#### Deleting\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#delete\"><code>nb delete</code></a>,\n    <a href=\"#browse\"><code>nb browse delete</code></a>\n  </sup>\n</p>\n\nTo delete one or more notes, pass any number of\nids, filenames, titles, and other [selectors](#-selectors)\nto [`nb delete`](#delete) (shortcuts: [`nb d`](#delete), [`nb -`](#delete)):\n\n```bash\n# delete item by id\nnb delete 3\n\n# delete item by filename\nnb delete example.md\n\n# delete item by title\nnb delete \"A Document Title\"\n\n# delete item by id, alternative\nnb 3 delete\n\n# delete item 12 in the notebook named \"example\"\nnb delete example:12\n\n# delete item 12 in the notebook named \"example\", alternative\nnb example:12 delete\n\n# delete item 12 in the notebook named \"example\", alternative\nnb example:delete 12\n\n# delete item 345 in the folder named \"example\"\nnb delete example/345\n\n# delete items with the ids 89, 56, and 21\nnb delete 89 56 21\n```\n\nBy default, [`nb delete`](#delete) will display a confirmation prompt.\nTo skip, use the [`--force`](#delete) / [`-f`](#delete) option:\n\n```bash\nnb delete 3 --force\n```\n\n##### Shortcut Aliases: `nb d`, `nb -`\n\n[`nb delete`](#delete) has the aliases [`nb d`](#delete) and [`nb -`](#delete):\n\n```bash\n# delete note by id\nnb d 3\n\n# delete note by filename\nnb d example.md\n\n# delete note by title\nnb - \"A Document Title\"\n\n# delete note by id, alternative\nnb 3 d\n\n# delete note 12 in the notebook named \"example\"\nnb - example:12\n\n# delete note 12 in the notebook named \"example\", alternative\nnb example:12 d\n\n# delete note 12 in the notebook named \"example\", alternative\nnb example:d 12\n```\n\nFor [`nb delete`](#delete) help information, run [`nb help delete`](#delete).\n\n##### Deleting with `nb browse`\n\nItems can be deleted within terminal and GUI web browsers using\n[`nb browse delete`](#browse) / [`nb b d`](#browse):\n\n```bash\n❯ nb browse delete example:4\n❯nb · example : 4 · ↓ · edit · - | +\n\n              deleting\n\n[4] example_file.md \"Example Title\"\n\n              [delete]\n\n```\n\nFor more information, see [Browsing](#-browsing).\n\n### 🔖 Bookmarks\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#nb-help\"><code>nb&nbsp;&lt;url&gt;</code></a>,\n    <a href=\"#browse\"><code>nb&nbsp;browse</code></a>,\n    <a href=\"#bookmark\"><code>nb&nbsp;bookmark</code></a>,\n    <a href=\"#open\"><code>nb&nbsp;open</code></a>,\n    <a href=\"#peek\"><code>nb&nbsp;peek</code></a>,\n    <a href=\"#show\"><code>nb&nbsp;show</code></a>\n  </sup>\n</p>\n\n`nb` includes a bookmarking system to conveniently\ncreate, annotate, view, search, [browse](#-browsing), and manage\ncollections of bookmarks.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-bookmarks-gui-gui-terminal.png\"\n        alt=\"nb bookmarks\"\n        width=\"450\">\n</div>\n\nBookmarks in `nb` are stored as\n[simple structured Markdown files](#nb-markdown-bookmark-file-format)\ncontaining information extracted from the bookmarked pages.\n\nTo create a new bookmark, pass a URL as the first argument to `nb`:\n\n```bash\nnb https://example.com\n```\n\n`nb` automatically generates a bookmark using information from the page:\n\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\n`nb` embeds the page content in the bookmark, making it available for\n[full text search](#-search) with [`nb search`](#search) and\nlocally-served, distraction-free [reading and browsing](#-browsing)\nwith [`nb browse`](#browse).\nWhen [Pandoc](https://pandoc.org/) is installed,\nthe HTML page content is converted to Markdown.\nWhen [readability-cli](https://gitlab.com/gardenappl/readability-cli)\nis installed, markup is cleaned up to focus on content. When\n[Chromium](https://www.chromium.org) or\n[Chrome](https://www.google.com/chrome/) is installed on the system,\n`nb` automatically renders JavaScript-dependent pages\nand saves the resulting markup.\n\nMany shells automatically escape special characters in URLs. If a\nURL contains characters that are preventing it from being saved in full,\nURLs can also be enclosed in quotes when passed to `nb`:\n\n```bash\nnb \"https://example.com#sample-anchor\"\n```\n\nIn addition to caching the page content,\nyou can also include a quote from the page in a\n[`## Quote`](#-quote) section\nusing the\n[`-q <quote>`](#bookmark) / [`--quote <quote>`](#bookmark) option:\n\n```bash\nnb https://example.com --quote \"Example quote line one.\n\nExample quote line two.\"\n```\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Quote\n\n> Example quote line one.\n>\n> Example quote line two.\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\nAdd a comment in a [`## Comment`](#-comment) section using the\n[`-c <comment>`](#bookmark) / [`--comment <comment>`](#bookmark) option:\n\n```bash\nnb https://example.com --comment \"Example comment.\"\n```\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Comment\n\nExample comment.\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\nAdd related URLs and [linked](#-linking) [selectors](#-selectors)\nto a [`## Related`](#-related) section using the\n[`-r (<url> | <selector>)`](#bookmark) /\n[`--related (<url> | <selector>)`](#bookmark)\noption:\n\n```bash\nnb https://example.com --related example:123 -r https://example.net\n```\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Related\n\n- [[example:123]]\n- <https://example.net>\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\nBookmarks can be tagged using the\n[`-t <tag1>,<tag2>...`](#bookmark) /\n[`--tags <tag1>,<tag2>...`](#bookmark) option.\nTags are converted into [#hashtags](#-tagging) and\nadded to a [`## Tags`](#-tags) section:\n\n```bash\nnb https://example.com --tags tag1,tag2\n```\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\n[Search](#-search) for tagged bookmarks with\n[`nb search`](#search) / [`nb q`](#search):\n\n```bash\nnb search --tag tag1\n\nnb q -t tag1\n\nnb q \\#tag1\n```\n\n[`nb search`](#search) / [`nb q`](#search)\nautomatically searches archived page content:\n\n```bash\n❯ nb q \"example query\"\n[10] 🔖 example.bookmark.md \"Example Bookmark (example.com)\"\n------------------------------------------------------------\n5:Lorem ipsum example query.\n```\n\nBookmarks can also be encrypted:\n\n```bash\n# create a new password-protected, encrypted bookmark\nnb https://example.com --encrypt\n```\n\nEncrypted bookmarks require a password before they can be viewed or\nopened.\n\nMultiple URLs can be bookmarked with a single command by passing\nmultiple [`<url>`](#bookmark) arguments. Additional arguments will be reused\nfor each bookmark:\n\n```bash\n❯ nb https://example.com https://example.net --tags tag1,tag2 --filename example\nAdded: [1] 🔖 example.bookmark.md \"Example Domain (example.com)\"\nAdded: [2] 🔖 example-1.bookmark.md \"Example Domain (example.net)\"\n```\n\n#### Listing and Filtering Bookmarks\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-bookmarks-gui-terminal-terminal.png\"\n        alt=\"nb bookmark lists\"\n        width=\"500\">\n</div>\n\nBookmarks are included in\n`nb`,\n[`nb ls`](#ls),\n[`nb list`](#list),\nand [`nb browse`](#browse)\nalong with items of other types.\n[`nb bookmark`](#bookmark) and [`nb bookmark list`](#bookmark) can be used to\nlist and filter only bookmarks:\n\n```bash\n❯ nb bookmark\nAdd: nb <url> Help: nb help bookmark\n------------------------------------\n[3] 🔖 🔒 example.bookmark.md.enc\n[2] 🔖 Bookmark Two (example.com)\n[1] 🔖 Bookmark One (example.com)\n\n❯ nb bookmark list two\n[2] 🔖 Bookmark Two (example.com)\n```\n\nBookmarks are also included in `nb`, [`nb ls`](#ls), and [`nb list`](#list):\n\n```bash\n❯ nb\nhome\n----\n[7] 🔖 Bookmark Three (example.com)\n[6] Example Note\n[5] 🔖 Bookmark Two (example.net)\n[4] Sample Note\n[3] 🔖 🔒 example-encrypted.bookmark.md.enc\n[2] Demo Note\n[1] 🔖 Bookmark One (example.com)\n```\n\nUse the [`--type <type>`](#ls) / [`--<type>`](#ls)\noption as a filter to display only bookmarks:\n\n```bash\n❯ nb --type bookmark\n[7] 🔖 Bookmark Three (example.com)\n[5] 🔖 Bookmark Two (example.net)\n[3] 🔖 🔒 example-encrypted.bookmark.md.enc\n[1] 🔖 Bookmark One (example.com)\n\n❯ nb --bookmark\n[7] 🔖 Bookmark Three (example.com)\n[5] 🔖 Bookmark Two (example.net)\n[3] 🔖 🔒 example-encrypted.bookmark.md.enc\n[1] 🔖 Bookmark One (example.com)\n```\n\n`nb` saves the domain in the title, making it easy to filter by domain\nusing any list subcommands:\n\n```bash\n❯ nb example.com\n[7] 🔖 Bookmark Three (example.com)\n[1] 🔖 Bookmark One (example.com)\n```\n\nFor more listing options, see\n[`nb help ls`](#ls),\n[`nb help list`](#list),\nand [`nb help bookmark`](#bookmark).\n\n##### Shortcut Aliases: `nb bk`, `nb bm`\n\n[`nb bookmark`](#bookmark) can also be used with the aliases\n[`nb bk`](#bookmark) and [`nb bm`](#bookmark):\n\n```bash\n❯ nb bk\nAdd: nb <url> Help: nb help bookmark\n------------------------------------\n[7] 🔖 Bookmark Three (example.com)\n[5] 🔖 Bookmark Two (example.net)\n[3] 🔖 🔒 example-encrypted.bookmark.md.enc\n[1] 🔖 Bookmark One (example.com)\n\n❯ nb bm example.net\n[5] 🔖 Bookmark Two (example.net)\n```\n\n#### Viewing Bookmarks\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#browse\"><code>nb&nbsp;browse</code></a>,\n    <a href=\"#open\"><code>nb&nbsp;open</code></a>,\n    <a href=\"#peek\"><code>nb&nbsp;peek</code></a>,\n    <a href=\"#show\"><code>nb&nbsp;show</code></a>\n  </sup>\n</p>\n\n`nb` provides multiple ways to view bookmark files, bookmarked content,\nand bookmarked URLs.\n\nUse [`nb browse`](#browse) (shortcut: [`nb b`](#browse))\nto [browse](#-browsing) bookmarks with cached content,\n<a href=\"#-linking\">[[wiki-style links]]</a>,\nlinked [#tags](#-tagging), and external links:\n\n```bash\n❯ nb browse text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · edit | +\nDaring Fireball: Markdown (daringfireball.net)\n\nhttps://daringfireball.net/projects/markdown/\n\nRelated\n\n  • https://en.wikipedia.org/wiki/Markdown\n\nComments\n\nSee also:\n\n  • [[text:formats/org]]\n  • [[cli:apps/nb]]\n\nTags\n\n#markup #plain-text\n\nContent\n\nDaring Fireball: Markdown\n\nDownload\n\nMarkdown 1.0.1 (18 KB) — 17 Dec 2004\n\nIntroduction\n\nMarkdown is a text-to-HTML conversion tool for web writers. Markdown allows\nyou to write using an easy-to-read, easy-to-write plain text format, then\nconvert it to structurally valid XHTML (or HTML).\n```\n\nFor more information, see [Browsing](#-browsing).\n\n[`nb open`](#open) (shortcut: [`nb o`](#open)) opens the bookmarked URL in\nyour system's primary web browser:\n\n```bash\n# open bookmark by id\nnb open 3\n\n# open bookmark 12 in the notebook named \"example\"\nnb open example:12\n\n# open bookmark 12 in the notebook named \"example\", alternative\nnb example:12 open\n\n# open bookmark 12 in the notebook named \"example\", alternative\nnb example:open 12\n```\n\n*N.B. To use [`nb open`](#open) with\n[WSL](https://docs.microsoft.com/en-us/windows/wsl/install),\ninstall [wslu](https://github.com/wslutilities/wslu).*\n\n[`nb peek`](#peek) (shortcut: [`nb p`](#peek), alias: [`nb preview`](#peek))\nopens the bookmarked URL in your terminal web browser,\nsuch as\n[w3m](https://en.wikipedia.org/wiki/W3m),\n[Links](https://en.wikipedia.org/wiki/Links_(web_browser)), or\n[Lynx](https://en.wikipedia.org/wiki/Lynx_(web_browser)):\n\n```bash\n# peek bookmark by id\nnb peek 3\n\n# peek bookmark 12 in the notebook named \"example\"\nnb peek example:12\n\n# peek bookmark 12 in the notebook named \"example\", alternative\nnb example:12 peek\n\n# peek bookmark 12 in the notebook named \"example\", alternative\nnb example:peek 12\n```\n\n[`nb open`](#open) and [`nb peek`](#peek)\nwork seamlessly with encrypted bookmarks.\n`nb` simply prompts you for the bookmark's password.\n\n[`nb open`](#open) and [`nb peek`](#peek)\nautomatically check whether the URL is still valid.\nIf the page has been removed, `nb` can check\nthe [Internet Archive Wayback Machine](https://archive.org/web/)\nfor an archived copy.\n\nThe preferred terminal web browser can be set using\nthe `$BROWSER` environment variable,\nassigned in `~/.bashrc`, `~/.zshrc`, or similar:\n\n```bash\nexport BROWSER=lynx\n```\n\nWhen `$BROWSER` is not set, `nb` looks for\n[`w3m`](https://en.wikipedia.org/wiki/W3m),\n[`links`](https://en.wikipedia.org/wiki/Links_(web_browser)), and\n[`lynx`](https://en.wikipedia.org/wiki/Lynx_(web_browser))\nand uses the first one it finds.\n\n`$BROWSER` can also be used to easy specify the terminal browser for\nan individual command:\n\n```bash\n❯ BROWSER=links nb 12 peek\n# opens the URL from bookmark 12 in links\n\n❯ BROWSER=w3m nb 12 peek\n# opens the URL from bookmark 12 in w3m\n```\n\n[`nb show`](#show) and [`nb edit`](#edit)\ncan also be used to view and edit bookmark files,\nwhich include the cached page converted to Markdown.\n\n[`nb show <id> --render`](#show) / [`nb show <id> -r`](#show)\ndisplays the bookmark file converted to HTML in the terminal web browser,\nincluding all bookmark fields and the cached page content,\nproviding a cleaned-up, distraction-free, locally-served view of\nthe page content along with all of your notes.\n\n##### Shortcut Aliases: `nb o` and `nb p`\n\n[`nb open`](#open) and [`nb peek`](#peek)\ncan also be used with the shortcut aliases\n[`nb o`](#open) and [`nb p`](#peek):\n\n```bash\n# open bookmark by id\nnb o 3\n\n# open bookmark 12 in the notebook named \"example\"\nnb o example:12\n\n# open bookmark 12 in the notebook named \"example\", alternative\nnb example:12 o\n\n# peek bookmark by id\nnb p 3\n\n# peek bookmark 12 in the notebook named \"example\"\nnb p example:12\n\n# peek bookmark 12 in the notebook named \"example\", alternative\nnb example:12 p\n```\n\n#### Bookmark File Format\n\nBookmarks are identified by a `.bookmark.md` file extension.\nThe bookmark URL is the first URL in the file within `<` and `>` characters.\nTo create a minimally valid bookmark file with [`nb add`](#add):\n\n```bash\nnb add example.bookmark.md --content \"<https://example.com>\"\n```\n\nFor a full overview, see\n[`nb` Markdown Bookmark File Format](#nb-markdown-bookmark-file-format).\n\n#### `bookmark` -- A command line tool for managing bookmarks.\n\n`nb` includes [`bookmark`](#bookmark-help), a full-featured\ncommand line interface for creating, viewing, searching, and editing bookmarks.\n\n[`bookmark`](#bookmark-help) is a shortcut for the\n[`nb bookmark`](#bookmark) subcommand,\naccepting all of the same subcommands and options with identical behavior.\n\nBookmark a page:\n\n```bash\n❯ bookmark https://example.com --tags tag1,tag2\nAdded: [3] 🔖 20200101000000.bookmark.md \"Example Title (example.com)\"\n```\nList and filter bookmarks with\n[`bookmark`](#bookmark) and [`bookmark list`](#bookmark):\n\n```bash\n❯ bookmark\nAdd: bookmark <url> Help: bookmark help\n---------------------------------------\n[3] 🔖 🔒 example.bookmark.md.enc\n[2] 🔖 Example Two (example.com)\n[1] 🔖 Example One (example.com)\n\n❯ bookmark list two\n[2] 🔖 Example Two (example.com)\n```\n\nView a bookmark in your terminal web browser:\n\n```bash\nbookmark peek 2\n```\n\nOpen a bookmark in your system's primary web browser:\n\n```bash\nbookmark open 2\n```\n\nPerform a full text search of bookmarks and archived page content:\n\n```bash\n❯ bookmark search \"example query\"\n[10] 🔖 example.bookmark.md \"Example Bookmark (example.com)\"\n------------------------------------------------------------\n5:Lorem ipsum example query.\n```\n\nSee [`bookmark help`](#bookmark-help) for more information.\n\n### ✅ Todos\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#do\"><code>nb do</code></a>,\n    <a href=\"#tasks\"><code>nb tasks</code></a>,\n    <a href=\"#todo\"><code>nb todo</code></a>,\n    <a href=\"#undo\"><code>nb undo</code></a>\n  </sup>\n</p>\n\nUse [`nb todo`](#todo) (shortcut: [`nb to`](#todo))\nto create, list, and update todos.\n`nb` todos are [structured Markdown documents](#nb-markdown-todo-file-format)\nreferencing a single primary todo,\nwith optional [tasks](#%EF%B8%8F-tasks).\n\nUse [`nb todo add`](#todo) to create a new todo:\n\n```bash\n# create a new todo titled \"Example todo one.\"\n❯ nb todo add \"Example todo one.\"\nAdded: [1] ✔️ [ ] Example todo one.\n\n❯ nb show 1 --print\n# [ ] Example todo one.\n```\n\nUse the [`--due <date>`](#todo) option to add an optional due date in a\n[`## Due`](#-due) section:\n\n```bash\n# create a new todo titled \"Example todo two.\" with a due date of \"2100-01-01\"\n❯ nb todo add \"Example todo two.\" --due \"2100-01-01\"\nAdded: [2] ✔️ [ ] Example todo two.\n\n❯ nb show 2 --print\n# [ ] Example todo two.\n\n## Due\n\n2100-01-01\n```\n\nAdd an optional [description](#-description-1) with the\n[`--description <description>`](#todo)\noption:\n\n```bash\n❯ nb todo add \"Example todo three.\" --description \"Example description.\"\nAdded: [3] ✔️ [ ] Example todo three.\n\n❯ nb show 3 --print\n# [ ] Example todo three.\n\n## Description\n\nExample description.\n```\n\nTodos can have [tasks](#%EF%B8%8F-tasks).\nTasks added with one or more [`--task <task>`](#todo) options\nare represented as a markdown task list and placed in a\n[`## Tasks`](#-tasks) section:\n\n```bash\n❯ nb todo add \"Example todo seven.\" --task \"Task one.\" --task \"Task two.\" --task \"Task three.\"\nAdded: [7] ✔️ [ ] Example todo seven.\n\n❯ nb show 7 --print\n# [ ] Example todo seven.\n\n## Tasks\n\n- [ ] Task one.\n- [ ] Task two.\n- [ ] Task three.\n```\n\nRelated URLs and [linked](#-linking) [selectors](#-selectors)\ncan be added to a [`## Related`](#-related-1) field using the\n[`-r (<url> | <selector>)`](#todo) / [`--related (<url> | <selector>)`](#todo)\noption:\n\n```bash\n❯ nb todo add \"Example todo four.\" --related example:123 -r https://example.com\nAdded: [4] ✔️ [ ] Example todo four.\n\n❯ nb show 4 --print\n# [ ] Example todo four.\n\n## Related\n\n- [[example:123]]\n- <https://example.com>\n```\n\n[Tags](#-tagging) can be added to todos with the\n[`--tags <tag1>,<tag2>...`](#todo) option:\n\n```bash\n❯ nb todo add \"Example todo five.\" --tags tag1,tag2\nAdded: [5] ✔️ [ ] Example todo five.\n\n❯ nb show 5 --print\n# [ ] Example todo five.\n\n## Tags\n\n#tag1 #tag2\n```\n\n[Tags](#-tagging), [links](#-linking), and URLs can be\n[browsed](#-browsing)\nin terminal and GUI web browsers with [`nb browse`](#browse).\n\n#### Listing Todos\n\nList todos in with [`nb todos`](#todo):\n\n```bash\n# list todos in the current notebook\n❯ nb todos\n[6] ✔️ [ ] Example todo six.\n[5] ✅ [x] Example todo five.\n[4] ✔️ [ ] Example todo four.\n[3] ✅ [x] Example todo three.\n[2] ✅ [x] Example todo two.\n[1] ✔️ [ ] Example todo one.\n\n# list todos in the notebook named \"sample\"\n❯ nb todos sample:\n[sample:4] ✅ [x] Sample todo four.\n[sample:3] ✔️ [ ] Sample todo three.\n[sample:2] ✔️ [ ] Sample todo two.\n[sample:1] ✅ [x] Sample todo one.\n\n```\n\nOpen / undone todos can be listed with [`nb todos open`](#todo):\n\n```bash\n# list open todos in the current notebook\n❯ nb todos open\n[6] ✔️ [ ] Example todo six.\n[4] ✔️ [ ] Example todo four.\n[1] ✔️ [ ] Example todo one.\n\n# list open todos in the notebook named \"sample\"\n❯ nb tasks open sample:\n[sample:3] ✔️ [ ] Sample todo three.\n[sample:2] ✔️ [ ] Sample todo two.\n```\n\nClosed / done todos can be listed with [`nb todos closed`](#todo):\n\n```bash\n# list closed todos in the current notebook\n❯ nb todos closed\n[5] ✅ [x] Example todo five.\n[3] ✅ [x] Example todo three.\n[2] ✅ [x] Example todo two.\n\n# list closed todos in the notebook named \"sample\"\n❯ nb tasks closed sample:\n[sample:4] ✅ [x] Sample todo four.\n[sample:1] ✅ [x] Sample todo one.\n```\n\nSee\n[`nb help todo`](#todo)\nfor more information.\n\n#### `do` / `undo`\n\nMark a todo as done or closed with [`nb do`](#do):\n\n```bash\n# add a new todo titled \"Example todo six.\"\n❯ nb todo add \"Example todo six.\"\nAdded: [6] ✔️ [ ] Example todo six.\n\n# mark todo 6 as done / closed\n❯ nb do 6\nDone: [6] ✅ [x] Example todo six.\n```\n\nRe-open a closed todo with [`nb undo`](#undo):\n\n```bash\n# mark todo 6 as undone / open\n❯ nb undo 6\nUndone: [6] ✔️ [ ] Example todo six.\n```\n\nSee\n[`nb help do`](#do)\nand\n[`nb help undo`](#undo)\nfor more information.\n\n### ✔️ Tasks\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#do\"><code>nb do</code></a>,\n    <a href=\"#tasks\"><code>nb tasks</code></a>,\n    <a href=\"#todo\"><code>nb todo</code></a>,\n    <a href=\"#undo\"><code>nb undo</code></a>\n  </sup>\n</p>\n\n`nb` can list and update tasks in [todos](#-todos) and other Markdown documents.\n\nTasks are defined as one or more Markdown list items starting with\n`- [ ]` to indicate an open task or `- [x]` to indicate a done / closed task:\n\n```markdown\n- [ ] Example open task.\n- [x] Example closed task.\n```\n\nList tasks in items, folders, and notebooks with\n[`nb tasks`](#tasks) (shortcut: [`nb t`](#tasks)),\nwhich lists both tasks and todos:\n\n```bash\n# list tasks in item 7\n❯ nb tasks 7\n[7] ✔️ [ ] Example todo seven.\n------------------------------\n[7 1] [x] Task one.\n[7 2] [x] Task two.\n[7 3] [ ] Task three.\n\n# list tasks and todos in the notebook named \"example\"\n❯ nb tasks example:\n[example:9] ✔️ [ ] Example todo nine.\n[example:8] ✅ [x] Example todo eight.\n--------------------------------------\n[example:8 1] [x] Task one.\n[example:8 2] [x] Task two.\n\n[example:6] ✔️ [ ] Example todo six.\n[example:4] Example Note Title\n------------------------------\n[example:4 1] [ ] Task one.\n[example:4 2] [x] Task two.\n[example:4 3] [ ] Task three.\n\n[example:3] ✔️ [ ] Example todo three.\n```\n\nOpen / undone tasks can be listed with [`nb tasks open`](#tasks):\n\n```bash\n# list open tasks in item 7\n❯ nb tasks open 7\n[7] ✔️ [ ] Example todo seven.\n------------------------------\n[7 3] [ ] Task three.\n\n# list open tasks and todos in the notebook named \"example\"\n❯ nb tasks open example:\n[example:9] ✔️ [ ] Example todo nine.\n[example:6] ✔️ [ ] Example todo six.\n[example:4] Example Note Title\n------------------------------\n[example:4 1] [ ] Task one.\n[example:4 3] [ ] Task three.\n\n[example:3] ✔️ [ ] Example todo three.\n```\n\nClosed / done tasks can be listed with [`nb tasks closed`](#tasks):\n\n```bash\n# list closed tasks in item 7\n❯ nb tasks closed 7\n[7] ✔️ [ ] Example todo seven.\n------------------------------\n[7 1] [x] Task one.\n[7 2] [x] Task two.\n\n# list closed tasks and todos in the notebook named \"example\"\n❯ nb tasks closed example:\n[example:8] ✅ [x] Example todo eight.\n--------------------------------------\n[example:8 1] [x] Task one.\n[example:8 2] [x] Task two.\n\n[example:4] Example Note Title\n------------------------------\n[example:4 2] [x] Task two.\n```\n\nTasks are identified by the item [selector](#-selectors), followed by\na space, then followed by the sequential number of the task in the file.\n\nUse [`nb do`](#do) to mark tasks as done / closed:\n\n```bash\n# list tasks in item 9\n❯ nb tasks 9\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\n[9 1] [ ] Task one.\n[9 2] [ ] Task two.\n[9 3] [ ] Task three.\n\n# mark task 2 in item 9 as done / closed\n❯ nb do 9 2\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\nDone: [9 2] [x] Task two.\n\n# list tasks in item 9\n❯ nb tasks 9\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\n[9 1] [ ] Task one.\n[9 2] [x] Task two.\n[9 3] [ ] Task three.\n```\n\nUndo a done / closed task with [`nb undo`](#undo):\n\n```bash\n# mark task 2 in item 9 as undone / open\n❯ nb undo 9 2\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\nUndone: [9 2] [ ] Task two.\n\n# list tasks in item 9\n❯ nb tasks 9\n[9] ✔️ [ ] Example todo nine.\n-----------------------------\n[9 1] [ ] Task one.\n[9 2] [ ] Task two.\n[9 3] [ ] Task three.\n```\n\nSee\n[`nb help tasks`](#tasks)\nfor more information.\n\n### 🏷 #tagging\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#add\"><code>nb add</code></a>,\n    <a href=\"#bookmark\"><code>nb bookmark</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>,\n    <a href=\"#list\"><code>nb list</code></a>,\n    <a href=\"#ls\"><code>nb ls</code></a>,\n    <a href=\"#search\"><code>nb search</code></a>\n  </sup>\n</p>\n\nTagging is a flexible and powerful way to organize, filter, and discover your\nnotes, bookmarks, and todos in `nb`.\n\nTags in `nb` are written as `#hashtags`\nand can be placed anywhere within a document. A hashtag is defined as a `#`\ncharacter followed by any number of letters, numbers, underscores, or dashes,\nallowing you to create custom categories or keywords tailored to your workflow.\n\nTagging lets you group related items, quickly search for topics, set up ad hoc\ncollections, and create multi-dimensional taxonomies that complement notebooks\nand folders.\n\nTags can be added when creating or editing items, or embedded\ndirectly in your note content.\n\n#### Nested Tagging\n\nIn addition to standard hashtags, `nb` supports hierarchical tags using\nslashes, such as `#project/design/ui`. This enables an organizational structure\nwhere tags can represent parent-child relationships. For example, tagging a\nnote with `#topic/subtopic/detail` lets you group related notes at different\nlevels of specificity.\n\nWhen searching for tags, nested tags are matched by prefix:\n- Searching for `#project` matches notes tagged with `#project`,\n  `#project/design`, and `#project/design/ui`.\n- Searching for `#project/design` matches `#project/design` and any deeper\n  descendants like `#project/design/ui`.\n- Searching for an exact nested tag like `#project/design/ui` matches only\n  that tag.\n- Searching for a branch that doesn't exist, such as `#project/ui` when only\n  `#project/design/ui` exists, will match nothing.\n\nThis makes it easy to filter, organize, and browse notes and bookmarks using\neither broad or specific tag queries.\n\n#### Adding Tags\n\nNotes and bookmarks can be tagged when they are created using the\n`--tags <tag1>,<tag2>...` option,\nwhich is available with\n[`nb add`](#add),\n[`nb <url>`](#nb-help),\n[`nb browse add`](#browse),\n[`nb bookmark`](#bookmark),\nand\n[`nb todo`](#todo).\n`--tags` takes a comma-separated list of tags, converts them to\n`#hashtags`,\nand adds them to the document.\n\nTags added to notes with [`nb add --tags`](#add) are placed between the title\nand body text:\n\n```bash\n❯ nb add --title \"Example Title\" \"Example note content.\" --tags tag1,tag2\n```\n\n```markdown\n# Example Title\n\n#tag1 #tag2\n\nExample note content.\n```\n\nTags added to [bookmarks](#bookmarks) with\n[`nb <url> --tags`](#nb-help) and [`nb bookmark <url> --tags`](#bookmark)\nare placed in a [`## Tags`](#-tags) section:\n\n```bash\n❯ nb https://example.com --tags tag1,tag2\n```\n\n```markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n```\n\nTags added to [todos](#-todos) with\n[`nb todo add --tags`](#todo)\nare placed in a [`## Tags`](#-tags-1) section:\n\n```bash\n❯ nb todo add --tags tag1,tag2 \"Example todo.\"\n```\n\n```markdown\n# [ ] Example todo.\n\n## Tags\n\n#tag1 #tag2\n```\n\n#### Listing and Searching Tags\n\nUse [`nb --tags`](#nb-help), [`nb ls --tags`](#ls),\nand [`nb list --tags`](#list)\nto list the tags present in a notebook, folder, or item:\n\n```bash\n# list all tags found in items in the current notebook\nnb --tags\n\n# list all tags found in the folder named \"example\"\nnb example/ --tags\n\n# list all tags in the item with id 123 in the notebook named \"sample\"\nnb sample:123 --tags\n```\n\nList tagged items by passing `\\#escaped` or `\"#quoted\"` hashtags or tags\nspecified with the [`--tags`](#ls) option to [`nb`](#ls) / [`nb ls`](#ls):\n\n```bash\n# list items in the current notebook tagged with \"#tag1\", escaped\nnb \\#tag1\n\n# list items in the \"example\" notebook tagged with \"#tag2\", quoted\nnb example: \"#tag2\"\n\n# list items in all notebooks tagged with \"#tag3\", long option\nnb --tags tag3 --all\n\n# list items in all notebooks tagged with \"#tag3\", short option\nnb --tags tag3 -a\n```\n\nCombine multiple tags to search for items containing all specified tags:\n\n```bash\n# list items in the current notebook tagged with \"#tag1\" AND \"#tag2\"\nnb \\#tag1 \"#tag2\"\n\n# list items in the current notebook tagged with \"#tag2\" AND \"#tag3\"\nnb --tags tag2,tag3\n\n# list items in all notebooks tagged with \"#tag1\" AND \"#tag2\" AND \"#tag3\" AND \"#tag4\"\nnb \\#tag1 \"#tag2\" --tags tag3,tag4 --all\n```\n\nTagged items can be [searched](#-search) with\n[`nb search`](#search) / [`nb q`](#search):\n\n```bash\n# search for items tagged with \"#tag1\"\nnb search --tag tag1\n\n# search for items tagged with \"#tag1\", shortcut and short option\nnb q -t tag1\n\n# search for items tagged with \"#tag1\", shortcut and argument\nnb q \\#tag1\n\n# search for items tagged with \"#tag1\", shortcut and argument, alternative\nnb q \"#tag1\"\n\n# search for items tagged with \"#tag1\" AND \"#tag2\"\nnb q --tag tag1 --tag tag2\n\n# search for items tagged with \"#tag1\" AND \"#tag2\", short options\nnb q -t tag1 -t tag2\n\n# search for items tagged with \"#tag1\" AND \"#tag2\", arguments\nnb q \\#tag1 \\#tag2\n\n# search for items tagged with \"#tag1\" AND \"#tag2\", tag list\nnb q --tags tag1,tag2\n\n# search for items tagged with either \"#tag1\" OR \"#tag2\", options\nnb q -t tag1 --or -t tag2\n\n# search for items tagged with either \"#tag1\" OR \"#tag2\", arguments\nnb q \\#tag1 --or \\#tag2\n\n# search for items tagged with either \"#tag1\" OR \"#tag2\", single argument\nnb q \"#tag1|#tag2\"\n\n# search for items tagged with \"#tag1\" AND \"#tag2\" AND \"#tag3\"\nnb q -t tag1 --tags tag2,tag3\n\n# search for items tagged with \"#tag1\" OR \"#tag2\" OR \"#tag3\"\nnb q -t tag1 --or --tags tag2,tag3\n\n# search for items tagged with \"#tag1\" OR \"#tag2\" OR \"#tag3\"\nnb q \\#tag1 --or -t tag2 --or \"#tag3\"\n```\n\n#### Browsing Tags\n\nLinked tags can be [browsed](#-browsing) with [`nb browse`](#browse),\nproviding another dimension of browsability in terminal and GUI web browsers,\ncomplimenting <a href=\"#-linking\">[[wiki-style linking]]</a>.\n\nTags in notes,\nbookmarks,\nfiles in text-based formats,\nWord `.docx` documents,\nand [Open Document](https://en.wikipedia.org/wiki/OpenDocument) `.odt` files\nare rendered as links to the list of items in the notebook sharing that tag:\n\n```bash\n❯nb · example : 321\n\nExample Title\n\n#tag1 #tag2\n\nExample content with link to [[Sample Title]].\n\nMore example content:\n\n- one\n- two\n- three\n```\n\nUse the [`-t <tag>`](#browse) / [`--tag <tag>`](#browse) option\nto open [`nb browse`](#browse) to the list of\nall items in the current notebook or a specified notebook or folder that\nshare a tag:\n\n```bash\n# open to a list of items tagged with \"#tag2\" in the \"example\" notebook\n❯ nb browse example: --tag tag2\n❯nb · example\n\nsearch: [#tag2               ]\n\n[example:321] Example Title\n[example:654] Sample Title\n[example:789] Demo Title\n\n# shortcut alias and short option\n❯ nb b example: -t tag2\n❯nb · example\n\nsearch: [#tag2               ]\n\n[example:321] Example Title\n[example:654] Sample Title\n[example:789] Demo Title\n```\n\nFor more information about full-text search, see\n[Search](#-search) and [`nb search`](#search).\nFor more information about browsing, see\n[Browsing](#-browsing) and [`nb browse`](#browse).\n\n### 🔗 Linking\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\nNotes,\nbookmarks,\nfiles in text-based formats,\nWord `.docx` documents,\nand [Open Document](https://en.wikipedia.org/wiki/OpenDocument) `.odt` files\ncan reference other items using\n<a href=\"#-linking\">[[wiki-style links]]</a>,\nmaking `nb` a powerful terminal-first platform for\n[Zettelkasten](#-zettelkasten),\nwiki-style knowledge mapping,\nand other link-based note-taking methods.\n\nTo add a link from a note or bookmark to another in the same notebook,\ninclude the id, title, or relative path for the target item\nwithin double square brackets anywhere in the linking document:\n\n```bash\n# link to the item with id 123 in the root level of current notebook\n[[123]]\n\n# link to the item titled \"Example Title\" in the root level of the current notebook\n[[Example Title]]\n\n# link to the item with id 456 in the folder named \"Sample Folder\"\n[[Sample Folder/456]]\n\n# link to the item titled \"Demo Title\" in the folder named \"Sample Folder\"\n[[Sample Folder/Demo Title]]\n```\n\nTo link to an item in another notebook,\nadd the notebook name with a colon before the identifier:\n\n```bash\n# link to the item with id 123 in the \"sample\" folder in the \"example\" notebook\n[[example:sample/123]]\n\n# link to the item titled \"Example Title\" in the \"demo\" notebook\n[[demo:Example Title]]\n\n# link to the item with filename \"Example File.md\" in the \"sample\" notebook\n[[sample:Example File.md]]\n```\n\nThe text for a link can be specified after a pipe `|` character:\n\n```bash\n# render link to item 123 in the \"example\" notebook as [[Example Link Text]]\n[[example:123|Example Link Text]]\n```\n\n<a href=\"#-linking\">[[wiki-style links]]</a> cooperate well with\n[Org links](https://orgmode.org/guide/Hyperlinks.html),\nwhich have a similar syntax,\nproviding a convenient option for linking collections of Org files.\n\nLinked items can be [browsed](#-browsing) with [`nb browse`](#browse).\n\nFor more information about identifying items, see [Selectors](#-selectors).\n\n### 🌍 Browsing\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\nUse [`nb browse`](#browse) (shortcut: [`nb b`](#browse)) to\nbrowse, view, edit, and search linked notes, bookmarks, notebooks, folders,\nand other items using terminal and GUI web browsers.\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/gui-gui-terminal-browse.png\"\n        alt=\"nb browse\"\n        width=\"500\">\n</div>\n\n[`nb browse`](#browse) includes an embedded, terminal-first web application\nthat renders\n<a href=\"#-linking\">[[wiki-style links]]</a>\nand\n[#hashtags](#-tagging)\nas internal links, enabling you to browse your notes and notebooks in web\nbrowsers, including seamlessly browsing to and from the offsite links in\nbookmarks and notes.\n\n```bash\n❯ nb browse\n❯nb · home : +\n\nsearch: [                    ]\n\n[home:6]  📌 Example Markdown Title\n[home:12] 🔒 example-encrypted.md.enc\n[home:11] 🔖 Example Bookmark (example.com)\n[home:10] 🔖 🔒 example-encrypted.bookmark.md.enc\n[home:9]  Example .org Title\n[home:8]  🌄 example-image.png\n[home:7]  📄 example.pdf\n[home:5]  🔉 example-audio.mp3\n[home:4]  Example LaTeX Title\n[home:3]  📹 example-video.mp4\n[home:2]  example.md\n[home:1]  📂 Example Folder\n```\n\nLists are displayed using the same format as `nb` and [`nb ls`](#ls),\nincluding [pinned](#-pinning) items, with each list item linked.\nLists are automatically paginated to fit the height of the terminal window.\n\n```bash\n❯ nb browse example:sample/demo/\n❯nb · example : sample / demo / +\n\nsearch: [                    ]\n\n[example:sample/demo/7] Title Seven\n[example:sample/demo/6] Title Six\n[example:sample/demo/5] Title Five\n[example:sample/demo/4] Title Four\n[example:sample/demo/3] Title Three\n\nnext ❯\n```\n\n[`nb browse`](#browse) is designed to make it easy to navigate within\nterminal web browsers using only keyboard commands,\nwhile also supporting mouse interactions.\nThe [`nb browse`](#browse) interface includes links\nto quickly jump to parent folders,\nthe current notebook,\nand other notebooks.\n\n[`nb browse`](#browse) opens in\n[w3m](https://en.wikipedia.org/wiki/W3m),\n[Links](https://en.wikipedia.org/wiki/Links_\\(web_browser\\)),\nor in the browser set in the `$BROWSER` environment variable.\nUse [`nb browse --gui`](#browse) / [`nb b -g`](#browse) to\nopen in the system's primary [GUI web browser](#browse---gui).\n\nTo open a specific item in [`nb browse`](#browse),\npass the [selector](#-selectors) for the item, folder, or notebook\nto [`nb browse`](#browse):\n\n```bash\n# open the item with id 42 in the folder named \"sample\" in the \"example\" notebook\n❯ nb browse example:sample/42\n❯nb · example : sample / 42 · ↓ · edit | +\n\nExample Title\n\n#tag1 #tag2\n\nExample content with link to [[Demo Title]].\n\nMore example content:\n\n  • one\n  • two\n  • three\n```\n\nItems can also be browsed with\n[`nb show --browse`](#show) / [`nb s -b`](#show),\nwhich behaves identically.\n\n[`nb browse`](#browse) is particularly useful for [bookmarks](#-bookmarks).\nCached content is rendered in the web browser along with comments and notes.\nInternal and external links are easily accessible directly in the terminal,\nproviding a convenient, distraction-free approach for browsing collections\nof bookmarks.\n\n```bash\n❯ nb browse text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · edit | +\nDaring Fireball: Markdown (daringfireball.net)\n\nhttps://daringfireball.net/projects/markdown/\n\nRelated\n\n  • https://en.wikipedia.org/wiki/Markdown\n\nComments\n\nSee also:\n\n  • [[text:formats/org]]\n  • [[cli:apps/nb]]\n\nTags\n\n#markup #plain-text\n\nContent\n\nDaring Fireball: Markdown\n\nDownload\n\nMarkdown 1.0.1 (18 KB) — 17 Dec 2004\n\nIntroduction\n\nMarkdown is a text-to-HTML conversion tool for web writers. Markdown allows\nyou to write using an easy-to-read, easy-to-write plain text format, then\nconvert it to structurally valid XHTML (or HTML).\n```\n\nNotes, bookmarks, files in text-based formats, source code,\nWord `.docx` documents, and\n[Open Document](https://en.wikipedia.org/wiki/OpenDocument) `.odt`\nfiles are converted into HTML and rendered in the browser. Use the down\narrow (`↓`) link to view or download the original file.\n\n[MathJax](https://www.mathjax.org/) support can be enabled by setting\nthe [`$NB_MATHJAX_ENABLED`](https://github.com/xwmx/nb#nb_mathjax_enabled)\nvariable in your `~/.nbrc` file:\n\n```bash\nexport NB_MATHJAX_ENABLED=1\n```\n\nWith this variable set, `nb` will automatically download and install MathJax\nfrom [GitHub](https://github.com/mathjax/MathJax) and enable it when items\nare viewed in [`nb browse --gui`](#browse).\n\n#### `browse edit`\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/gui-terminal-browse-edit.png\"\n        alt=\"nb browse edit\"\n        width=\"500\">\n</div>\n\nItems in text formats can be edited within terminal and GUI web browsers using\nthe `edit` link on the item page or by opening the item with\n[`nb browse edit`](#browse) / [`nb b e`](#browse),\nwhich automatically resizes the form to fit the current terminal window:\n\n```bash\n❯ nb browse edit text:formats/markdown/123\n❯nb · text : formats / markdown / 123 · ↓ · editing · - | +\n\n[# Daring Fireball: Markdown (daringfireball.net)         ]\n[                                                         ]\n[<https://daringfireball.net/projects/markdown/>          ]\n[                                                         ]\n[## Related                                               ]\n[                                                         ]\n[- <https://en.wikipedia.org/wiki/Markdown>               ]\n[                                                         ]\n[## Comments                                              ]\n[                                                         ]\n[See also:                                                ]\n[                                                         ]\n[- [[text:formats/org]]                                   ]\n[- [[cli:apps/nb]]                                        ]\n[                                                         ]\n[## Tags                                                  ]\n[                                                         ]\n\n[save] · last: 2021-01-01 01:00:00\n```\n\nTerminal web browsers provide different editing workflows.\n[`w3m`](https://en.wikipedia.org/wiki/W3m) opens items in your `$EDITOR`,\nthen returns you back to the browser to save changes and continue browsing.\nEdits in [`links`](https://en.wikipedia.org/wiki/Links_(web_browser))\nare performed directly in the browser.\n\nSyntax highlighting, block selection, and other\n[advanced editor features](#browse---gui-editing)\nare available with [`nb browse --gui`](#browse).\n\n#### `browse add`\n\nAdd an item within the browser using the `+` link or\n[`nb browse add`](#browse) / [`nb b a`](#browse).\nPass a notebook, folder, and / or filename selector to create a new note\nin that location:\n\n```bash\n❯ nb browse add text:formats/\n❯nb · text : formats / +\n\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n\n[add]\n```\n\n[`nb browse add`](#browse) includes options for quickly pre-populating\nnew notes with content:\n\n```bash\n❯ nb browse add --title \"Example Title\" --content \"Example content.\" --tags tag1,tag2\n❯nb · home : +\n\n[# Example Title                                    ]\n[                                                   ]\n[#tag1 #tag2                                        ]\n[                                                   ]\n[Example content.                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n[                                                   ]\n\n[add]\n```\n\n#### `browse delete`\n\nUse the `-` link on the [`nb browse edit`](#browse) page or\n[`nb browse delete`](#browse) / [`nb b d`](#browse)\nto delete an item:\n\n```bash\n❯ nb browse delete example:4\n❯nb · example : 4 · ↓ · edit · - | +\n\n              deleting\n\n[4] example_file.md \"Example Title\"\n\n              [delete]\n\n```\n\n#### `browse` Search\n\n[`nb browse`](#browse) includes a search field powered by\n[`nb search`](#search)\nthat can be used to search the current notebook or folder.\nSearch queries are treated as command line arguments for\n[`nb search`](#search),\nproviding the ability to perform `AND` and `OR` queries.\nUse the\n[`-q <query>`](#browse) / [`--query <query>`](#browse)\noption to open [`nb browse`](#browse) to\nthe results page for a search:\n\n```bash\n# open to a list of items containing \"example\" in the current notebook\n❯ nb browse --query \"example\"\n❯nb · home\n\nsearch: [example             ]\n\n[home:321] Test Title\n[home:654] Sample Title\n[home:789] Demo Title\n\n# using shortcut alias and short option\n❯ nb b -q \"example\"\n❯nb · home\n\nsearch: [example             ]\n\n[home:321] Test Title\n[home:654] Sample Title\n[home:789] Demo Title\n```\n\nSearch for [#tags](#-tagging) with the\n[`-t`](#browse) / [`--tag`](#browse) / [`--tags`](#browse) options:\n\n```bash\n# open to a list of items tagged with \"#tag2\" in the current notebook\n❯ nb browse --tag tag2\n❯nb · home\n\nsearch: [#tag2               ]\n\n[home:654] Sample Title\n[home:789] Demo Title\n\n# using shortcut alias and short option\n❯ nb b -t tag2\n❯nb · home\n\nsearch: [#tag2               ]\n\n[home:654] Sample Title\n[home:789] Demo Title\n```\n\nFor more information about search options, see [Search](#-search) and\n[`nb search`](#search).\n\n#### `browse --gui`\n\nTo open any [`nb browse`](#browse) view in\nthe system's primary GUI web browser,\nadd the [`nb browse --gui`](#browse) / [`nb b -g`](#browse) option:\n\n```bash\n# open the item with id 123 in the \"sample\" notebook in the system's primary GUI browser\nnb browse sample:123 --gui\n\n# open the folder named \"example\" in the system's primary GUI browser,\n# short option\nnb browse example/ -g\n\n# open the current notebook in the system's primary GUI browser,\n# shortcut alias and short option\nnb b -g\n```\n\n##### `browse --gui` Editing\n\nBy default,\n[`nb browse --gui`](#browse)\nuses the browser's default `<textarea>` for editing items.\n\n[Ace](https://ace.c9.io/) is a text editor for GUI web browsers\nthat provides advanced text editing functionality,\nincluding block selection and\n[syntax highlighting](#gui-web-syntax-highlighting).\n\nTo use Ace as the editor for [`nb browse --gui`](#browse),\nadd the following line to set the\n[`$NB_ACE_ENABLED`](https://github.com/xwmx/nb#nb_ace_enabled)\nvariable in your `~/.nbrc` file:\n\n```bash\nexport NB_ACE_ENABLED=1\n```\n\nThe next time a form is loaded in [`nb browse`](#browse),\n`nb` will automatically download\n(from [GitHub](https://github.com/ajaxorg/ace-builds/)),\ninstall,\nand enable the Ace editor in\n[`nb browse edit --gui`](#browse) and [`nb browse add --gui`](#browse).\n\n#### `browse` Portability\n\n[`nb browse`](#browse) depends on\neither [`socat`](https://www.kali.org/tools/socat/)\nor\n[`ncat`](https://nmap.org/ncat/) (available as part of\nthe `ncat` or `nmap` package in most package managers) and\n[`pandoc`](https://pandoc.org/). When neither `socat` nor `ncat` is\navailable and the Bash version is 5.2 or higher, [`nb browse`](#browse)\nfalls back to a pure Bash implementation that supports all features\nexcept the Ace editor. When only `pandoc` is available,\nthe current note is rendered and\n<a href=\"#-linking\">[[wiki-style links]]</a>\ngo to unrendered, original files.\nWhen `socat`,`ncat`, or Bash 5.2+ is available without `pandoc`,\nfiles in plain text formats are rendered with the original markup unconverted.\nIf neither `ncat`, `socat`, Bash 5.2+, nor `pandoc` is available,\n[`nb browse`](#browse) falls back to the default behavior of [`nb show`](#show).\n\nWhen `nb` is installed on Windows,\n`socat` ([MSYS](https://packages.msys2.org/package/socat),\n[Cygwin](https://cygwin.com/packages/summary/socat.html)) is recommended.\n\n#### `browse` Privacy\n\n[`nb browse`](#browse) is completely local and self-contained within `nb`,\nfrom the CSS and JavaScript\nall the way down through the HTTP request parsing and response building,\nwith no imports, libraries, frameworks, or third-party code\noutside of the few binary dependencies\n(`bash`, `git`, `ncat` / `socat`, `pandoc`),\nthe Linux / Unix environment,\nand the optional [Ace editor](#ace-editor).\n\nTerminal web browsers don't use JavaScript, so visits from them are not\nvisible to some web analytics tools.\n[`nb browse`](#browse) includes a number of additional features\nto enhance privacy and avoid leaking information:\n\n- Page content is cached locally within each bookmark file,\n  making it readable in terminal and GUI web browsers\n  without requesting the page again or needing to be connected to the internet.\n- `<img>` tags in bookmarked content are removed to avoid requests.\n- Outbound links are automatically rewritten to use an\n  [exit page redirect](https://geekthis.net/post/hide-http-referer-headers/#exit-page-redirect)\n  to mitigate leaking information via the\n  [referer header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer).\n- All pages include the `<meta name=\"referrer\" content=\"no-referrer\" />` tag.\n- Links include a `rel=\"noopener noreferrer\"` attribute.\n- `lynx` is opened with the `-noreferer` option.\n\n#### `browse` AsciiDoc\n\nTo [`browse`](#browse) items in [AsciiDoc](https://asciidoc.org/) format,\ninstall [`asciidoctor`](https://asciidoctor.org/).\n\n#### Shortcut Alias: `nb b`\n\n[`nb browse`](#browse) can also be used with the alias [`nb b`](#browse):\n\n```bash\n# open the current notebook in the terminal web browser\nnb b\n\n# open the item with id 123 in the \"example\" notebook using the terminal web browser\nnb b example:123\n\n# open the notebook named \"sample\" in the GUI web browser\nnb b sample: -g\n```\n\nFor more information, see [`nb browse`](#browse).\n\n### 🌄 Images\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#browse\"><code>nb browse</code></a>,\n    <a href=\"#import\"><code>nb import</code></a>,\n    <a href=\"#open\"><code>nb open</code></a>,\n    <a href=\"#show\"><code>nb show</code></a>\n  </sup>\n</p>\n\n`nb` can be used to view, organize, browse, reference, and work with images in\nterminals,\nweb browsers,\nand GUI applications.\n\n#### Image Items\n\n[Import](#%EF%B8%8F-import--export) images with [`nb import`](#import):\n\n```bash\n# import the image file \"example.png\" into the current notebook\nnb import example.png\n\n# import an image file from a URL into the current notebook\nnb import https://raw.githubusercontent.com/xwmx/nb/master/docs/images/nb.png\n\n# nb import \"sample.jpg\" into the \"demo\" folder in the \"example\" notebook\nnb import sample.jpg example:demo/\n```\n\nImported images are displayed with [`🌄` indicators](#indicators) in\n[lists](#listing--filtering):\n\n```bash\n❯ nb\nhome\n----\n[5] Example Five\n[4] 🌄 example-image.png\n[3] Example Three\n[2] Example Two\n[1] Example One\n```\n\nImported image items can be opened in the system GUI application for\nthe item's file type using [`nb open`](#open):\n\n```bash\n# open the image \"example-image.png\" in the system GUI photo viewer\nnb open example-image.png\n\n# open the image with id \"4\" in the system GUI photo viewer\nnb 4 o\n```\n\nImage items can be viewed in web browsers with [`nb browse`](#browse),\nproviding a convenient mechanism for\n[browsing](#-browsing) notebooks and folders containing image collections.\n\n[`nb browse`](#browse) renders image items within in an `<img>` tag\non the item page. Open the item page for an image item by passing a\n[selector](#-selectors) to [`nb browse`](#browse), optionally including the\n[`-g`](#browse) / [`--gui`](#browse) option\nto open the page in the system GUI web browser:\n\n```bash\n# open item with id \"123\" in the terminal web browser\nnb browse 123\n\n# open item with id \"456\" in the \"example\" notebook in the GUI web browser\nnb browse example:456 --gui\n\n# open item \"example:456\" in the GUI web browser, alternative\nnb example:456 b -g\n```\n\nThe original file can be viewed or downloaded from the item page\nby either clicking the image item or using the down arrow (`↓`) link.\n\n[`nb browse --gui`](#browse---gui) displays images in any GUI web browser.\nSome terminal web browsers, such as [`w3m`](http://w3m.sourceforge.net/),\ncan be configured to display images.\n\n[`nb show`](#show) can display images directly in the terminal with\nsupported tools and configurations, including:\n\n- [`catimg`](https://github.com/posva/catimg)\n- [Chafa](https://github.com/hpjansson/chafa)\n- [ImageMagick](https://imagemagick.org/) with a terminal that\n  supports [sixels](https://en.wikipedia.org/wiki/Sixel)\n- [`imgcat`](https://www.iterm2.com/documentation-images.html) with\n  [iTerm2](https://www.iterm2.com/)\n- [kitty's `icat` kitten](https://sw.kovidgoyal.net/kitty/kittens/icat.html)\n- [`termvisage`](https://github.com/AnonymouX47/termvisage)\n- [`timg`](https://github.com/hzeller/timg)\n- [`viu`](https://github.com/atanunq/viu)\n\nA preferred image viewer tool can be set with the\n[`$NB_IMAGE_TOOL`](#nb_image_tool) variable in your `~/.nbrc` file,\nwhich can be opened in your editor with [`nb settings edit`](#settings).\n\n#### Inline Images\n\nImages can be referenced and rendered inline within\nnotes, bookmarks, and other items.\n\nTo reference an image in the same notebook,\nspecify the image's relative path within the notebook:\n\n```markdown\n# reference \"example.jpg\" from markdown\n![](example.jpg)\n\n# reference \"demo.png\" in the \"sample\" folder from markdown\n![](sample/demo.png)\n```\n\nImages in any notebook can be referenced using the `--original` URL,\nobtainable from the image's [`nb browse`](#browse) item page\nby either clicking the image item or using the down arrow (`↓`) link.\n\n```markdown\n# reference \"example.jpg\" in the \"home\" notebook with the --original URL\n![](http://localhost:6789/--original/home/example.jpg)\n```\n\nImage references in content are rendered inline within web browsers with\n[`nb browse`](#browse) and [`nb show --render`](#show).\n\n`<img>` tags are stripped from bookmarked content when rendering to HTML.\nInline images can still be used in other bookmark sections like\n[`## Comment`](#-comment).\n\n### 🗂 Zettelkasten\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a>\n  </sup>\n</p>\n\nZettelkasten (German: \"slip box\") is a method of note-taking and\npersonal knowledge management modeled around a few key features:\n\n- Notes are taken liberally on index cards.\n- Each note is numbered for easy reference.\n- Index cards are organized into boxes.\n- Index cards can reference other index cards.\n- Cards can include tags and other metadata.\n\nSince `nb` works directly on plain text files\norganized in normal system directories in normal git repositories,\n`nb` is a very close digital analogue to physical zettelkasten note-taking.\n\n|    Zettelkasten   |                       `nb`                      |\n|:-----------------:|:-----------------------------------------------:|\n| index cards       | [notes](#-notes) & [bookmarks](#-bookmarks)     |\n| numbering         | ids & [selectors](#-selectors)                  |\n| slip boxes        | [notebooks](#-notebooks)                        |\n| tags              | [#tags](#-tagging)                              |\n| metadata          | [front matter](#front-matter)                   |\n| cross-references  |  <a href=\"#-linking\">[[wiki-style links]]</a>   |\n| fast note-taking  | [`nb add`](#adding)/[`nb <url>`](#-bookmarks)   |\n\nFor more information about Zettelkasten, see\n[Wikipedia](https://en.wikipedia.org/wiki/Zettelkasten).\n\n### 📂 Folders\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#add\"><code>nb add</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>,\n    <a href=\"#folders\"><code>nb folders</code></a>,\n    <a href=\"#list\"><code>nb list</code></a>,\n    <a href=\"#ls\"><code>nb ls</code></a>\n  </sup>\n</p>\n\nItems can be organized in folders.\nTo add a note to a folder,\ncall [`nb add`](#add) with the folder's relative path within the notebook\nfollowed by a slash:\n\n```bash\n# add a new note in the folder named \"example\"\nnb add example/\n\n# add a new note in the folder named \"demo\" in \"example\"\nnb add example/demo/\n```\n\n`nb` automatically creates any intermediate folders as needed.\n\nFolders can be created directly using [`nb add folder`](#add),\n[`nb folders add`](#folders), and [`nb add --type folder`](#add):\n\n```bash\n# create a new folder named \"sample\"\nnb add folder sample\n\n# create a new folder named \"sample\", alternative\nnb folders add sample\n\n# create a new folder named \"demo\"\nnb add demo --type folder\n\n# create a folder named \"example\" containing a folder named \"test\"\nnb add example/test --type folder\n```\n\nTo list the items in a folder, pass the folder relative path to\n`nb`,\n[`nb ls`](#ls),\n[`nb list`](#list),\nor [`nb browse`](#browse)\nwith a trailing slash:\n\n```bash\n❯ nb example/demo/\nhome\n----\n[example/demo/3] Title Three\n[example/demo/2] Title Two\n[example/demo/1] Title One\n```\n\nFolders can also be identified by the folder's id\nand listed with a trailing slash:\n\n```bash\n❯ nb list\n[1] 📂 example\n\n❯ nb list 1/\n[example/2] 📂 demo\n[example/1] document.md\n\n❯ nb list 1/2/\n[example/demo/3] Title Three\n[example/demo/2] Title Two\n[example/demo/1] Title One\n```\n\nItems in folders can be idenitified with\nthe folder's relative path using either folder ids or names,\nfollowed by the id, title, or filename of the item:\n\n```bash\n# list item 1 (\"Title One\", one.md) in the example/demo/ folder\nnb list example/demo/1\n\n# edit item 1 (\"Title One\", one.md) in the example/demo/ folder\nnb edit example/2/one.md\n\n# show item 1 (\"Title One\", one.md) in the example/demo/ folder\nnb show 1/2/Title\\ One\n\n# delete item 1 (\"Title One\", one.md) in the example/demo/ folder\nnb delete 1/demo/1\n```\n\nFor folders and items in other notebooks,\ncombine the relative path with the notebook name, separated by a colon:\n\n```bash\n# list the contents of the \"sample\" folder in the \"example\" notebook\nnb example:sample/\n\n# add an item to the \"sample/demo\" folder in the \"example\" notebook\nnb add example:sample/demo/\n\n# edit item 3 in the \"sample/demo\" folder in the \"example\" notebook\nnb edit example:sample/demo/3\n```\n\n[Browse](#-browsing) starting at any folder with [`nb browse`](#browse):\n\n```bash\n❯ nb browse example:sample/demo/\n❯nb · example : sample / demo /\n\nsearch: [                    ]\n\n[example:sample/demo/5] Title Five\n[example:sample/demo/4] Title Four\n[example:sample/demo/3] Title Three\n[example:sample/demo/2] Title Two\n[example:sample/demo/1] Title One\n```\n\nFor more information about identifying folders, see [Selectors](#-selectors).\n\n### 📌 Pinning\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#pin\"><code>nb pin</code></a>,\n    <a href=\"#unpin\"><code>nb unpin</code></a>,\n    <a href=\"#ls\"><code>nb ls</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\nItems can be pinned so they appear first in\n`nb`, [`nb ls`](#ls), and [`nb browse`](#browse):\n\n```bash\n❯ nb\nhome\n----\n[2] 📌 Title Two\n[5] Title Five\n[4] Title Four\n[3] Title Three\n[1] Title One\n```\n\nUse [`nb pin`](#pin) and [`nb unpin`](#unpin) to pin and unpin items:\n\n```bash\n❯ nb\nhome\n----\n[5] Title Five\n[4] Title Four\n[3] Title Three\n[2] Title Two\n[1] Title One\n\n❯ nb pin 4\nPinned: [4] four.md \"Title Four\"\n\n❯ nb pin 1\nPinned: [1] one.md \"Title One\"\n\n❯ nb\nhome\n----\n[4] 📌 Title Four\n[1] 📌 Title One\n[5] Title Five\n[3] Title Three\n[2] Title Two\n\n❯ nb unpin 4\nUnpinned: [4] four.md \"Title Four\"\n\n❯ nb\nhome\n----\n[1] 📌 Title One\n[5] Title Five\n[4] Title Four\n[3] Title Three\n[2] Title Two\n```\n\n`nb` can also be configured to pin notes that contain\na specified [#hashtag](#-tagging) or other search pattern.\nTo enable tag / search-based pinning,\nset the [`$NB_PINNED_PATTERN`](#nb_pinned_pattern) environment variable to\nthe desired [#tag](#-tagging) or pattern.\n\nFor example, to treat all items tagged with `#pinned` as pinned items,\nadd the following line to your `~/.nbrc` file,\nwhich can be opened in your editor with [`nb settings edit`](#settings):\n\n```bash\nexport NB_PINNED_PATTERN=\"#pinned\"\n```\n\nAll [indicator icons](#indicators) in `nb` can be customized, so\nto use a different character as the pindicator,\nsimply add a line like the following to your `~/.nbrc` file:\n\n```bash\nexport NB_INDICATOR_PINNED=\"💖\"\n```\n\n```bash\n❯ nb\nhome\n----\n[1] 💖 Title One\n[5] Title Five\n[4] Title Four\n[3] Title Three\n[2] Title Two\n```\n\nTo bump an item to the top of the list without pinning, use the\n[`bump` plugin](#bump).\n\n### 🔍 Search\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#search\"><code>nb search</code></a>\n  </sup>\n</p>\n\nUse [`nb search`](#search) (shortcut: [`nb q`](#search)) to\nperform full text searches, with support for regular expressions,\n[#tags](#-tagging), and `AND`, `OR`, and `NOT` queries:\n\n```bash\n# search current notebook for \"example query\"\nnb search \"example query\"\n\n# search the notebook \"example\" for \"example query\"\nnb search example: \"example query\"\n\n# search the folder named \"demo\" for \"example query\"\nnb search demo/ \"example query\"\n\n# search all unarchived notebooks for \"example query\" and list matching items\nnb search \"example query\" --all --list\n\n# search for \"example\" AND \"demo\" with multiple arguments\nnb search \"example\" \"demo\"\n\n# search for \"example\" AND \"demo\" with option\nnb search \"example\" --and \"demo\"\n\n# search for \"example\" OR \"sample\" with argument\nnb search \"example|sample\"\n\n# search for \"example\" OR \"sample\" with option\nnb search \"example\" --or \"sample\"\n\n# search for items matching both \"Example\" AND \"Sample\", and NOT \"Demo\"\nnb search \"Example\" --and \"Sample\" --not \"Demo\"\n\n# search items containing the hashtag \"#example\"\nnb search \"#example\"\n\n# search with a regular expression\nnb search \"\\d\\d\\d-\\d\\d\\d\\d\"\n\n# search bookmarks for \"example\"\nnb search \"example\" --type bookmark\n\n# search bookmarks for \"example\", alternative\nnb bk q \"example\"\n\n# search the current notebook for \"example query\"\nnb q \"example query\"\n\n# search the notebook named \"example\" for \"example query\"\nnb q example: \"example query\"\n\n# search all unarchived notebooks for \"example query\" and list matching items\nnb q -la \"example query\"\n```\n\n[`nb search`](#search) prints the id number, filename,\nand title of each matched file,\nfollowed by each search query match and its line number,\nwith color highlighting:\n\n```bash\n❯ nb search \"example\"\n[314]  🔖 example.bookmark.md \"Example Bookmark (example.com)\"\n--------------------------------------------------------------\n1:# Example Bookmark (example.com)\n\n3:<https://example.com>\n\n[2718] example.md \"Example Note\"\n--------------------------------\n1:# Example Note\n```\n\nTo just print the note information line without the content matches,\nuse the [`-l`](#search) or [`--list`](#search) option:\n\n```bash\n❯ nb search \"example\" --list\n[314]  🔖 example.bookmark.md \"Example Bookmark (example.com)\"\n[2718] example.md \"Example Note\"\n```\n\nMultiple query arguments are treated as `AND` queries,\nreturning items that match all queries.\n`AND` queries can also be specified with the\n[`--and <query>`](#search) option:\n\n```bash\n# search for items tagged with \"#example\" AND \"#demo\" AND \"#sample\" using\n# multiple arguments\nnb q \"#example\" \"#demo\" \"#sample\"\n\n# options\nnb q \"#example\" --and \"#demo\" --and \"#sample\"\n```\n\n`nb` matches `AND` query terms regardless of where they appear in a document,\nan improvement over most approaches for performing `AND` queries\nwith command line tools,\nwhich typically only match terms appearing on the same line.\n\n`OR` queries return items that match at least one of the queries\nand can be created by separating terms in a single argument\nwith a pipe character `|` or with the [`--or <query>`](#search) option:\n\n```bash\n# search for \"example\" OR \"sample\" with argument\nnb q \"example|sample\"\n\n# search for \"example\" OR \"sample\" with option\nnb q \"example\" --or \"sample\"\n```\n\n[`--or`](#search) and [`--and`](#search) queries can be used together:\n\n```bash\nnb q \"example\" --or \"sample\" --and \"demo\"\n# equivalent: example|sample AND demo|sample\n```\n\n`NOT` queries exclude items that match the specified query and are\nspecified with [`--not <query>`](#search), which can be used with\n`--and` and `--or`:\n\n```bash\n# search for items that match \"Example\", excluding items that also match \"Sample\"\nnb search \"Example\" --not \"Sample\"\n\n# search for items matching both \"Example\" AND \"Sample\", and NOT \"Demo\"\nnb search \"Example\" --and \"Sample\" --not \"Demo\"\n```\n\nSearch for [#tags](#-tagging) with flexible\n[`nb search --tags [<tags>]`](#search) / [`nb q -t [<tags>]`](#search) options:\n\n```bash\n# search for tags in the current notebook\nnb search --tags\n\n# search for tags in the \"sample\" notebook, shortcut alias\nnb sample:q --tags\n\n# search for items tagged with \"#tag1\"\nnb search --tag tag1\n\n# search for items tagged with \"#tag1\", shortcut alias and short option\nnb q -t tag1\n\n# search for items tagged with \"#tag1\", shortcut alias and argument\nnb q \\#tag1\n\n# search for items tagged with \"#tag1\", shortcut alias and argument, alternative\nnb q \"#tag1\"\n\n# search for items in the \"sample\" notebook tagged with \"#tag1\" AND \"#tag2\"\nnb sample:search --tag tag1 --tag tag2\n\n# search for items in the \"sample\" notebook tagged with \"#tag1\" AND \"#tag2\"\nnb sample:q --tags tag1,tag2\n\n# search for items in the current notebook tagged with \"#tag1\" AND \"#tag2\"\nnb q --tag tag1 --tag tag2\n\n# search for items in the current notebook tagged with \"#tag1\" OR \"#tag2\"\nnb q -t tag1 --or -t tag2\n\n# search for items tagged with \"#tag1\" AND \"#tag2\" AND \"#tag3\"\nnb q -t tag1 --tags tag2,tag3\n\n# search for items tagged with \"#tag1\" OR \"#tag2\" OR \"#tag3\"\nnb q -t tag1 --or --tags tag2,tag3\n\n# search for items tagged with \"#tag1\" OR \"#tag2\" OR \"#tag3\"\nnb q \\#tag1 --or -t tag2 --or \"#tag3\"\n```\n\n[`nb search`](#search) leverages Git's powerful built-in\n[`git grep`](https://git-scm.com/docs/git-grep).\n`nb` also supports performing searches with alternative search tools\nusing the [`--utility <name>`](#search) option.\n\nSupported alternative search tools:\n- [`rga`](https://github.com/phiresky/ripgrep-all)\n- [`rg`](https://github.com/BurntSushi/ripgrep)\n- [`ag`](https://github.com/ggreer/the_silver_searcher)\n- [`ack`](https://beyondgrep.com/)\n- [`grep`](https://en.wikipedia.org/wiki/Grep)\n\n##### Shortcut Alias: `nb q`\n\n[`nb search`](#search) can also be used with the alias\n[`nb q`](#search) (for \"query\"):\n\n```bash\n# search for \"example\" and print matching excerpts\nnb q \"example\"\n\n# search for \"example\" and list each matching file\nnb q -l \"example\"\n\n# search for \"example\" in all unarchived notebooks\nnb q -a \"example\"\n\n# search for \"example\" in the notbook named \"sample\"\nnb sample:q \"example\"\n```\n\nFor more information about search, see [`nb help search`](#search).\n\n##### Searching with `browse`\n\nSearches can be performed within terminal and GUI web browsers using\n[`nb browse --query`](#browse) / [`nb b -q`](#browse):\n\n```bash\n❯ nb browse --query \"#example\"\n❯nb · home : +\n\nsearch: [#example             ]\n\n[home:7]   Title Seven\n[home:32]  Title Thirty-Two\n[home:56]  Title Fifty-Six\n[home:135] Title One Hundred and Thirty-Five\n```\n\nFor more information, see [Browsing](#-browsing).\n\n### ↔ Moving & Renaming\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#move\"><code>nb move</code></a>,\n    <a href=\"#copy\"><code>nb copy</code></a>\n  </sup>\n</p>\n\nUse [`nb move`](#move) (alias: [`nb rename`](#move), shortcut: [`nb mv`](#move))\nto move and rename items:\n\n```bash\n# move \"example.md\" to \"sample.org\"\nnb move example.md sample.org\n\n# rename note 2 (\"example.md\") to \"New Name.md\"\nnb rename 2 \"New Name\"\n```\n\nItems can be moved between notebooks and folders:\n\n```bash\n# move note 12 from the \"example\" notebook into \"Sample Folder\" in the \"demo\" notebook\nnb move example:12 demo:Sample\\ Folder/\n```\n\nWhen the file extension is omitted, the existing extension is used:\n\n```bash\n# rename \"example.bookmark.md\" to \"New Name.bookmark.md\"\nnb move example.bookmark.md \"New Name\"\n```\n\nWhen only a file extension is specified, only the extension is updated:\n\n```bash\n# change the file extension of note 5 (\"demo file.md\") to .org (\"demo file.org\")\nnb rename 5 .org\n```\n\nUse [`nb rename --to-bookmark`](#move) to change the extension of a note\nto `.bookmark.md`,\n[`nb rename --to-todo`](#move) to change the extension to `.todo.md`,\nand [`nb rename --to-note`](#move) to change the extension\nof a bookmark or todo to either `.md` or the extension set with\n[`nb set default_extension`](#default_extension):\n\n```bash\n# rename note 3 (\"example.md\") to a bookmark named \"example.bookmark.md\"\nnb rename 3 --to-bookmark\n\n# rename bookmark 6 (\"sample.bookmark.md\") to a note named \"sample.md\"\nnb rename 6 --to-note\n\n# rename note 7 (\"demo.md\") to a todo named \"demo.todo.md\"\nnb rename 7 --to-todo\n```\n\nUse [`nb rename --to-title`](#move) to set the filename to the note title,\nlowercased with spaces and disallowed filename characters replaced\nwith underscores:\n\n```bash\n❯ nb rename 12 --to-title\nMoving:   [12] 20210101010000.md \"Example Title\"\nTo:       example_title.md\nProceed?  [y/N]\n```\n\nCopy an item to a destination notebook, folder path, or filename\nwith [`nb copy`](#copy) (alias: [`nb duplicate`](#copy)):\n\n```bash\n# copy item 456 to \"sample.md\"\nnb copy 456 sample.md\n\n# copy item 678 to the \"example\" notebook\nnb copy 678 example:\n\n# copy item 789 to the \"demo\" folder\nnb copy 789 demo/\n\n# copy item 543 to test.md in the \"sample\" folder in the \"example\" notebook\nnb copy 543 example:sample/test.md\n```\n\nOmit a destination to copy the item in place:\n\n```bash\n# copy item 123 (\"example.md\") to example-1.md\n❯ nb copy 123\nAdded: [124] example-1.md\n\n# copy item 123 (\"example.md\") to example-2.md, alias\n❯ nb duplicate 123\nAdded: [125] example-2.md\n```\n\nFor more information about moving, renaming, and copying items, see\n[`nb help move`](#move) and [`nb help copy`](#copy).\n\n### 🗒 Revision History\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#history\"><code>nb history</code></a>,\n    <a href=\"#notebooks\"><code>nb notebooks</code></a>\n  </sup>\n</p>\n\nWhenever a note is added, modified, or deleted,\n`nb` automatically commits the change to git transparently in the background.\n\nUse [`nb history`](#history) to view the revision history of\nany notebook, folder, or item:\n\n```bash\n# show history for current notebook\nnb history\n\n# show history for note number 4\nnb history 4\n\n# show history for note with filename example.md\nnb history example.md\n\n# show history for note titled \"Example\"\nnb history Example\n\n# show history for the notebook named \"example\"\nnb example:history\n\n# show history for the notebook named \"example\", alternative\nnb history example:\n\n# show the history for note 12 in the notebook named \"example\"\nnb history example:12\n```\n\n[`nb history`](#history) uses `git log` by default and prefers\n[`tig`](https://github.com/jonas/tig) when available.\n\n#### Authorship\n\nBy default, git commits are attributed to the email and name configured in your\n[global `git` configuration](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration).\n\nChange the email and name used for a notebook with\n[`nb notebooks author`](#notebooks):\n\n```bash\n# edit the commit author email and name for the current notebook\n❯ nb notebooks author\nCurrent configuration for: home\n--------------------------\nemail (global): example@example.test\nname  (global): Example Name\n\nUpdate?  [y/N]\n\n# edit the commit author email and name for the notebook named \"example\"\n❯ nb notebooks author example\nCurrent configuration for: example\n--------------------------\nemail (global): example@example.test\nname  (global): Example Name\n\nUpdate?  [y/N]\n```\n\nThe updated author email and name applies to subsequent commits.\n\nTo use a different email and name from the beginning of a notebook's\nhistory, create the new notebook using\n[`nb notebooks add --author`](#notebooks) or\n[`nb notebooks init --author`](#notebooks).\n\n### 📚 Notebooks\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#notebooks\"><code>nb&nbsp;notebooks</code></a>,\n    <a href=\"#archive\"><code>nb&nbsp;archive</code></a>,\n    <a href=\"#unarchive\"><code>nb&nbsp;unarchive</code></a>,\n    <a href=\"#use\"><code>nb&nbsp;use</code></a>\n  </sup>\n</p>\n\nYou can create additional notebooks, each of which has its own version history.\n\nCreate a new notebook with [`nb notebooks add`](#notebooks):\n\n```bash\n# add a notebook named example\nnb notebooks add example\n```\n\n`nb` and [`nb ls`](#ls) list the available notebooks above the list of notes:\n\n```bash\n❯ nb\nexample · home\n--------------\n[3] Title Three\n[2] Title Two\n[1] Title One\n```\n\nCommands in `nb` run within the current notebook, and identifiers\nsuch as ids, filenames, and titles refer to notes within the current notebook.\n`nb edit 3`, for example, tells `nb` to\n[`edit`](#edit) note with id `3` within the current notebook.\n\nTo switch to a different notebook, use [`nb use`](#use):\n\n```bash\n# switch to the notebook named \"example\"\nnb use example\n```\n\nIf you are in one notebook and you want\nto perform a command in a different notebook without switching to it,\nadd the notebook name with a colon before the command name:\n\n```bash\n# add a new note in the notebook \"example\"\nnb example:add\n\n# add a new note in the notebook \"example\", shortcut alias\nnb example:a\n\n# show note 5 in the notebook \"example\"\nnb example:show 5\n\n# show note 5 in the notebook \"example\", shortcut alias\nnb example:s 5\n\n# edit note 12 in the notebook \"example\"\nnb example:edit 12\n\n# edit note 12 in the notebook \"example\", shortcut alias\nnb example:e 12\n\n# search for \"example query\" in the notebook \"example\"\nnb example:search \"example query\"\n\n# search for \"example query\" in the notebook \"example\", shortcut alias\nnb example:q \"example query\"\n\n# show the revision history of the notebook \"example\"\nnb example:history\n```\n\nThe notebook name with colon can also be used as a modifier to\nthe id, filename, or title:\n\n```bash\n# edit note 12 in the notebook \"example\"\nnb edit example:12\n\n# edit note 12 in the notebook \"example\", shortcut alias\nnb e example:12\n\n# edit note 12 in the notebook \"example\", alternative\nnb example:12 edit\n\n# edit note 12 in the notebook \"example\", alternative, shortcut alias\nnb example:12 e\n\n# show note titled \"misc\" in the notebook \"example\"\nnb show example:misc\n\n# show note titled \"misc\" in the notebook \"example\", shortcut alias\nnb s example:misc\n\n# delete note with filename \"todos.md\" in the notebook \"example\", alternative\nnb example:todos.md delete\n\n# delete note with filename \"todos.md\" in the notebook \"example\", alternative,\n# shortcut alias\nnb example:todos.md d\n```\n\nWhen a notebook name with colon is called without a subcommand,\n`nb` runs [`nb ls`](#ls) in the specified notebook:\n\n```bash\n❯ nb example:\nexample · home\n--------------\n[example:3] Title Three\n[example:2] Title Two\n[example:1] Title One\n```\n\nA bookmark can be created in another notebook by specifying\nthe notebook name with colon, then a space, then the URL and bookmark options:\n\n```bash\n# create a new bookmark in a notebook named \"sample\"\n❯ nb sample: https://example.com --tags tag1,tag2\n```\n\nNotes can also be moved between notebooks:\n\n```bash\n# move note 3 from the current notebook to \"example\"\nnb move 3 example:\n\n# move note 5 in the notebook \"example\" to the notebook \"sample\"\nnb move example:5 sample:\n```\n\n##### Example Workflow\n\nThe flexibility of `nb`'s argument handling makes it easy to\nbuild commands step by step as items are listed, filtered, viewed, and edited,\nparticularly in combination with shell history:\n\n```bash\n# list items in the \"example\" notebook\n❯ nb example:\nexample · home\n--------------\n[example:3] Title Three\n[example:2] Title Two\n[example:1] Title One\n\n# filter list\n❯ nb example: three\n[example:3] Title Three\n\n# view item\n❯ nb example:3 show\n# opens item in `less`\n\n# edit item\n❯ nb example:3 edit\n# opens item in $EDITOR\n```\n\n##### Notebooks and Tab Completion\n\n[`nb` tab completion](#tab-completion) is optimized for\nfrequently running commands in various notebooks using the colon syntax,\nso installing the completion scripts is recommended\nand makes working with notebooks easy, fluid, and fun.\n\nFor example, listing the contents of a notebook is usually as simple as typing\nthe first two or three characters of the name,\nthen pressing the `<tab>` key,\nthen pressing `<enter>` / `<return>`:\n\n```bash\n❯ nb exa<tab>\n# completes to \"example:\"\n❯ nb example:\nexample · home\n--------------\n[example:3] Title Three\n[example:2] Title Two\n[example:1] Title One\n```\n\nScoped notebook commands are also available in tab completion:\n\n```bash\n❯ nb exa<tab>\n# completes to \"example:\"\n❯ nb example:hi<tab>\n# completes to \"example:history\"\n```\n\n#### Notebooks, Tags, and Taxonomy\n\n`nb` is optimized to work well with a collection of notebooks, so\nnotebooks are a good way to organize notes and bookmarks by top-level topic.\n\n[#tags](#-tagging) are searchable across notebooks and can be created ad hoc,\nmaking notebooks and tags distinct and complementary organizational systems\nin `nb`.\n\nSearch for a tag in or across notebooks with\n[`nb search`](#search) / [`nb q`](#search):\n\n```bash\n# search for #tag in the current notebook\nnb q --tag tag\n\n# search for #tag in all notebooks, short options\nnb q -t tag -a\n\n# search for #tag in the \"example\" notebook, argument\nnb q example: \"#tag\"\n```\n\n#### Global and Local Notebooks\n\n##### Global Notebooks\n\nBy default, all `nb` notebooks are global, making them\nalways accessible in the terminal regardless of the current working directory.\nGlobal notebooks are stored in the directory configured in\n[`nb set nb_dir`](#nb_dir),\nwhich is `~/.nb` by default.\n\n##### Local Notebooks\n\n`nb` also supports creating and working with local notebooks.\nLocal notebooks are notebooks that are\nanywhere on the system outside of [`$NB_DIR`](#nb_dir-1).\nAny folder can be an `nb` local notebook, which is just a normal folder\nthat has been initialized as a git repository and contains an `nb` .index file.\nInitializing a folder as an `nb` local notebook is a very easy way to\nadd structured git versioning to any folder of documents and other files.\n\nWhen `nb` runs within a local notebook,\nthe local notebook is set as the current notebook:\n\n```bash\n❯ nb\nlocal · example · home\n----------------------\n[3] Title Three\n[2] Title Two\n[1] Title One\n```\n\nA local notebook is always referred to by the name `local`\nand otherwise behaves just like a global notebook\nwhenever a command is run from within it:\n\n```bash\n# add a new note in the local notebook\nnb add\n\n# edit note 15 in the local notebook\nnb edit 15\n\n# move note titled \"Todos\" from the home notebook to the local notebook\nnb move home:Todos local:\n\n# move note 1 from the local notebook to the home notebook\nnb move 1 home:\n\n# search the local notebook for <query string>\nnb search \"query string\"\n\n# search the local notebook and all unarchived global notebooks for <query string>\nnb search \"query string\" --all\n```\n\nLocal notebooks can be created with [`nb notebooks init`](#notebooks):\n\n```bash\n# initialize the current directory as a notebook\nnb notebooks init\n\n# create a new notebook at ~/example\nnb notebooks init ~/example\n\n# clone an existing notebook to ~/example\nnb notebooks init ~/example https://github.com/example/example.git\n```\n\nLocal notebooks can also be created by exporting a global notebook:\n\n```bash\n# export global notebook named \"example\" to \"../path/to/destination\"\nnb notebooks export example ../path/to/destination\n\n# alternative\nnb export example ../path/to/destination\n```\n\nLocal notebooks can also be imported, making them global:\n\n```bash\n# import notebook or folder at \"../path/to/notebook\"\nnb notebooks import ../path/to/notebook\n\n# alternative\nnb import ../path/to/notebook\n```\n\n[`nb notebooks init`](#notebooks) and [`nb notebooks import`](#notebooks)\ncan be used together to easily turn any directory of existing files\ninto a global `nb` notebook:\n\n```bash\n❯ ls\nexample-directory\n\n❯ nb notebooks init example-directory\nInitialized local notebook: /home/username/example-directory\n\n❯ nb notebooks import example-directory\nImported notebook: example-directory\n\n❯ nb notebooks\nexample-directory\nhome\n```\n\n#### Archiving Notebooks\n\n<p>\n  <sup>\n    <a href=\"#-notebooks\">↑</a> ·\n    <a href=\"#archive\"><code>nb&nbsp;archive</code></a>,\n    <a href=\"#status\"><code>nb&nbsp;status</code></a>,\n    <a href=\"#unarchive\"><code>nb&nbsp;unarchive</code></a>\n  </sup>\n</p>\n\nNotebooks can be archived using\n[`nb archive`](#archive) (shortcut: [`nb ar`](#archive)):\n\n```bash\n# archive the current notebook\nnb archive\n\n# archive the notebook named \"example\"\nnb archive example\n\n# archive the current notebook, shortcut alias\nnb ar\n\n# archive the notebook named \"example\", shortcut alias\nnb ar example\n```\n\nWhen a notebook is archived it is not included in\n[`nb`](#ls) / [`nb ls`](#ls) output,\n[`nb search --all`](#search),\nor tab completion,\nnor synced automatically with [`nb sync --all`](#sync).\n\n```bash\n❯ nb\nexample1 · example2 · example3 · [1 archived]\n---------------------------------------------\n[3] Title Three\n[2] Title Two\n[1] Title One\n```\n\nArchived notebooks can still be used individually\nusing normal notebook commands:\n\n```bash\n# switch the current notebook to the archived notebook \"example\"\nnb use example\n\n# run the `list` subcommand in the archived notebook \"example\"\nnb example:list\n```\n\nCheck a notebook's archival status with\n[`nb status`](#status) (shortcut: [`nb st`](#status)) and\n[`nb notebooks status`](#notebooks):\n\n```bash\n# print status information, including archival status, for the current notebook\nnb status\n\n# print status information, including archival status, for the notebook named \"example\"\nnb status example\n\n# print status information, including archival status, for the current notebook,\n# shortcut alias\nnb st\n\n# print status information, including archival status, for the notebook named \"example\",\n# shortcut alias\nnb st example\n\n# print the archival status of the current notebook\nnb notebooks status\n\n# print the archival status of the notebook named \"example\"\nnb notebooks status example\n```\n\nUse [`nb unarchive`](#unarchive) (shortcut: [`nb unar`](#unarchive))\nto unarchive a notebook:\n\n```bash\n# unarchive the current notebook\nnb unarchive\n\n# unarchive the notebook named \"example\"\nnb unarchive example\n```\n\nFor more information about working with notebooks, see\n[`nb help notebooks`](#notebooks),\n[`nb help archive`](#archive),\nand [`nb help unarchive`](#unarchive).\n\nFor technical details about notebooks, see\n[`nb` Notebook Specification](#nb-notebook-specification).\n\n### 🔄 Git Sync\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#remote\"><code>nb remote</code></a>,\n    <a href=\"#sync\"><code>nb sync</code></a>\n  </sup>\n</p>\n\nEach notebook can be synced with a remote git repository by\nsetting the remote URL using [`nb remote`](#remote):\n\n```bash\n# set the current notebook's remote to a private GitHub repository\nnb remote set https://github.com/example/example\n\n# set the remote for the notebook named \"example\"\nnb example:remote set https://github.com/example/example\n```\n\nAny notebook with a remote URL will sync automatically\nevery time a command is run in that notebook.\n\nWhen you use `nb` on multiple systems, you can\nset a notebook on each system to the same remote\nand `nb` will keep everything in sync in the background\nevery time there's a change in that notebook.\n\nSince each notebook has its own git history,\nyou can have some notebooks syncing with remotes\nwhile other notebooks are only available locally on that system.\n\nMany services provide free private git repositories, so\ngit syncing with `nb` is easy, free, and vendor-independent.\nYou can also sync your notes using\nDropbox, Drive, Box, Syncthing, or another syncing tool\nby changing your `nb` directory with\n[`nb set nb_dir <path>`](#nb_dir),\nand git syncing will still work simultaneously.\n\nClone an existing notebook by passing the URL to\n[`nb notebooks add`](#notebooks):\n\n```bash\n# create a new notebook named \"example\" cloned from a private GitLab repository\nnb notebooks add example https://gitlab.com/example/example.git\n```\n\nTurn off syncing for a notebook by removing the remote:\n\n```bash\n# remove the remote from the current notebook\nnb remote remove\n\n# remove the remote from the notebook named \"example\"\nnb example:remote remove\n```\n\nAutomatic git syncing can be turned on or off with\n[`nb set auto_sync`](#auto_sync).\n\nTo sync manually, use [`nb sync`](#sync):\n\n```bash\n# manually sync the current notebook\nnb sync\n\n# manually sync the notebook named \"example\"\nnb example:sync\n```\n\nTo bypass `nb` syncing and run `git` commands directly within a\nnotebook, use [`nb git`](#git):\n\n```bash\n# run `git fetch` in the current notebook\nnb git fetch origin\n\n# run `git status` in the notebook named \"example\"\nnb example:git status\n```\n\n#### Syncing Multiple Notebooks with One Remote\n\nMultiple notebooks can be synced to one remote using orphan branches.\nAn\n[orphan branch](https://git-scm.com/docs/git-checkout#Documentation/git-checkout.txt---orphanltnewbranchgt)\nis a branch with a history that is independent\nfrom the repository's `main`, `master`,\nor equivalent primary branch history.\nTo sync a notebook with a new orphan branch,\nadd the remote using [`nb remote set`](#remote)\nand select the option to create a new orphan branch.\nThe name of orphan branch is derived from notebook name\nand can alternatively be specified as an argument to\n[`nb remote set`](#remote):\n\n```bash\n# set the remote for the current notebook to a remote URL and branch\nnb remote set https://github.com/xwmx/example demo-branch\n```\n\nTo create a notebook using an existing orphan branch on a remote,\npass the branch name to\n[`nb init`](#init),\n[`nb notebooks add`](#notebooks), or\n[`nb notebooks init`](#notebooks) after the URL:\n\n```bash\n# initialize new \"home\" notebook with the branch \"sample-branch\" on the remote\nnb init https://github.com/xwmx/example sample-branch\n\n# add a new \"example\" notebook from the branch \"example-branch\" on the remote\nnb notebooks add example https://github.com/xwmx/example example-branch\n```\n\nTo list all branches on a remote, use [`nb remote branches`](#remote):\n\n```bash\n# list all branches on the current remote\nnb remote branches\n\n# list all branches on a remote repository identified by a URL\nnb remote branches \"https://github.com/xwmx/example\"\n```\n\nFor information about assigning remotes, see [`nb help remote`](#remote).\n\n#### Private Repositories and Git Credentials\n\nSyncing with private repositories requires\nconfiguring git to not prompt for credentials.\nFor repositories cloned over HTTPS,\n[credentials can be cached with git\n](https://docs.github.com/en/free-pro-team@latest/github/using-git/caching-your-github-credentials-in-git).\nFor repositories cloned over SSH,\n[keys can be added to the ssh-agent\n](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent).\n\nUse [`nb sync`](#sync) within a notebook to determine\nwhether your configuration is working.\nIf `nb sync` displays a password prompt,\nthen follow the instructions above to configure your credentials.\nThe password prompt can be used to authenticate, but\n`nb` does not cache or otherwise handle git credentials in any way,\nso there will likely be multiple password prompts during each sync\nif credentials are not configured.\n\n#### Sync Conflict Resolution\n\n`nb` handles git operations automatically, so\nyou shouldn't ever need to use the `git` command line tool directly.\n`nb` merges changes when syncing\nand handles conflicts using a couple different strategies.\n\nWhen [`nb sync`](#sync) encounters a conflict in a text file\nand can't cleanly merge overlapping local and remote changes,\n`nb` saves both versions within the file separated by git conflict markers\nand prints a message indicating which files contain conflicting text.\nUse [`nb edit`](#edit) to remove the conflict markers\nand delete any unwanted text.\n\nFor example, in the following file, the second list item was changed\non two systems, and git has no way to determine which one we want to keep:\n\n```\n# Example Title\n\n- List Item apple\n<<<<<<< HEAD\n- List Item apricot\n=======\n- List Item pluot\n>>>>>>> 719od01... [nb] Commit\n- List Item plum\n```\n\nThe local change is between the lines starting with\n`<<<<<<<` and `=======`,\nwhile the remote change is between the\n`=======` and `>>>>>>>`\nlines.\n\nTo resolve this conflict by keeping both items, simply\nedit the file with [`nb edit`](#edit) and\nremove the lines starting with `<<<<<<<`, `=======`, and `>>>>>>>`:\n\n```\n# Example Title\n\n- List Item apple\n- List Item apricot\n- List Item pluot\n- List Item plum\n```\n\nWhen `nb` encounters a conflict in a binary file,\nsuch as an encrypted note,\nboth versions of the file are saved in the notebook as individual files,\nwith `--conflicted-copy` appended to the filename\nof the version from the remote.\nTo resolve a conflicted copy of a binary file,\ncompare both versions and merge them manually,\nthen delete the `--conflicted-copy`.\n\nIf you do encounter a conflict that `nb` says it can't merge at all,\n[`nb git`](#git) and [`nb run`](#run) can be used to\nperform git and shell operations within the notebook\nto resolve the conflict manually.\nPlease also\n[open an issue](https://github.com/xwmx/nb/issues/new)\nwith any relevant details\nthat could inform a strategy for handling any such cases automatically.\n\n### ↕️ Import / Export\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#import\"><code>nb import</code></a>,\n    <a href=\"#export\"><code>nb export</code></a>,\n    <a href=\"#browse\"><code>nb browse</code></a>\n  </sup>\n</p>\n\n#### Importing\n\nFiles of any type can be imported into a notebook using\n[`nb import`](#import) (shortcut: [`nb i`](#import)).\n[`nb edit`](#edit) and [`nb open`](#open) open files in\nyour system's default application for that file type.\n\n```bash\n# import an image file\nnb import ~/Pictures/example.png\n\n# open image in your default image viewer\nnb open example.png\n\n# import a .docx file\nnb import ~/Documents/example.docx\n\n# open .docx file in Word or your system's .docx viewer\nnb open example.docx\n```\n\nMultiple filenames and globbing are supported:\n\n```bash\n# import all files and directories in the current directory\nnb import ./*\n\n# import all markdown files in the current directory\nnb import ./*.md\n\n# import example.md and sample.md in the current directory\nnb import example.md sample.md\n```\n\n[`nb import`](#import) can also download and import files directly from the web:\n\n```bash\n# import a PDF file from the web\nnb import https://example.com/example.pdf\n# Imported \"https://example.com/example.pdf\" to \"example.pdf\"\n\n# open example.pdf in your system's PDF viewer\nnb open example.pdf\n```\n\nSome imported file types have [indicators](#indicators) to make them\neasier to identify in lists:\n\n```bash\n❯ nb\nhome\n----\n[6] 📖 example-ebook.epub\n[5] 🌄 example-picture.png\n[4] 📄 example-document.docx\n[3] 📹 example-video.mp4\n[2] 🔉 example-audio.mp3\n[1] 📂 Example Folder\n```\n\n#### Importing Bookmarks\n\nBookmarks exported from Chrome, Firefox, and Edge can be imported with\n[`nb import bookmarks`](#import). A new `nb` bookmark file is created for\neach bookmark.\n\n#### Exporting\n\nNotes, bookmarks, and other files can be exported using [`nb export`](#export).\nIf [Pandoc](https://pandoc.org/) is installed,\nnotes can be automatically converted to any of the\n[formats supported by Pandoc](https://pandoc.org/MANUAL.html#option--to).\nBy default, the output format is determined by the file extension:\n\n```bash\n# export a Markdown note to a .docx Microsoft Office Word document\nnb export example.md /path/to/example.docx\n\n# export a note titled \"Movies\" to an HTML web page.\nnb export Movies /path/to/example.html\n```\n\nFor more control over the `pandoc` options, use the\n[`nb export pandoc`](#export) subcommand:\n\n```bash\n# export note 42 as an epub with pandoc options\nnb export pandoc 42 --from markdown_strict --to epub -o path/to/example.epub\n```\n\n[`nb export notebook`](#export) and [`nb import notebook`](#import) can be\nused to export and import notebooks:\n\n```bash\n# export global notebook named \"example\" to \"../path/to/destination\"\nnb export notebook example ../path/to/destination\n\n# import notebook or folder at \"../path/to/notebook\"\nnb import notebook ../path/to/notebook\n```\n\n[`nb export notebook`](#export) and [`nb import notebook`](#import)\nbehave like aliases for\n[`nb notebooks export`](#notebooks) and [`nb notebooks import`](#notebooks),\nand the subcommands can be used interchangeably.\n\nFor more information about imported and exported notebooks, see\n[Global and Local Notebooks](#global-and-local-notebooks).\n\nFor [`nb import`](#import) and [`nb export`](#export) help information, see\n[`nb help import`](#import) and [`nb help export`](#export).\n\n#### Exporting with `browse`\n\nItems can be exported using terminal and GUI [web browsers](#-browsing).\nUse the down arrow (`↓`) link\non the [`nb browse`](#browse) item page\nto download the original file:\n\n```bash\n❯ nb browse 123\n❯nb · home : 123 · ↓ | +\n\n    example.pdf\n\n```\n\n### ⚙️ `set` & `settings`\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#-variables\">Variables</a>,\n    <a href=\"#settings\"><code>nb settings</code></a>,\n    <a href=\"#unset\"><code>nb unset</code></a>\n  </sup>\n</p>\n\n[`nb set`](#settings) and [`nb settings`](#settings)\nopen the settings prompt,\nwhich provides an easy way to change your `nb` settings.\n\n```bash\nnb set\n```\n\nTo update a setting in the prompt,\nenter the setting name or number and then enter the new value.\n`nb` will add the setting to your `~/.nbrc` configuration file.\n\n#### Example: editor\n\n`nb` can be configured to use a specific command line editor\nusing the `editor` setting.\n\nThe settings prompt for a setting can be started by passing\nthe setting name or number to [`nb set`](#settings):\n\n```bash\n❯ nb set editor\n[6]  editor\n     ------\n     The command line text editor used by `nb`.\n\n     • Example Values:\n\n         atom\n         code\n         emacs\n         hx\n         macdown\n         mate\n         micro\n         nano\n         pico\n         subl\n         vi\n         vim\n\nEDITOR is currently set to vim\n\nEnter a new value, unset to set to the default value, or q to quit.\nValue:\n```\n\nA setting can also be updated without the prompt by\npassing both the name and value to [`nb set`](#settings):\n\n```bash\n# set editor with setting name\n❯ nb set editor code\nEDITOR set to code\n\n# set editor with setting number (6)\n❯ nb set 6 code\nEDITOR set to code\n\n# set the color theme to blacklight\n❯ nb set color_theme blacklight\nNB_COLOR_THEME set to blacklight\n\n# set the default `ls` limit to 10\n❯ nb set limit 10\nNB_LIMIT set to 10\n```\n\nUse [`nb settings get`](#settings) to print the value of a setting:\n\n```bash\n❯ nb settings get editor\ncode\n\n❯ nb settings get 6\ncode\n```\n\nUse\n[`nb unset`](#unset) or\n[`nb settings unset`](#settings)\nto unset a setting and revert to the default:\n\n```bash\n❯ nb unset editor\nEDITOR restored to the default: vim\n\n❯ nb settings get editor\nvim\n```\n\n[`nb set`](#settings) and [`nb settings`](#settings)\nare aliases that refer to the same subcommand,\nso the two subcommand names can be used interchangeably.\n\nFor more information about [`set`](#settings) and [`settings`](#settings), see\n[`nb help settings`](#settings).\n\n### 🎨 Color Themes\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#color_theme\"><code>nb&nbsp;set&nbsp;color_theme</code></a>,\n    <a href=\"#syntax_theme\"><code>nb&nbsp;set&nbsp;syntax_theme</code></a>,\n    <a href=\"#color_primary\"><code>nb&nbsp;set&nbsp;color_primary</code></a>,\n    <a href=\"#color_secondary\"><code>nb&nbsp;set&nbsp;color_secondary</code></a>\n  </sup>\n</p>\n\n`nb` uses color to highlight various interface elements, including\nids and [selectors](#-selectors),\nthe current notebook name,\nthe shell prompt,\ndivider lines,\n[syntax elements](#terminal-syntax-highlighting-theme),\nand links.\n\n`nb` includes several built-in color themes\nand also supports user-defined themes.\nThe current color theme can be set using [`nb set color_theme`](#color_theme):\n\n```bash\nnb set color_theme\n```\n\n#### Built-in Color Themes\n\n##### `blacklight`\n\n| ![blacklight](https://xwmx.github.io/misc/nb/images/nb-theme-blacklight-home.png) | ![blacklight](https://xwmx.github.io/misc/nb/images/nb-theme-blacklight-web.png)  |\n|:--:|:--:|\n|    |    |\n\n##### `console`\n\n| ![console](https://xwmx.github.io/misc/nb/images/nb-theme-console-home.png)       | ![console](https://xwmx.github.io/misc/nb/images/nb-theme-console-web.png)        |\n|:--:|:--:|\n|    |    |\n\n##### `desert`\n\n| ![desert](https://xwmx.github.io/misc/nb/images/nb-theme-desert-home.png)         | ![desert](https://xwmx.github.io/misc/nb/images/nb-theme-desert-web.png)          |\n|:--:|:--:|\n|    |    |\n\n##### `electro`\n\n| ![electro](https://xwmx.github.io/misc/nb/images/nb-theme-electro-home.png)       | ![electro](https://xwmx.github.io/misc/nb/images/nb-theme-electro-web.png)        |\n|:--:|:--:|\n|    |    |\n\n##### `forest`\n\n| ![forest](https://xwmx.github.io/misc/nb/images/nb-theme-forest-home.png)         | ![forest](https://xwmx.github.io/misc/nb/images/nb-theme-forest-web.png)          |\n|:--:|:--:|\n|    |    |\n\n##### `nb` (default)\n\n| ![nb](https://xwmx.github.io/misc/nb/images/nb-theme-nb-home.png)                 | ![nb](https://xwmx.github.io/misc/nb/images/nb-theme-nb-web.png)                  |\n|:--:|:--:|\n|    |    |\n\n##### `ocean`\n\n| ![ocean](https://xwmx.github.io/misc/nb/images/nb-theme-ocean-home.png)           | ![ocean](https://xwmx.github.io/misc/nb/images/nb-theme-ocean-web.png)            |\n|:--:|:--:|\n|    |    |\n\n##### `raspberry`\n\n| ![raspberry](https://xwmx.github.io/misc/nb/images/nb-theme-raspberry-home.png)   | ![raspberry](https://xwmx.github.io/misc/nb/images/nb-theme-raspberry-web.png)    |\n|:--:|:--:|\n|    |    |\n\n##### `smoke`\n\n| ![smoke](https://xwmx.github.io/misc/nb/images/nb-theme-monochrome-home.png)      | ![smoke](https://xwmx.github.io/misc/nb/images/nb-theme-smoke-web.png)            |\n|:--:|:--:|\n|    |    |\n\n##### `unicorn`\n\n| ![unicorn](https://xwmx.github.io/misc/nb/images/nb-theme-unicorn-home.png)       | ![unicorn](https://xwmx.github.io/misc/nb/images/nb-theme-unicorn-web.png)        |\n|:--:|:--:|\n|    |    |\n\n##### `utility`\n\n| ![utility](https://xwmx.github.io/misc/nb/images/nb-theme-utility-home.png)       | ![utility](https://xwmx.github.io/misc/nb/images/nb-theme-utility-web.png)        |\n|:--:|:--:|\n|    |    |\n\n#### Custom Color Themes\n\nColor themes are\n[`nb` plugins](#-plugins) with a `.nb-theme` file extension.\n`.nb-theme` files are expected to contain one `if` statement\ntesting for the theme name\nand setting the color environment variables to `tput` ANSI color numbers:\n\n```bash\n# turquoise.nb-theme\nif [[ \"${NB_COLOR_THEME}\" == \"turquoise\" ]]\nthen\n  export NB_COLOR_PRIMARY=43\n  export NB_COLOR_SECONDARY=38\nfi\n```\n\nView this theme as a complete file:\n[`plugins/turquoise.nb-theme`](https://github.com/xwmx/nb/blob/master/plugins/turquoise.nb-theme)\n\nThemes can be installed using [`nb plugins`](#plugins):\n\n```bash\n❯ nb plugins install https://github.com/xwmx/nb/blob/master/plugins/turquoise.nb-theme\nPlugin installed:\n/home/example/.nb/.plugins/turquoise.nb-theme\n```\n\nOnce a theme is installed,\nuse [`nb set color_theme`](#color_theme) to set it as the current theme:\n\n```bash\n❯ nb set color_theme turquoise\nNB_COLOR_THEME set to turquoise\n```\n\nThe primary and secondary colors can also be overridden individually,\nmaking color themes easily customizable:\n\n```bash\n# open the settings prompt for the primary color\nnb set color_primary\n\n# open the settings prompt for the secondary color\nnb set color_secondary\n```\n\nTo view a table of available colors and numbers, run:\n\n```bash\nnb set colors\n```\n\n#### Terminal Syntax Highlighting Theme\n\n`nb` displays files with syntax highlighting when\n[`bat`](https://github.com/sharkdp/bat),\n[`highlight`](http://www.andre-simon.de/doku/highlight/en/highlight.php),\nor\n[Pygments](https://pygments.org/)\nis installed.\n\nWhen `bat` is installed, syntax highlighting\ncolor themes are available for both light and dark terminal backgrounds.\nTo view a list of available themes\nand set the syntax highlighting color theme,\nuse [`nb set syntax_theme`](#syntax_theme).\n\n#### GUI Web Syntax Highlighting\n\nSyntax highlighting is also available when\nviewing and editing items in text formats with\n[`nb browse --gui`](#browse---gui),\nwhich incorporates the color theme's primary color into the syntax theme:\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/nb-web-pandoc-ruby-utility.png\"\n        alt=\"nb syntax highlighting\"\n        width=\"500\">\n</div>\n\n#### Indicators\n\n`nb` uses emoji characters to represent information about files in lists.\nThese characters are referred to internally as \"indicators\"\nand can be customized by assigning a different character to\nthe indicator's environment variable in your `~/.nbrc` file,\nwhich can be opened with [`nb settings edit`](#settings).\n\nFor example, to use a different indicator for pinned items,\nadd a line like the following to your `~/.nbrc` file:\n\n```bash\nexport NB_INDICATOR_PINNED=\"✨\"\n```\n\nTo turn off an indicator, assign the variable to an empty string:\n\n```bash\nexport NB_INDICATOR_PINNED=\"\"\n```\n\nAvailable indicator [variables](#-variables) with default values:\n\n```bash\nexport  NB_INDICATOR_AUDIO=\"🔉\"\nexport  NB_INDICATOR_BOOKMARK=\"🔖\"\nexport  NB_INDICATOR_DOCUMENT=\"📄\"\nexport  NB_INDICATOR_EBOOK=\"📖\"\nexport  NB_INDICATOR_ENCRYPTED=\"🔒\"\nexport  NB_INDICATOR_FOLDER=\"📂\"\nexport  NB_INDICATOR_IMAGE=\"🌄\"\nexport  NB_INDICATOR_PINNED=\"📌\"\nexport  NB_INDICATOR_TODO=\"✔️ \"\nexport  NB_INDICATOR_TODO_DONE=\"✅\"\nexport  NB_INDICATOR_VIDEO=\"📹\"\n```\n\n### $ Shell Theme Support\n\n- [`astral` Zsh Theme](https://github.com/xwmx/astral) - Displays the\n    current notebook name in the context line of the prompt.\n\n### 🔌 Plugins\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#plugin-help\">Plugin Help</a>,\n    <a href=\"#plugins\"><code>nb plugins</code></a>\n  </sup>\n</p>\n\n`nb` includes support for plugins, which can be used to create new\nsubcommands, design themes, and otherwise extend the functionality of `nb`.\n\n`nb` supports two types of plugins, identified by their file extensions:\n\n<dl>\n  <dt><code>.nb-theme</code></dt>\n  <dd>Plugins defining <a href=\"#custom-color-themes\">color themes</a>.</dd>\n  <dt><code>.nb-plugin</code></dt>\n  <dd>Plugins defining new subcommands and adding functionality.</dd>\n</dl>\n\nPlugins are managed with the [`nb plugins`](#plugins) subcommand and\nare installed in the `${NB_DIR}/.plugins` directory.\n\nPlugins can be installed from either a URL or a path using the\n[`nb plugins install`](#plugins) subcommand.\n\n```bash\n# install a plugin from a URL\nnb plugins install https://raw.githubusercontent.com/xwmx/nb/master/plugins/clip.nb-plugin\n\n# install a plugin from a standard GitHub URL\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/example.nb-plugin\n\n# install a theme from a standard GitHub URL\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/turquoise.nb-theme\n\n# install a plugin from a path\nnb plugins install plugins/example.nb-plugin\n```\n\nThe `<url>` should be the full URL to the plugin file.\n`nb` also recognizes regular GitHub URLs,\nwhich can be used interchangeably with raw GitHub URLs.\n\nInstalled plugins can be listed with [`nb plugins`](#plugins),\nwhich optionally takes a name and prints full paths:\n\n```bash\n❯ nb plugins\nclip.nb-plugin\nexample.nb-plugin\nturquoise.nb-theme\n\n❯ nb plugins clip.nb-plugin\nclip.nb-plugin\n\n❯ nb plugins --paths\n/home/example/.nb/.plugins/clip.nb-plugin\n/home/example/.nb/.plugins/example.nb-plugin\n/home/example/.nb/.plugins/turquoise.nb-theme\n\n❯ nb plugins turquoise.nb-theme --paths\n/home/example/.nb/.plugins/turquoise.nb-theme\n```\n\nUse [`nb plugins uninstall`](#plugins) to uninstall a plugin:\n\n```bash\n❯ nb plugins uninstall example.nb-plugin\nPlugin successfully uninstalled:\n/home/example/.nb/.plugins/example.nb-plugin\n```\n\n#### Creating Plugins\n\nPlugins are written in a Bash-compatible shell scripting language\nand have an `.nb-plugin` extension.\n\n`nb` includes a few example plugins:\n\n- [`example.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/example.nb-plugin)\n- [`clip.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/clip.nb-plugin)\n- [`ebook.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/ebook.nb-plugin)\n\nCreate a new subcommand in three easy steps:\n\n##### 1. Add the new subcommand name with `_subcommands add <name>`:\n\n```bash\n_subcommands add \"example\"\n```\n\n##### 2. Define help and usage text with `_subcommands describe <subcommand> <usage>`:\n\n```bash\n_subcommands describe \"example\" <<HEREDOC\nUsage:\n  nb example\n\nDescription:\n  Print \"Hello, World!\"\nHEREDOC\n```\n\n##### 3. Define the subcommand as a function, named with a leading underscore:\n\n```bash\n_example() {\n  printf \"Hello, World!\\\\n\"\n}\n```\n\nThat's it! 🎉\n\nView the complete plugin:\n[`plugins/example.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/example.nb-plugin)\n\nWith `example.nb-plugin` installed, `nb` includes an `nb example` subcommand\nthat prints \"Hello, World!\"\n\nFor a full example,\n[`clip.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/clip.nb-plugin)\nadd clipboard functionality to `nb` and demonstrates how to create a\nplugin using `nb` subcommands and simple shell scripting.\n\nYou can install any plugin you create locally with\n[`nb plugins install <path>`](#plugins),\nand you can publish it on GitHub, GitLab,\nor anywhere else online and install it with\n[`nb plugins install <url>`](#plugins).\n\n#### API\n\nThe `nb` API is the [command line interface](#nb-help), which is designed for\ncomposability and provides a variety of powerful options for interacting with\nnotes, bookmarks, notebooks, and `nb` functionality. Within plugins,\nsubcommands can be called using their function names, which are named with\nleading underscores. Options can be used to output information in formats\nsuitable for parsing and processing:\n\n```bash\n# print the content of note 3 to standard output with no color\n_show 3 --print --no-color\n\n# list all unarchived global notebook names\n_notebooks --names --no-color --unarchived --global\n\n# list all filenames in the current notebook\n_list --filenames --no-id --no-indicator\n\n# print the path to the current notebook\n_notebooks current --path\n```\n\n`nb` automatically scans arguments for\n[selectors](#-selectors) with notebook names\nand updates the current notebook if a valid one is found.\n\nIdentifier selectors are passed to subcommands as arguments along with\nany subcommand options. Use [`show <selector>`](#show) to query\ninformation about the file specified in the selector. For example, to\nobtain the filename of a selector-specified file, use\n[`show <selector> --filename`](#show):\n\n```bash\n_example() {\n  local _selector=\"${1:-}\"\n  [[ -z \"${_selector:-}\" ]] && printf \"Usage: example <selector>\\\\n\" && exit 1\n\n  # Get the filename using the selector.\n  local _filename=\n  _filename=\"$(_show \"${_selector}\" --filename)\"\n\n  # Rest of subcommand function...\n}\n```\n\n[`notebooks current --path`](#notebooks) returns the path to the current\nnotebook:\n\n```bash\n# _example() continued:\n\n# get the notebook path\nlocal _notebook_path=\n_notebook_path=\"$(_notebooks current --path)\"\n\n# print the file at \"${_notebook_path}/${_filename}\" to standard output\ncat \"${_notebook_path}/${_filename}\"\n```\n\nSee\n[`clip.nb-plugin`](https://github.com/xwmx/nb/blob/master/plugins/clip.nb-plugin)\nfor a practical example using both [`show <selector>`](#show) and\n[`notebooks current --path`](#notebooks) along with other\nsubcommands called using their underscore-prefixed function names.\n\n### `:/` Selectors\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a>\n  </sup>\n</p>\n\nItems in `nb` are primarily identified using structured arguments called\n\"selectors.\" Selectors are like addresses for notebooks, folders, and items.\nA selector can be as simple as an id like `123` or folder path like `example/`,\nor it can combine multiple elements to identify\nan item in a nested folder within a particular notebook, such as:\n\n```bash\ncli:tools/shellcheck/home-page.bookmark.md\n```\n\nAn item, folder, or notebook selector is constructed by specifying the\nnotebook name, folder path, and / or item identifier\nin the following pattern:\n\n```text\nnotebook:folder/path/item-idenitifer\n```\n\nRepresented in a [docopt](http://docopt.org/)-like format:\n\n```text\n[<notebook>:][<folder-path>/][<id> | <filename> | <title>]\n```\n\nNotebooks are identified by the notebook name followed by a colon.\nFolder and item identifiers without a notebook name refer to\nitems within the current notebook.\nWhen a selector consists of notebook name and colon\nwith no folder path or item identifier,\nthe command runs in the root folder of the notebook:\n\n```bash\n# list items in the \"example\" notebook\nnb example:\n\n# add a new note named \"Example Title\" to the \"example\" notebook\nnb add example: --title \"Example Title\"\n\n# edit item with id \"123\" in the notebook \"example\"\nnb edit example:123\n```\n\nA notebook selector can be combined with a subcommand name to\nrun the command within the notebook:\n\n```bash\n# list all items in the \"example\" notebook and display excerpts\nnb example:list -e\n\n# edit item with id \"123\" in the \"example\" notebook\nnb example:edit 123\n\n# show the git history for the notebook named \"example\"\nnb example:history\n```\n\nFolders are identified by relative path from the notebook root.\nFolders can be referenced by either id or name, and segments\nin nested paths can mix and match names and ids:\n\n```bash\n# list items in the folder named \"sample\" in the folder named demo\"\nnb sample/demo/\n\n# add a new item to the folder named \"demo\" in the folder with id \"3\"\nnb add 3/demo/\n\n# show the history of the folder with id \"4\" in the folder named\n# \"sample\" in the notebook named \"example\"\nnb history example:sample/4/\n```\n\nA trailing slash indicates that the command is expected to operate on\nthe contents of the folder. When a trailing slash is omitted, the\nselector refers to the folder itself:\n\n```bash\n❯ nb list sample\n[1] 📂 sample\n\n❯ nb list sample/\n[sample/3] Title Three\n[sample/2] Title Two\n[sample/1] Title One\n```\n\nFor more information about folders, see [Folders](#-folders).\n\nAn item is identified by id, filename, or title, optionally preceded by\nnotebook name or folder path:\n\n```bash\n# edit item with id \"123\"\nnb edit 123\n\n# open the item titled \"demo title\" in the folder with id \"3\"\nnb open 3/demo\\ title\n\n# show \"file.md\" in the \"sample\" folder in the \"example\" notebook\nnb show example:sample/file.md\n```\n\nItems can also be specified using the full path:\n\n```bash\n# edit \"demo.md\" in the \"sample\" folder in the \"home\" notebook\nnb edit /home/example/.nb/home/sample/demo.md\n```\n\n##### Examples\n\n*Idenitifer Selectors*\n\n```text\n123\nexample.md\ntitle\nrelative/path/to/123\nrelative/path/to/demo.md\nrelative/path/to/title\n/full/path/to/sample.md\nnotebook:123\nnotebook:example.md\nnotebook:title\nnotebook:relative/path/to/123\nnotebook:relative/path/to/demo.md\nnotebook:relative/path/to/title\n```\n\n*Subcommand Selectors*\n\n```text\nnotebook:\nnotebook:show\nnotebook:history\nnotebook:a\nnotebook:q\n```\n\n### `01` Metadata\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#show\"><code>nb show</code></a>\n  </sup>\n</p>\n\nMetadata in `nb` is primarily derived from git, the filesystem, and file\ncontent. For example, displayed timestamps are derived from\n[`git log`](https://git-scm.com/docs/git-log), with [`nb show --added`](#show)\ndisplaying the datetime of the first commit containing the file and\n[`nb show --updated`](#show) displaying the datetime of the last commit in\nwhich the file was modified. Meanwhile, the file system's modified\ntimestamp is used for sorting.\n\n`nb` also uses plain text files to store ids and state information in\ngit, including\n[`.index` files](#index-files),\n[`.pindex` files](#pindex-files),\nand [`.archived` files](#archived-notebooks).\n\n#### Front Matter\n\nUser-defined metadata can be added to notes in `nb` using [front\nmatter](https://jekyllrb.com/docs/front-matter/). Front matter is a\nsimple, human accessible, and future-friendly method for defining metadata\nfields in plain text and is well supported in tools for working with\nMarkdown.\n\nFront matter is defined within a Markdown file with triple-dashed lines\n(`---`) indicating the start and end of the block, with each field represented\nby a key name with a colon followed by the value:\n\n```markdown\n---\ntitle:  Example Title\nauthor: xwmx\nyear:   2021\n---\n\nExample content.\n\nMore example content:\n\n- one\n- two\n- three\n```\n\nAny metadata can be placed in the front matter block. `nb` uses the\n`title:` field for listing, filtering, and selecting items, if one is\npresent, and ignores any other fields.\n\nThe simple `key: value` syntax is suitable for many metadata fields.\nMore complex data can be defined using additional\n[YAML](https://en.wikipedia.org/wiki/YAML)\ncapabilities.\n\n### `❯` Interactive Shell\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#shell\"><code>nb shell</code></a>\n  </sup>\n</p>\n\n`nb` has an interactive shell that can be started with\n[`nb shell`](#shell), [`nb -i`](#nb-help), or [`nb --interactive`](#nb-help):\n\n```bash\n$ nb shell\n__          _\n\\ \\   _ __ | |__\n \\ \\ | '_ \\| '_ \\\n / / | | | | |_) |\n/_/  |_| |_|_.__/\n------------------\nnb shell started. Enter ls to list notes and notebooks.\nEnter help for usage information. Enter exit to exit.\nnb❯ ls\nhome\n----\n[3] Example\n[2] Sample\n[1] Demo\n\nnb❯ edit 3 --content \"New content.\"\nUpdated: [3] Example\n\nnb❯ bookmark https://example.com\nAdded: [4] 🔖 example.bookmark.md \"Example Title (example.com)\"\n\nnb❯ ls\nhome\n----\n[4] 🔖 Example Title (example.com)\n[3] Example\n[2] Sample\n[1] Demo\n\nnb❯ bookmark url 4\nhttps://example.com\n\nnb❯ search \"example\"\n[4] example.bookmark.md \"Example (example.com)\"\n-----------------------------------------------\n1:# Example (example.com)\n\n3:<https://example.com>\n\n[3] example.md \"Example\"\n------------------------\n1:# Example\n\nnb❯ exit\n$\n```\n\nThe `nb` shell recognizes all `nb` subcommands and options,\nproviding a streamlined, distraction-free approach for working with `nb`.\n\n### Shortcut Aliases\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a>\n  </sup>\n</p>\n\nSeveral core `nb` subcommands have shortcut aliases to make\nthem faster to work with:\n\n```bash\n# `a` (add): add a new note named \"example.md\"\nnb a example.md\n\n# `+` (add): add a new note titled \"Example Title\"\nnb + --title \"Example Title\"\n\n# `b` (browse): open the folder named \"sample\" in the web browser\nnb b sample/\n\n# `o` (open): open the URL from bookmark 12 in your web browser\nnb o 12\n\n# `p` (peek): open the URL from bookmark 6 in your terminal browser\nnb p 6\n\n# `e` (edit): edit note 5\nnb e 5\n\n# `d` (delete): delete note 19\nnb d 19\n\n# `d` (delete): delete note 123 in the notebook named \"example:\"\nnb - example:123\n\n# `s` (show): show note 27\nnb s 27\n\n# `q` (search): search notes for \"example query\"\nnb q \"example query\"\n\n# `h` (help): display the help information for the `add` subcommand\nnb h add\n\n# `u` (use): switch to example-notebook\nnb u example-notebook\n```\n\nFor more commands and options, run\n[`nb help`](#nb-help) or\n[`nb help <subcommand>`](#subcommands)\n\n<div align=\"center\">\n  <img  src=\"https://xwmx.github.io/misc/nb/images/gui-browse-themes.png\"\n        alt=\"nb browse themes\"\n        width=\"700\">\n</div>\n\n### `?` Help\n\n<div align=\"center\">\n  <a href=\"#nb-help\">nb</a>&nbsp;·\n  <a href=\"#bookmark-help\">bookmark</a>&nbsp;·\n  <a href=\"#subcommands\">subcommands</a>&nbsp;·\n  <a href=\"#plugin-help\">plugins</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#add\">add</a>&nbsp;·\n  <a href=\"#archive\">archive</a>&nbsp;·\n  <a href=\"#bookmark\">bookmark</a>&nbsp;·\n  <a href=\"#browse\">browse</a>&nbsp;·\n  <a href=\"#completions\">completions</a>&nbsp;·\n  <a href=\"#copy\">copy</a>&nbsp;·\n  <a href=\"#count\">count</a>&nbsp;·\n  <a href=\"#delete\">delete</a>&nbsp;·\n  <a href=\"#do\">do</a>&nbsp;·\n  <a href=\"#edit\">edit</a>&nbsp;·\n  <a href=\"#env\">env</a>&nbsp;·\n  <a href=\"#export\">export</a>&nbsp;·\n  <a href=\"#folders\">folders</a>&nbsp;·\n  <a href=\"#git\">git</a>&nbsp;·\n  <a href=\"#help\">help</a>&nbsp;·\n  <a href=\"#history\">history</a>&nbsp;·\n  <a href=\"#import\">import</a>&nbsp;·\n  <a href=\"#init\">init</a>&nbsp;·\n  <a href=\"#list\">list</a>&nbsp;·\n  <a href=\"#ls\">ls</a>&nbsp;·\n  <a href=\"#move\">move</a>&nbsp;·\n  <a href=\"#notebooks\">notebooks</a>&nbsp;·\n  <a href=\"#open\">open</a>&nbsp;·\n  <a href=\"#peek\">peek</a>&nbsp;·\n  <a href=\"#pin\">pin</a>&nbsp;·\n  <a href=\"#plugins\">plugins</a>&nbsp;·\n  <a href=\"#remote\">remote</a>&nbsp;·\n  <a href=\"#run\">run</a>&nbsp;·\n  <a href=\"#search\">search</a>&nbsp;·\n  <a href=\"#settings\">settings</a>&nbsp;·\n  <a href=\"#shell\">shell</a>&nbsp;·\n  <a href=\"#show\">show</a>&nbsp;·\n  <a href=\"#status\">status</a>&nbsp;·\n  <a href=\"#subcommands-1\">subcommands</a>&nbsp;·\n  <a href=\"#sync\">sync</a>&nbsp;·\n  <a href=\"#tasks\">tasks</a>&nbsp;·\n  <a href=\"#todo\">todo</a>&nbsp;·\n  <a href=\"#unarchive\">unarchive</a>&nbsp;·\n  <a href=\"#undo\">undo</a>&nbsp;·\n  <a href=\"#unpin\">unpin</a>&nbsp;·\n  <a href=\"#unset\">unset</a>&nbsp;·\n  <a href=\"#update\">update</a>&nbsp;·\n  <a href=\"#use\">use</a>&nbsp;·\n  <a href=\"#version\">version</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#overview\">&nbsp;↑&nbsp;</a>\n</div>\n\n#### `nb help`\n\n[↑](#-help) · See also:\n[`help`](#help)\n\n```text\n__          _\n\\ \\   _ __ | |__\n \\ \\ | '_ \\| '_ \\\n / / | | | | |_) |\n/_/  |_| |_|_.__/\n\n[nb] Command line and local web note-taking, bookmarking, and archiving with\nplain text data storage, encryption, filtering and search, pinning, #tagging,\nGit-backed versioning and syncing, Pandoc-backed conversion, global and local\nnotebooks, customizable color themes, [[wiki-style linking]], plugins, and more\nin a single portable, user-friendly script.\n\nHelp:\n  nb help               Display this help information.\n  nb help <subcommand>  View help information for <subcommand>.\n  nb help --colors      View information about color settings.\n  nb help --readme      View the `nb` README file.\n\nUsage:\n  nb\n  nb [<ls-options>...] [<id> | <filename> | <path> | <title> | <notebook>]\n  nb [<url>] [<bookmark options>...]\n  nb add [<notebook>:][<folder-path>/][<filename>] [<content>]\n         [-b | --browse] [-c <content> | --content <content>] [--edit]\n         [-e | --encrypt] [-f <filename> | --filename <filename>]\n         [--folder <folder-path>] [--no-template] [--tags <tag1>,<tag2>...]\n         [--template <template>] [-t <title> | --title <title>] [--type <type>]\n  nb add bookmark [<bookmark-options>...]\n  nb add folder [<name>]\n  nb add todo [<todo-options>...]\n  nb archive [<notebook>]\n  nb bookmark [<ls-options>...]\n  nb bookmark [<notebook>:][<folder-path>/] <url>...\n              [-c <comment> | --comment <comment>] [--edit] [-e | --encrypt]\n              [-f <filename> | --filename <filename>] [--no-request]\n              [-q <quote> | --quote <quote>] [--save-source]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]...\n              [-t <tag1>,<tag2>... | --tags <tag1>,<tag2>...] [--title <title>]\n  nb bookmark [list [<list-options>...]]\n  nb bookmark (open | peek | url) (<id> | <filename> | <path> | <title>)\n  nb bookmark (edit | delete) (<id> | <filename> | <path> | <title>)\n  nb bookmark search <query>\n  nb browse [<notebook>:][<folder-path>/][<id> | <filename> | <title>] [--daemon]\n            [-g | --gui] [-n | --notebooks] [-p | --print] [-q | --query <query>]\n            [-s | --serve] [-t <tag> | --tag <tag> | --tags <tag1>,<tag2>...]\n  nb browse add [<notebook>:][<folder-path>/][<filename>]\n            [-c <content> | --content <content>] [--tags <tag1>,<tag2>...]\n            [-t <title> | --title <title>]\n  nb browse delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb browse edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb completions (check | install [-d | --download] | uninstall)\n  nb copy ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[<notebook>:][<folder-path>/]<filename>]\n  nb count [<notebook>:][<folder-path>/]\n  nb delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])...\n            [-f | --force]\n  nb do ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n        [<task-number>]\n  nb edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [-c <content> | --content <content>] [--edit]\n          [-e <editor> | --editor <editor>] [-l | --last] [--overwrite]\n          [--prepend]\n  nb env [-l | --long]\n  nb env [install | update] [--ace | --mathjax]\n  nb export ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <path> [-f | --force] [<pandoc options>...]\n  nb export notebook <name> [<path>]\n  nb export pandoc ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            [<pandoc options>...]\n  nb folders (add | delete) [<notebook>:][<folder-path>/]<folder-name>\n  nb folders <list-options>...\n  nb git [checkpoint [<message>] | dirty]\n  nb git <git-options>...\n  nb help [<subcommand>] [-p | --print]\n  nb help [-c | --colors] | [-r | --readme] | [-s | --short] [-p | --print]\n  nb history [<notebook>:][<folder-path>/][<id> | <filename> | <title>]\n  nb import [bookmarks | copy | download | move] (<path>... | <url>)\n            [--convert] [<notebook>:][<folder-path>/][<filename>]\n  nb import notebook <path> [<name>]\n  nb init [<remote-url> [<branch>]] [--author] [--email <email>]\n          [--name <name>]\n  nb list [-e [<length>] | --excerpt [<length>]] [--filenames]\n          [-f | --folders-first] [-n <limit> | --limit <limit> | --<limit>]\n          [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n          [--paths] [-s | --sort] [-r | --reverse] [--tags]\n          [-t <type> | --type <type> | --<type>]\n          [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n  nb ls [-a | --all] [-b | --browse] [-e [<length>] | --excerpt [<length>]]\n        [--filenames] [-f | --folders-first] [-g | --gui]\n        [-n <limit> | --limit <limit> | --<limit>] [--no-footer] [--no-header]\n        [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n        [--paths] [-s | --sort] [-r | --reverse] [--tags]\n        [-t <type> | --type <type> | --<type>]\n        [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n  nb move ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          ([<notebook>:][<path>] | --reset | --to-bookmark | --to-note |\n          --to-title | --to-todo) [-f | --force]\n  nb notebooks [<name> | <query>] [--ar | --archived] [--global] [--local]\n               [--names] [--paths] [--unar | --unarchived]\n  nb notebooks add ([<name>] [<remote-url> [<branch>... | --all]]) [--author]\n                   [--email <email>] [--name <name>]\n  nb notebooks (archive | open | peek | status | unarchive) [<name>]\n  nb notebooks author [<name> | <path>] [--email <email>] [--name <name>]\n  nb notebooks current [--path | --selected | --filename [<filename>]]\n                       [--global | --local]\n  nb notebooks delete <name> [-f | --force]\n  nb notebooks (export <name> [<path>] | import <path>)\n  nb notebooks init [<path> [<remote-url> [<branch>]]] [--author]\n                    [--email <email>] [--name <name>]\n  nb notebooks rename <old-name> <new-name>\n  nb notebooks select <selector>\n  nb notebooks show (<name> | <path> | <selector>) [--ar | --archived]\n                    [--escaped | --name | --path | --filename [<filename>]]\n  nb notebooks use <name>\n  nb open ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb peek ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb pin  ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb plugins [<name>] [--paths]\n  nb plugins install [<path> | <url>] [--force]\n  nb plugins uninstall <name> [--force]\n  nb remote [branches [<url>] | remove | rename [<branch-name>] <name>]\n  nb remote [delete <branch-name> | reset <branch-name>]\n  nb remote set <url> [<branch-name>]\n  nb run <command> [<arguments>...]\n  nb search ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <query>... [-a | --all] [--and <query>] [--not <query>] [--or <query>]\n            [-l | --list] [--path] [-t <tag1>,<tag2>... | --tag <tag1>,<tag2>...]\n            [-t | --tags] [--type <type> | --<type>] [--utility <name>]\n  nb set [<name> [<value>] | <number> [<value>]]\n  nb settings [colors [<number> | themes] | edit | list [--long]]\n  nb settings (get | show | unset) (<name> | <number>)\n  nb settings set (<name> | <number>) <value>\n  nb shell [<subcommand> [<options>...] | --clear-history]\n  nb show ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[-a | --added] | [--authors] | [-b | --browse] | --filename | --id |\n          --info-line | --path | [-p | --print] | --relative-path | [-r |\n          --render] | --title | --type [<type>] | [-u | --updated]] [--no-color]\n  nb show <notebook>\n  nb status [<notebook>]\n  nb subcommands [add <name>...] [alias <name> <alias>]\n                 [describe <name> <usage>]\n  nb sync [-a | --all]\n  nb tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n           [open | closed]\n  nb todo add [<notebook>:][<folder-path>/][<filename>] <title>\n              [--description <description>] [--due <date>]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]\n              [--tags <tag1>,<tag2>...] [--task <title>...]\n  nb todo do   ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  nb todo undo ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  nb todos [<notebook>:][<folder-path>/] [open | closed] [--pager]\n               [--tags <tag1>,<tag2>...]\n  nb todos tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n                 [open | closed] [--pager]\n  nb unarchive [<notebook>]\n  nb undo ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [<task-number>]\n  nb unpin ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb unset (<name> | <number>)\n  nb update\n  nb use <notebook>\n  nb -h | --help | help [<subcommand> | --readme]\n  nb -i | --interactive [<subcommand> [<options>...]]\n  nb --no-color\n  nb --version | version\n\nSubcommands:\n  (default)    List notes and notebooks. This is an alias for `nb ls`.\n               When a <url> is provided, create a new bookmark.\n  add          Add a note, folder, or file.\n  archive      Archive the current or specified notebook.\n  bookmark     Add, open, list, and search bookmarks.\n  browse       Browse and manage linked items in terminal and GUI web browsers.\n  completions  Install and uninstall completion scripts.\n  copy         Copy or duplicate an item.\n  count        Print the number of items in a notebook or folder.\n  delete       Delete a note.\n  do           Mark a todo or task as done.\n  edit         Edit a note.\n  env          Print environment information and install dependencies.\n  export       Export a note to a variety of different formats.\n  folders      Add, delete, and list folders.\n  git          Run `git` commands within the current notebook.\n  help         View help information for the program or a subcommand.\n  history      View git history for the current notebook or a note.\n  import       Import a file into the current notebook.\n  init         Initialize the first notebook.\n  list         List notes in the current notebook.\n  ls           List notebooks and notes in the current notebook.\n  move         Move or rename a note.\n  notebooks    Manage notebooks.\n  open         Open a bookmarked web page or notebook folder, or edit a note.\n  peek         View a note, bookmarked web page, or notebook in the terminal.\n  pin          Pin an item so it appears first in lists.\n  plugins      Install and uninstall plugins and themes.\n  remote       Configure the remote URL and branch for the notebook.\n  run          Run shell commands within the current notebook.\n  search       Search notes.\n  settings     Edit configuration settings.\n  shell        Start the `nb` interactive shell.\n  show         Show a note or notebook.\n  status       Run `git status` in the current notebook.\n  subcommands  List, add, alias, and describe subcommands.\n  status       Print notebook status information.\n  sync         Sync local notebook with the remote repository.\n  tasks        List tasks in todos, notebooks, folders, and other items.\n  todo         Manage todos and tasks.\n  unarchive    Unarchive the current or specified notebook.\n  undo         Mark a todo or task as not done.\n  unpin        Unpin a pinned item.\n  unset        Return a setting to its default value.\n  update       Update `nb` to the latest version.\n  use          Switch to a notebook.\n  version      Display version information.\n\nNotebook Usage:\n  nb <notebook>:[<subcommand>] [<identifier>] [<options>...]\n  nb <subcommand> <notebook>:<identifier> [<options>...]\n\nProgram Options:\n  -h, --help          Display this help information.\n  -i, --interactive   Start the `nb` interactive shell.\n  --no-color          Print without color highlighting.\n  --version           Display version information.\n\nMore Information:\n  https://github.com/xwmx/nb\n```\n\n#### `bookmark help`\n\n[↑](#-help) · See also:\n[Bookmarks](#-bookmarks),\n[`bookmark`](#bookmark),\n[`browse`](#browse)\n\n```text\n    __                __                        __\n   / /_  ____  ____  / /______ ___  ____ ______/ /__\n  / __ \\/ __ \\/ __ \\/ //_/ __ `__ \\/ __ `/ ___/ //_/\n / /_/ / /_/ / /_/ / ,< / / / / / / /_/ / /  / ,<\n/_.___/\\____/\\____/_/|_/_/ /_/ /_/\\__,_/_/  /_/|_|\n\nbookmark -- Command line bookmarking with tagging, encryption,\nfull-text page content search with regular expression support,\nGUI and terminal browser support, and data stored in plain text\nMarkdown files with Git-backed versioning and syncing.\n\nUsage:\n  bookmark [<ls-options>...]\n  bookmark [<notebook>:][<folder-path>] <url>\n              [-c <comment> | --comment <comment>] [--edit] [-e | --encrypt]\n              [-f <filename> | --filename <filename>] [--no-request]\n              [-q <quote> | --quote <quote>] [--save-source]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]...\n              [-t <tag1>,<tag2>... | --tags <tag1>,<tag2>...] [--title <title>]\n  bookmark (edit | delete | open | peek | url)\n              ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  bookmark search <query>\n\nOptions:\n  -c, --comment <comment>      A comment or description for this bookmark.\n  --edit                       Open the bookmark in your editor before saving.\n  -e, --encrypt                Encrypt the bookmark with a password.\n  -f, --filename <filename>    The filename for the bookmark. It is\n                               recommended to omit the extension so the\n                               default bookmark extension is used.\n  --no-request                 Don't request or download the target page.\n  -q, --quote <quote>          A quote or excerpt from the saved page.\n                               Alias: `--excerpt`\n  -r, --related <selector>     A selector for an item related to the\n                               bookmarked page.\n  -r, --related <url>          A URL for a page related to the bookmarked page.\n                               Multiple `--related` flags can be used in a\n                               command to save multiple related URLs.\n  --save-source                Save the page source as HTML.\n  -t, --tags <tag1>,<tag2>...  A comma-separated list of tags.\n  --title <title>              The bookmark title. When not specified,\n                               `nb` will use the html <title> tag.\n\nSubcommands:\n  (default)  Add a new bookmark for <url>, or list bookmarks.\n             Bookmarks can also be added with `nb <url>`\n  delete     Delete a bookmark.\n  edit       Edit a bookmark.\n  list       List bookmarks in the current notebook.\n             Shortcut Alias: `ls`\n  open       Open the bookmarked page in your system's primary web browser.\n             Shortcut Alias: `o`\n  peek       Open the bookmarked page in your terminal web browser.\n             Alias: `preview`\n             Shortcut Alias: `p`\n  search     Search bookmarks for <query>.\n             Shortcut Alias: `q`\n  url        Print the URL for the specified bookmark.\n\nDescription:\n  Create, view, search, edit, and delete bookmarks.\n\n  By default, the html page content is saved within the bookmark, making the\n  bookmarked page available for full-text search. When Pandoc [1] is\n  installed, the HTML content is converted to Markdown before saving.\n  When readability-cli [2] is install, markup is cleaned up to focus on\n  content.\n\n  `peek` opens the page in `w3m` [3] or `links` [4] when available.\n  To specify a preferred browser, set the `$BROWSER` environment variable\n  in your .bashrc, .zshrc, or equivalent, e.g.: export BROWSER=\"lynx\"\n\n  Bookmarks are identified by the `.bookmark.md` file extension. The\n  bookmark URL is the first URL in the file within \"<\" and \">\" characters:\n\n    <https://www.example.com>\n\n    1. https://pandoc.org/\n    2. https://gitlab.com/gardenappl/readability-cli\n    3. https://en.wikipedia.org/wiki/W3m\n    4. https://en.wikipedia.org/wiki/Links_(web_browser)\n\nRead More:\n  https://github.com/xwmx/nb#-bookmarks\n\nSee Also:\n  nb help browse\n  nb help open\n  nb help peek\n  nb help show\n\nExamples:\n  bookmark https://example.com\n  bookmark https://example.com --encrypt\n  bookmark https://example.com --tags example,sample,demo\n  bookmark https://example.com/about -c \"Example comment.\"\n  bookmark https://example.com/faqs -f example-filename\n  bookmark https://example.com --quote \"Example quote or excerpt.\"\n  bookmark list\n  bookmark search \"example query\"\n  bookmark open 5\n\n------------------------------------------\nPart of `nb` (https://github.com/xwmx/nb).\nFor more information, see: `nb help`.\n```\n\n### Subcommands\n\n<div align=\"center\">\n  <a href=\"#add\">add</a>&nbsp;·\n  <a href=\"#archive\">archive</a>&nbsp;·\n  <a href=\"#bookmark\">bookmark</a>&nbsp;·\n  <a href=\"#browse\">browse</a>&nbsp;·\n  <a href=\"#completions\">completions</a>&nbsp;·\n  <a href=\"#copy\">copy</a>&nbsp;·\n  <a href=\"#count\">count</a>&nbsp;·\n  <a href=\"#delete\">delete</a>&nbsp;·\n  <a href=\"#do\">do</a>&nbsp;·\n  <a href=\"#edit\">edit</a>&nbsp;·\n  <a href=\"#env\">env</a>&nbsp;·\n  <a href=\"#folders\">folders</a>&nbsp;·\n  <a href=\"#export\">export</a>&nbsp;·\n  <a href=\"#git\">git</a>&nbsp;·\n  <a href=\"#help\">help</a>&nbsp;·\n  <a href=\"#history\">history</a>&nbsp;·\n  <a href=\"#import\">import</a>&nbsp;·\n  <a href=\"#init\">init</a>&nbsp;·\n  <a href=\"#list\">list</a>&nbsp;·\n  <a href=\"#ls\">ls</a>&nbsp;·\n  <a href=\"#move\">move</a>&nbsp;·\n  <a href=\"#notebooks\">notebooks</a>&nbsp;·\n  <a href=\"#open\">open</a>&nbsp;·\n  <a href=\"#peek\">peek</a>&nbsp;·\n  <a href=\"#pin\">pin</a>&nbsp;·\n  <a href=\"#plugins\">plugins</a>&nbsp;·\n  <a href=\"#remote\">remote</a>&nbsp;·\n  <a href=\"#run\">run</a>&nbsp;·\n  <a href=\"#search\">search</a>&nbsp;·\n  <a href=\"#settings\">settings</a>&nbsp;·\n  <a href=\"#shell\">shell</a>&nbsp;·\n  <a href=\"#show\">show</a>&nbsp;·\n  <a href=\"#status\">status</a>&nbsp;·\n  <a href=\"#subcommands-1\">subcommands</a>&nbsp;·\n  <a href=\"#sync\">sync</a>&nbsp;·\n  <a href=\"#tasks\">tasks</a>&nbsp;·\n  <a href=\"#todo\">todo</a>&nbsp;·\n  <a href=\"#unarchive\">unarchive</a>&nbsp;·\n  <a href=\"#undo\">undo</a>&nbsp;·\n  <a href=\"#unpin\">unpin</a>&nbsp;·\n  <a href=\"#unset\">unset</a>&nbsp;·\n  <a href=\"#update\">update</a>&nbsp;·\n  <a href=\"#use\">use</a>&nbsp;·\n  <a href=\"#version\">version</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#overview\">&nbsp;↑&nbsp;</a>\n</div>\n\n#### `add`\n\n[↑](#-help) · See also:\n[Adding](#adding),\n[`bookmark`](#bookmark),\n[`browse`](#browse),\n[`delete`](#delete),\n[`edit`](#edit),\n[`folders`](#folders),\n[`import`](#import),\n[`show`](#show),\n[`todo`](#todo)\n\n```text\nUsage:\n  nb add [<notebook>:][<folder-path>/][<filename>] [<content>]\n         [-b | --browse] [-c <content> | --content <content>] [--edit]\n         [-e | --encrypt] [-f <filename> | --filename <filename>]\n         [--folder <folder-path>] [--no-template] [--tags <tag1>,<tag2>...]\n         [--template <template>] [-t <title> | --title <title>] [--type <type>]\n  nb add bookmark [<bookmark-options>...]\n  nb add folder [<name>]\n  nb add todo [<todo-options>...]\n\nOptions:\n  -b, --browse                Add using a terminal or GUI web browser.\n  -c, --content <content>     The content for the new note.\n  --edit                      Open the note in the editor before saving when\n                              content is piped or passed as an argument.\n  -e, --encrypt               Encrypt the note with a password.\n  -f, --filename <filename>   The filename for the new note.\n  --folder <folder-path>      Add within the folder located at <folder-path>.\n  --no-template               Skip the template when one is assigned.\n  --tags <tag1>,<tag2>...     A comma-separated list of tags.\n  --template <template>       A string template or path to a template file.\n  -t, --title <title>         The title for a new note. If `--title` is\n                              present, the filename is derived from the\n                              title, unless `--filename` is specified.\n  --type <type>               The file type for the new note, as a file\n                              extension.\n\nDescription:\n  Create a new note or folder.\n\n  If no arguments are passed, a new blank note file is opened with `$EDITOR`,\n  currently set to: example\n\n  If a non-option argument is passed, `nb` will treat it as a <filename≥\n  if a file extension is found. If no file extension is found,  `nb` will\n  treat the string as <content> and will create a new note without opening the\n  editor. `nb add` can also create a new note with piped content.\n\n  `nb` creates Markdown files by default. To create a note with a\n  different file type, use the extension in the filename or use the `--type`\n  option. To change the default file type, use `nb set default_extension`.\n\n  When the `-e` / `--encrypt` option is used, `nb` will encrypt the\n  note with AES-256 using OpenSSL by default, or GPG, if configured in\n  `nb set encryption_tool`.\n\nRead More:\n  https://github.com/xwmx/nb#adding\n\nSee Also:\n  nb help bookmark\n  nb help browse\n  nb help delete\n  nb help edit\n  nb help folders\n  nb help import\n  nb help show\n  nb help todo\n\nExamples:\n  nb add\n  nb add example.md\n  nb add \"Note content.\"\n  nb add example.md --title \"Example Title\" --content \"Example content.\"\n  echo \"Note content.\" | nb add\n  nb add -t \"Secret Document\" --encrypt\n  nb add example/document.md\n  nb add folder sample/demo\n  nb example:add\n  nb example:add -t \"Title\"\n  nb a\n  nb a \"Note content.\"\n  nb example:a\n  nb example:a -t \"Title\"\n\nAliases:\n  nb create\n  nb new\n\nShortcut Aliases:\n  nb a\n  nb +\n```\n\n#### `archive`\n\n[↑](#-help) · See also:\n[Archiving Notebooks](#archiving-notebooks),\n[`notebooks`](#notebooks),\n[`status`](#status),\n[`unarchive`](#unarchive)\n\n```text\nUsage:\n  nb archive [<name>]\n\nDescription:\n  Set the current notebook or notebook <name> to \"archived\" status.\n\n  This is an alias for `nb notebooks archive`.\n\nRead More:\n  https://github.com/xwmx/nb#archiving-notebooks\n\nSee Also:\n  nb help notebooks\n  nb help status\n  nb help unarchive\n\nExamples:\n  nb archive\n  nb archive example\n\nShortcut Alias:\n  nb ar\n```\n\n#### `bookmark`\n\n[↑](#-help) · See also:\n[Bookmarks](#-bookmarks),\n[`browse`](#browse),\n[`open`](#open),\n[`peek`](#peek),\n[`show`](#show)\n\n```text\nUsage:\n  nb bookmark [<ls-options>...]\n  nb bookmark [<notebook>:][<folder-path>/] <url>...\n              [-c <comment> | --comment <comment>] [--edit] [-e | --encrypt]\n              [-f <filename> | --filename <filename>] [--no-request]\n              [-q <quote> | --quote <quote>] [--save-source]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]...\n              [-t <tag1>,<tag2>... | --tags <tag1>,<tag2>...] [--title <title>]\n  nb bookmark list [<list-options>...]\n  nb bookmark (edit | delete | open | peek | url)\n              ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb bookmark search <query>\n\nOptions:\n  -c, --comment <comment>      A comment or description for this bookmark.\n  --edit                       Open the bookmark in your editor before saving.\n  -e, --encrypt                Encrypt the bookmark with a password.\n  -f, --filename <filename>    The filename for the bookmark. It is\n                               recommended to omit the extension so the\n                               default bookmark extension is used.\n  --no-request                 Don't request or download the target page.\n  -q, --quote <quote>          A quote or excerpt from the saved page.\n                               Alias: `--excerpt`\n  -r, --related <selector>     A selector for an item related to the\n                               bookmarked page.\n  -r, --related <url>          A URL for a page related to the bookmarked page.\n                               Multiple `--related` flags can be used in a\n                               command to save multiple related URLs.\n  --save-source                Save the page source as HTML.\n  -t, --tags <tag1>,<tag2>...  A comma-separated list of tags.\n  --title <title>              The bookmark title. When not specified,\n                               `nb` will use the html <title> tag.\n\nSubcommands:\n  (default)  Add a new bookmark for <url>, or list bookmarks.\n             Bookmarks can also be added with `nb <url>`\n  delete     Delete a bookmark.\n  edit       Edit a bookmark.\n  list       List bookmarks in the current notebook.\n             Shortcut Alias: `ls`\n  open       Open the bookmarked page in your system's primary web browser.\n             Shortcut Alias: `o`\n  peek       Open the bookmarked page in your terminal web browser.\n             Alias: `preview`\n             Shortcut Alias: `p`\n  search     Search bookmarks for <query>.\n             Shortcut Alias: `q`\n  url        Print the URL for the specified bookmark.\n\nDescription:\n  Create, view, search, edit, and delete bookmarks.\n\n  By default, the html page content is saved within the bookmark, making the\n  bookmarked page available for full-text search. When Pandoc [1] is\n  installed, the HTML content is converted to Markdown before saving.\n  When readability-cli [2] is install, markup is cleaned up to focus on\n  content.\n\n  `peek` opens the page in `w3m` [3] or `links` [4] when available.\n  To specify a preferred browser, set the `$BROWSER` environment variable\n  in your .bashrc, .zshrc, or equivalent, e.g.: export BROWSER=\"lynx\"\n\n  Bookmarks are identified by the `.bookmark.md` file extension. The\n  bookmark URL is the first URL in the file within \"<\" and \">\" characters:\n\n    <https://www.example.com>\n\n    1. https://pandoc.org/\n    2. https://gitlab.com/gardenappl/readability-cli\n    3. https://en.wikipedia.org/wiki/W3m\n    4. https://en.wikipedia.org/wiki/Links_(web_browser)\n\nRead More:\n  https://github.com/xwmx/nb#-bookmarks\n\nSee Also:\n  nb help browse\n  nb help open\n  nb help peek\n  nb help show\n\nExamples:\n  nb https://example.com\n  nb example: https://example.com\n  nb https://example.com --encrypt\n  nb https://example.com --tags example,sample,demo\n  nb https://example.com/about -c \"Example comment.\"\n  nb https://example.com/faqs -f example-filename\n  nb https://example.com --quote \"Example quote or excerpt.\"\n  nb bookmark list\n  nb bookmark search \"example query\"\n  nb bookmark open 5\n  nb bk\n\nShortcut Aliases:\n  nb bk\n  nb bm\n```\n\n#### `browse`\n\n[↑](#-help) · See also:\n[Browsing](#-browsing),\n[Images](#-images),\n[Linking](#-linking),\n[`add`](#add),\n[`delete`](#delete),\n[`edit`](#edit),\n[`list`](#list),\n[`ls`](#ls),\n[`open`](#open),\n[`peek`](#peek),\n[`pin`](#pin),\n[`search`](#search),\n[`show`](#show)\n\n```text\nUsage:\n  nb browse [<notebook>:][<folder-path>/][<id> | <filename> | <title>] [--daemon]\n            [-g | --gui] [-n | --notebooks] [-p | --print] [-q | --query <query>]\n            [-s | --serve] [-t <tag> | --tag <tag> | --tags <tag1>,<tag2>...]\n  nb browse add [<notebook>:][<folder-path>/][<filename>]\n            [-c <content> | --content <content>] [--tags <tag1>,<tag2>...]\n            [-t <title> | --title <title>]\n  nb browse delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb browse edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nSubcommands:\n  (default)  Open a notebook, folder, or item in the terminal or GUI web browser.\n  add        Open the add view in the browser.\n             Shortcut Aliases: `a`, `+`\n  delete     Open the delete view in the browser.\n             Shortcut Aliases: `d`, `-`\n  edit       Open the edit view in the browser.\n             Shortcut Alias:   `e`\n\nOptions:\n  -c, --content <content>      Add content to the new note.\n  --daemon                     Start the web server. Close with <CTRL-C>.\n  -g, --gui                    Open in the system's primary GUI web browser.\n  -n, --notebooks              Browse notebooks.\n  -p, --print                  Print to standard output.\n  -q, --query <query>          Open to the search results for <query>.\n  -s, --serve                  Start the web server. Close with any key.\n  -t, --tag <tag>              Search for a tag.\n  --tags <tag1>,<tag2>...      A comma-separated list of tags.\n  -t, --title <title>          Add a title to the new note.\n\nDescription:\n  Browse, view, and edit linked notes, bookmarks, notebooks, folders, and\n  other items using terminal and GUI web browsers.\n\n  `browse` includes an embedded web application designed for terminal\n  and GUI web browsers that renders [[wiki-style links]] and #tags as\n  internal links, providing the ability to browse notes and notebooks,\n  as well as seamlessly browse to and from the offsite links in\n  bookmarks and notes.\n\n  To link to a note or bookmark from another, include the selector for the\n  target item within double square brackets anywhere in the linking document:\n\n    # link to item 123 in the \"sample\" folder in the \"example\" notebook\n    [[example:sample/123]]\n\n    # link to the item titled \"Example Title\" in the \"demo\" notebook\n    [[demo:Example Title]]\n\n  `browse` supports `w3m` [1] and `links` [2], and depends on\n  `ncat` [3] or `socat` [4] and `pandoc` [5]:\n\n    1. https://en.wikipedia.org/wiki/W3m\n    2. https://en.wikipedia.org/wiki/Links_(web_browser)\n    3. https://nmap.org/ncat/\n    4. https://www.kali.org/tools/socat/\n    5. https://pandoc.org/\n\nRead More:\n  https://github.com/xwmx/nb#-browsing\n\nSee Also:\n  nb help add\n  nb help delete\n  nb help edit\n  nb help list\n  nb help ls\n  nb help open\n  nb help peek\n  nb help pin\n  nb help search\n  nb help show\n  nb help unpin\n\nExamples:\n  nb browse\n  nb browse example:\n  nb browse Example\\ Folder/\n  nb browse 123\n  nb browse demo:456\n  nb br\n\nShortcut Alias:\n  nb b\n```\n\n#### `completions`\n\n[↑](#-help) · See also:\n[Tab Completion](https://github.com/xwmx/nb/tree/master/etc),\n[`env`](#env)\n\n```text\nUsage:\n  nb completions (check | install [-d | --download] | uninstall)\n\nOptions:\n  -d, --download  Download the completion scripts and install.\n\nDescription:\n  Manage completion scripts.\n\nRead More:\n  https://github.com/xwmx/nb/blob/master/etc/README.md\n\nSee Also:\n  nb help env\n```\n\n#### `copy`\n\n[↑](#-help) · See also:\n[Moving & Renaming](#-moving--renaming),\n[`move`](#move)\n\n```text\nUsage:\n  nb copy ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[<notebook>:][<folder-path>/]<filename>]\n\nDescription:\n  Copy or duplicate an item.\n\nRead More:\n  https://github.com/xwmx/nb#-moving--renaming\n\nSee Also:\n  nb help move\n\nExamples:\n  nb copy 321\n  nb copy 456 example:\n  nb copy sample/demo.md\n\nAlias:\n  nb duplicate\n```\n\n#### `count`\n\n[↑&nbsp;](#-help)\n\n```text\nUsage:\n  nb count [<notebook>:][<folder-path>/]\n\nDescription:\n  Print the number of items in the first level of the current notebook,\n  <notebook>, or the folder at <folder-path>.\n```\n\n#### `delete`\n\n[↑](#-help) · See also:\n[Deleting](#deleting),\n[`add`](#add),\n[`browse`](#browse),\n[`edit`](#edit),\n[`move`](#move),\n[`show`](#show)\n\n```text\nUsage:\n  nb delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])...\n            [-f | --force]\n\nOptions:\n  -f, --force   Skip the confirmation prompt.\n\nDescription:\n  Delete one or more items.\n\nRead More:\n  https://github.com/xwmx/nb#deleting\n\nSee Also:\n  nb help add\n  nb help browse\n  nb help edit\n  nb help move\n  nb help show\n\nExamples:\n  nb delete 3\n  nb delete example.md\n  nb delete \"A Document Title\"\n  nb 3 delete --force\n  nb example:delete 12\n  nb delete example:12\n  nb example:12 delete\n  nb d 3\n  nb 3 d\n  nb d example:12\n  nb example:12 d\n\nAliases:\n  nb rm\n  nb trash\n\nShortcut Aliases:\n  nb d\n  nb -\n```\n\n#### `do`\n\n[↑](#-help) · See also:\n[Todos](#-todos),\n[Tasks](#%EF%B8%8F-tasks),\n[`tasks`](#tasks),\n[`todo`](#todo),\n[`undo`](#undo)\n\n```text\nUsage:\n  nb do ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n        [<task-number>]\n\nDescription:\n  Mark a todo or task as done.\n\nRead More:\n  https://github.com/xwmx/nb#-todos\n\nSee Also:\n  nb help tasks\n  nb help todo\n  nb help undo\n\nExamples:\n  nb do 123\n  nb do example:sample/321\n  nb do 543 7\n```\n\n#### `edit`\n\n[↑](#-help) · See also:\n[Editing](#editing),\n[`add`](#add),\n[`browse`](#browse),\n[`delete`](#delete),\n[`move`](#move),\n[`show`](#show)\n\n```text\nUsage:\n  nb edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [-c <content> | --content <content>] [--edit]\n          [-e <editor> | --editor <editor>] [-l | --last] [--overwrite]\n          [--prepend]\n\nOptions:\n  -c, --content <content>  Content to add to the item.\n  --edit                   Open the note in the editor before saving when\n                           content is piped or passed as an argument.\n  -e, --editor <editor>    Edit the note with <editor>, overriding the editor\n                           specified in the `$EDITOR` environment variable.\n  -l, --last               Edit the last modified item.\n  --overwrite              Overwrite existing content with <content> and\n                           standard input.\n  --prepend                Prepend <content> and standard input before\n                           existing content.\n\nDescription:\n  Open the specified note in `$EDITOR` or <editor> if specified.\n  Content piped to `nb edit` or passed using the `--content` option\n  is appended to the file without opening it in the editor,\n  unless the `--edit` flag is specified.\n\n  Non-text files are opened in your system's preferred app or program for\n  that file type.\n\nRead More:\n  https://github.com/xwmx/nb#editing\n\nSee Also:\n  nb help add\n  nb help browse\n  nb help delete\n  nb help move\n  nb help show\n\nExamples:\n  nb edit 3\n  nb edit example.md\n  nb edit \"A Document Title\"\n  echo \"Content to append.\" | nb edit 1\n  nb 3 edit\n  nb example:edit 12\n  nb edit example:12\n  nb example:12 edit\n  nb e 3\n  nb 3 e\n  nb e example:12\n  nb example:12 e\n\nShortcut Alias:\n  nb e\n```\n\n#### `env`\n\n[↑](#-help) · See also:\n[Installation](#installation),\n[`completions`](#completions),\n[`init`](#init),\n[`update`](#update),\n[`version`](#version)\n\n```text\nUsage:\n  nb env [-l | --long]\n  nb env [install | update] [--ace | --mathjax]\n\nSubcommands:\n  (default) Print environment and configuration information.\n  install   Install dependencies on supported systems.\n  update    Update dependencies.\n\nOptions:\n  --ace       Install or update Ace editor [1][2].\n  -l, --long  Print additional environmental information.\n  --mathjax   Install or update MathJax [3].\n\n    1. https://github.com/ajaxorg/ace\n    2. https://github.com/ajaxorg/ace-builds\n    3. https://github.com/mathjax/MathJax\n\nDescription:\n  Print program environment and configuration information, or install\n  dependencies.\n\nRead More:\n  https://github.com/xwmx/nb#installation\n\nSee Also:\n  nb help completions\n  nb help init\n  nb help update\n  nb help version\n```\n\n#### `export`\n\n[↑](#-help) · See also:\n[Import / Export](#%EF%B8%8F-import--export),\n[`browse`](#browse),\n[`import`](#import)\n\n```text\nUsage:\n  nb export ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <path> [-f | --force] [<pandoc options>...]\n  nb export notebook <name> [<path>]\n  nb export pandoc ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            [<pandoc options>...]\n\nOptions:\n  -f, --force   Skip the confirmation prompt when overwriting an existing file.\n\nSubcommands:\n  (default)     Export a file to <path>. If <path> has a different extension\n                than the source note, convert the note using `pandoc`.\n  notebook      Export the notebook <name> to the current directory or <path>.\n                Alias for `nb notebooks export`.\n  pandoc        Export the file to standard output or a file using `pandoc`.\n                `export pandoc` prints to standard output by default.\n\nDescription:\n  Export a file or notebook.\n\n  If Pandoc [1] is available, convert the note from its current format\n  to the format of the output file as indicated by the file extension\n  in <path>. Any additional arguments are passed directly to Pandoc.\n  See the Pandoc help information for available options.\n\n    1. https://pandoc.org/\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-import--export\n\nSee Also:\n  nb help browse\n  nb help import\n\nExamples:\n  # Export an Org note\n  nb export example.org /path/to/example.org\n\n  # Export a Markdown note to HTML and print to standard output\n  nb export pandoc example.md --from=markdown_strict --to=html\n\n  # Export a Markdown note to a .docx Microsoft Office Word document\n  nb export example.md /path/to/example.docx\n\n  # Export note 12 in the \"sample\" notebook to HTML\n  nb export sample:12 /path/to/example.html\n```\n\n#### `folders`\n\n[↑](#-help) · See also:\n[Folders](#-folders),\n[`add`](#add),\n[`delete`](#delete),\n[`list`](#list),\n[`ls`](#ls)\n\n```text\nUsage:\n  nb folders add [<notebook>:][<folder-path>/]<folder-name>\n  nb folders delete [<notebook>:][<folder-path>/]<folder-name>\n  nb folders <list-options>...\n\nSubcommands:\n  (default)  List folders.\n  add        Add a new folder.\n  delete     Delete a folder.\n\nDescription:\n  Add, delete, and list folders.\n\nRead More:\n  https://github.com/xwmx/nb#-folders\n\nSee Also:\n  nb help add\n  nb help delete\n  nb help list\n  nb help ls\n\nExamples:\n  nb folders\n  nb folders add example\n  nb folders delete example:sample\n\nAlias:\n  nb folder\n\nShortcut Alias:\n  nb f\n```\n\n#### `git`\n\n[↑](#-help) · See also:\n[Git Sync](#-git-sync),\n[History](#-revision-history),\n[`history`](#history),\n[`remote`](#remote),\n[`run`](#run),\n[`status`](#status),\n[`sync`](#sync)\n\n```text\nUsage:\n  nb git [checkpoint [<message>] | dirty]\n  nb git <git-options>...\n\nSubcommands:\n  checkpoint    Create a new git commit in the current notebook and sync with\n                the remote if `nb set auto_sync` is enabled.\n  dirty         0 (success, true) if there are uncommitted changes in the\n                current notebook. 1 (error, false) if the notebook is clean.\n\nDescription:\n  Run `git` commands within the current notebook directory.\n\nRead More:\n  https://github.com/xwmx/nb#-git-sync\n  https://github.com/xwmx/nb#-revision-history\n\nSee Also:\n  nb help history\n  nb help remote\n  nb help run\n  nb help status\n  nb help sync\n\nExamples:\n  nb git status\n  nb git diff\n  nb git log\n  nb example:git status\n```\n\n#### `help`\n\n[↑](#-help) · See also:\n[`nb help`](#nb-help)\n\n```text\nUsage:\n  nb help [<subcommand>] [-p | --print]\n  nb help [-c | --colors] | [-r | --readme] | [-s | --short] [-p | --print]\n\nOptions:\n  -c, --colors  View information about color themes and color settings.\n  -p, --print   Print to standard output / terminal.\n  -r, --readme  View the `nb` README file.\n  -s, --short   Print shorter help without subcommand descriptions.\n\nDescription:\n  Print the program help information. When a subcommand name is passed, print\n  the help information for the subcommand.\n\nExamples:\n  nb help\n  nb help add\n  nb help import\n  nb h notebooks\n  nb h e\n\nShortcut Alias:\n  nb h\n```\n\n#### `history`\n\n[↑](#-help) · See also:\n[History](#-revision-history),\n[Git Sync](#-git-sync),\n[`git`](#git),\n[`remote`](#remote),\n[`status`](#status),\n[`sync`](#sync)\n\n```text\nUsage:\n  nb history [<notebook>:][<folder-path>/][<id> | <filename> | <title>]\n\nDescription:\n  Display notebook history using `tig` [1] (if available) or `git log`.\n  When a note is specified, the history for that note is displayed.\n\n    1. https://github.com/jonas/tig\n\nRead More:\n  https://github.com/xwmx/nb#-revision-history\n  https://github.com/xwmx/nb#-git-sync\n\nSee Also:\n  nb help git\n  nb help remote\n  nb help status\n  nb help sync\n\nExamples:\n  nb history\n  nb history example.md\n  nb 3 history\n  nb history example:\n  nb example:history\n  nb example:history 12\n  nb history example:12\n  nb example:12 history\n```\n\n#### `import`\n\n[↑](#-help) · See also:\n[Import / Export](#%EF%B8%8F-import--export),\n[Images](#-images),\n[`add`](#add),\n[`export`](#export)\n\n```text\nUsage:\n  nb import [bookmarks | copy | download | move] (<path>... | <url>)\n            [--convert] [<notebook>:][<folder-path>/][<filename>]\n  nb import notebook <path> [<name>]\n\nOptions:\n  --convert  Convert HTML content to Markdown.\n\nSubcommands:\n  (default)  Copy or download the file(s) at <path> or <url>.\n  bookmarks  Import bookmarks from a Chrome, Firefox, or Edge export file.\n  copy       Copy the file(s) at <path> into the current notebook.\n  download   Download the file at <url> into the current notebook.\n  move       Move the file(s) at <path> into the current notebook.\n  notebook   Import the local notebook at <path> to make it global.\n\nDescription:\n  Copy, move, or download files into `nb`, import bookmarks, or import\n  a local notebook to make it global.\n\nDescription:\n  Copy, move, or download files into the current notebook or import\n  a local notebook to make it global.\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-import--export\n\nSee Also:\n  nb help add\n  nb help export\n\nExamples:\n  nb import ~/Pictures/example.png\n  nb import ~/Documents/example.docx\n  nb import https://example.com/example.pdf\n  nb example:import https://example.com/example.jpg\n  nb import ./*\n  nb import ./*.md\n  nb import ~/Pictures/example.png example-notebook:\n  nb import ~/Documents/example.docx example-folder/\n\nShortcut Alias:\n  nb i\n```\n\n#### `init`\n\n[↑](#-help) · See also: [`notebooks`](#notebooks)\n\n```text\nUsage:\n  nb init [<remote-url> [<branch>]] [--author] [--email <email>]\n          [--name <name>]\n\nOptions:\n  --author         Display the local email and name config prompt.\n  --email <email>  Set the local commit author email address to <email>.\n  --name  <name>   Set the local commit author name to <name>.\n\nDescription:\n  Initialize the initial \"home\" notebook and generate a configuration file at:\n\n      ~/.nbrc\n\n  Pass optional <remote-url> and <branch> arguments to create the initial\n  \"home\" notebook using a clone of an existing notebook.\n\nSee Also:\n  nb help notebooks\n\nExamples:\n  nb init\n  nb init https://github.com/example/example.git\n  nb init https://github.com/example/example.git example-branch\n```\n\n#### `list`\n\n[↑](#-help) · See also:\n[Listing & Filtering](#listing--filtering),\n[`browse`](#browse),\n[`ls`](#ls),\n[`pin`](#pin),\n[`search`](#search),\n[`unpin`](#unpin)\n\n```text\nUsage:\n  nb list [-e [<length>] | --excerpt [<length>]] [--filenames]\n          [-f | --folders-first] [-n <limit> | --limit <limit> | --<limit>]\n          [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n          [--paths] [-s | --sort] [-r | --reverse] [--tags]\n          [-t <type> | --type <type> | --<type>]\n          [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n\nOptions:\n  -e, --excerpt [<length>]        Print an excerpt <length> lines long under\n                                  each note's filename [default: 3].\n  --filenames                     Print the filename for each note.\n  -f, --folders-first             Print folders before other items.\n  -n, --limit <limit>, --<limit>  The maximum number of notes to list.\n  --no-id                         Don't include the id in list items.\n  --no-indicator                  Don't include the indicator in list items.\n  -p, --page <number>             The page to view in the list paginated by\n                                  a <limit> option or `nb set limit`.\n  --pager                         Display output in the pager.\n  --paths                         Print the full path to each item.\n  -s, --sort                      Order notes by id.\n  -r, --reverse                   List items in reverse order.\n  --tags                          List tags in the notebook or folder.\n  -t, --type <type>, --<type>     List items of <type>. <type> can be a file\n                                  extension or one of the following types:\n                                  archive, audio, book, bookmark, document,\n                                  folder, image, note, text, video\n\nDescription:\n  List notes in the current notebook.\n\n  When <id>, <filename>, <path>, or <title> are present, the listing for the\n  matching note is displayed. When no match is found, titles and filenames\n  are searched for any that match <query> as a case-insensitive regular\n  expression.\n\nRead More:\n  https://github.com/xwmx/nb#listing--filtering\n\nIndicators:\n  🔉  Audio\n  📖  Book\n  🔖  Bookmark\n  🔒  Encrypted\n  📂  Folder\n  🌄  Image\n  📄  PDF, Word, or Open Office document\n  📹  Video\n\nSee Also:\n  nb help browse\n  nb help ls\n  nb help pin\n  nb help search\n  nb help unpin\n\nExamples:\n  nb list\n  nb list example.md -e 10\n  nb list --excerpt --no-id\n  nb list --filenames --reverse\n  nb list \"^Example.*\"\n  nb list --10\n  nb list --type document\n  nb example:list\n```\n\n#### `ls`\n\n[↑](#-help) · See also:\n[Listing & Filtering](#listing--filtering),\n[`browse`](#browse),\n[`list`](#list),\n[`pin`](#pin),\n[`search`](#search),\n[`unpin`](#unpin)\n\n```text\nUsage:\n  nb ls [-a | --all] [-b | --browse] [-e [<length>] | --excerpt [<length>]]\n        [--filenames] [-f | --folders-first] [-g | --gui]\n        [-n <limit> | --limit <limit> | --<limit>] [--no-footer] [--no-header]\n        [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n        [--paths] [-s | --sort] [-r | --reverse] [--tags]\n        [-t <type> | --type <type> | --<type>]\n        [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n\nOptions:\n  -a, --all                       Print all items in the notebook. Equivalent\n                                  to no limit.\n  -b, --browse                    Open the specified item or current notebook\n                                  with `browse` in a terminal web browser.\n  -e, --excerpt [<length>]        Print an excerpt <length> lines long under\n                                  each note's filename [default: 3].\n  --filenames                     Print the filename for each note.\n  -f, --folders-first             Print folders before other items.\n  -g, --gui                       Open the specified item or current notebook\n                                  with `browse` in a GUI web browser.\n  -n, --limit <limit>, --<limit>  The maximum number of listed items.\n                                  [default: 15]\n  --no-footer                     Print without footer.\n  --no-header                     Print without header.\n  --no-id                         Don't include the id in list items.\n  --no-indicator                  Don't include the indicator in list items.\n  -p, --page <number>             The page to view in the list paginated by\n                                  a <limit> option or `nb set limit`.\n  --pager                         Display output in the pager.\n  --paths                         Print the full path to each item.\n  -s, --sort                      Order notes by id.\n  -r, --reverse                   List items in reverse order.\n  --tags                          List tags in the notebook or folder.\n  -t, --type <type>, --<type>     List items of <type>. <type> can be a file\n                                  extension or one of the following types:\n                                  archive, audio, book, bookmark, document,\n                                  folder, image, note, text, video\n\nDescription:\n  List notebooks and notes in the current notebook, displaying note titles\n  when available. `nb ls` is a combination of `nb notebooks` and\n  `nb list` in one view.\n\n  When <id>, <filename>, <path>, or <title> are present, the listing for the\n  matching note is displayed. When no match is found, titles and filenames\n  are searched for any that match <query> as a case-insensitive regular\n  expression.\n\n  Options are passed through to `list`. For more information, see\n  `nb help list`.\n\nRead More:\n  https://github.com/xwmx/nb#listing--filtering\n\nIndicators:\n  🔉  Audio\n  📖  Book\n  🔖  Bookmark\n  🔒  Encrypted\n  📂  Folder\n  🌄  Image\n  📄  PDF, Word, or Open Office document\n  📹  Video\n\nSee Also:\n  nb help browse\n  nb help list\n  nb help pin\n  nb help search\n  nb help unpin\n\nExamples:\n  nb\n  nb --all\n  nb ls\n  nb ls example.md -e 10\n  nb ls --excerpt --no-id\n  nb ls --reverse\n  nb ls \"^Example.*\"\n  nb ls --10\n  nb ls --type document\n  nb example:\n  nb example: -ae\n  nb example:ls\n\nShortcut Alias:\n  nb\n```\n\n#### `move`\n\n[↑](#-help) · See also:\n[Moving & Renaming](#-moving--renaming),\n[`copy`](#copy),\n[`delete`](#delete),\n[`edit`](#edit)\n\n```text\nUsage:\n  nb move ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          ([<notebook>:][<path>] | --reset | --to-bookmark | --to-note |\n          --to-title | --to-todo) [-f | --force]\n\nOptions:\n  -f, --force     Skip the confirmation prompt.\n  --reset         Reset the filename to the last modified timestamp.\n  --to-bookmark   Preserve the existing filename and replace the extension\n                  with \".bookmark.md\" to convert the note to a bookmark.\n  --to-note       Preserve the existing filename and replace the bookmark's\n                  \".bookmark.md\" extension with \".md\" to convert the bookmark\n                  to a Markdown note.\n  --to-title      Set the filename to the note title, lowercased with spaces\n                  and disallowed filename characters replaced with underscores.\n  --to-todo       Preserve the existing filename and replace the extension\n                  with \".todo.md\" to convert the note to a todo.\n\nDescription:\n  Move or rename a note. Move the note to <path> or change the file type.\n  When the file extension is omitted, the existing extension is used.\n  When only a file extension is specified, only the extension will be updated.\n\n  `nb move` and `nb rename` are aliases and can be used interchangeably.\n\nRead More:\n  https://github.com/xwmx/nb#-moving--renaming\n\nSee Also:\n  nb help copy\n  nb help delete\n  nb help edit\n\nExamples:\n  # move \"example.md\" to \"sample.org\"\n  nb move example.md sample.org\n\n  # rename note 3 (\"example.md\") to \"New Name.md\"\n  nb rename 3 \"New Name\"\n\n  # rename \"example.bookmark.md\" to \"New Name.bookmark.md\"\n  nb move example.bookmark.md \"New Name\"\n\n  # rename note 3 (\"example.md\") to a bookmark named \"example.bookmark.md\"\n  nb rename 3 --to-bookmark\n\n  # move note 12 into \"Sample Folder\" in the \"demo\" notebook\n  nb move example:12 demo:Sample\\ Folder/\n\n  # rename note 12 in the \"example\" notebook to \"sample.md\"\n  nb rename example:12 \"sample.md\"\n\n  # change the file extension of note 5 to .org\n  nb rename 5 .org\n\nAlias:\n  nb rename\n\nShortcut Alias:\n  nb mv\n```\n\n#### `notebooks`\n\n[↑](#-help) · See also:\n[Notebooks](#-notebooks),\n[`archive`](#archive),\n[`history`](#history),\n[`move`](#move),\n[`remote`](#remote),\n[`status`](#status),\n[`sync`](#sync),\n[`unarchive`](#unarchive),\n[`use`](#use)\n\n```text\nUsage:\n  nb notebooks [<name> | <query>] [--ar | --archived] [--global] [--local]\n               [--names] [--paths] [--unar | --unarchived]\n  nb notebooks add ([<name>] [<remote-url> [<branch>... | --all]]) [--author]\n                   [--email <email>] [--name <name>]\n  nb notebooks (archive | open | peek | status | unarchive) [<name>]\n  nb notebooks author [<name> | <path>] [--email <email>] [--name <name>]\n  nb notebooks current [--path | --selected | --filename [<filename>]]\n                       [--global | --local]\n  nb notebooks delete <name> [-f | --force]\n  nb notebooks (export <name> [<path>] | import <path>)\n  nb notebooks init [<path> [<remote-url> [<branch>]]] [--author]\n                    [--email <email>] [--name <name>]\n  nb notebooks rename <old-name> <new-name>\n  nb notebooks select <selector>\n  nb notebooks show (<name> | <path> | <selector>) [--ar | --archived]\n                    [--escaped | --name | --path | --filename [<filename>]]\n  nb notebooks use <name>\n\nOptions:\n  --all                    Add notebooks from all remote branches.\n  --ar, --archived         List archived notebooks, or return archival status\n                           with `show`.\n  --author                 Set the notebook's commit author email and name.\n  --email <email>          Set the notebook's commit author email to <email>.\n  --escaped                Print the notebook name with spaces escaped.\n  --filename [<filename>]  Print an available filename for the notebooks. When\n                           <filename> is provided, check for an existing file\n                           and provide a filename with an appended sequence\n                           number for uniqueness.\n  -f, --force              Skip the confirmation prompt.\n  --global                 List global notebooks or the notebook set globally\n                           with `use`.\n  --local                  Exit with 0 if current within a local notebook,\n                           otherwise exit with 1.\n  --name, --names          Print the notebook name.\n  --name <name>            Set the notebook's commit author name to <name>.\n  --path, --paths          Print the notebook path.\n  --selected               Exit with 0 if the current notebook differs from\n                           the current global notebook, otherwise exit with 1.\n  --unar, --unarchived     Only list unarchived notebooks.\n\nSubcommands:\n  (default)  List notebooks.\n  add        Create a new global notebook. When <remote-url> is specified,\n             create one or more new global notebook by cloning selected\n             or specified <branch>es from <remote-url>.\n             Aliases: `nb notebooks create`, `nb notebooks new`\n  archive    Set the current notebook or notebook <name> to \"archived\" status.\n  author     Configure the commit author email and name for the notebook.\n  current    Print the current notebook name or path.\n  delete     Delete a notebook.\n  export     Export the notebook <name> to the current directory or <path>,\n             making it usable as a local notebook.\n  import     Import the local notebook at <path> to make it global.\n  init       Create a new local notebook. Specify a <path> or omit to\n             initialize the current working directory as a local notebook.\n             Specify <remote-url> to clone an existing notebook.\n  open       Open the current notebook directory or notebook <name> in the\n             file browser, explorer, or finder.\n             Shortcut Alias: `o`\n  peek       Open the current notebook directory or notebook <name> in the\n             first tool found in the following list:\n             `ranger` [1], `mc` [2], `vifm` [3], `joshuto` [4], `lsd` [5],\n             `eza` [6], or `ls`.\n             Shortcut Alias: `p`\n  rename     Rename a notebook. Aliases: `move`, `mv`\n  select     Set the current notebook from a colon-prefixed selector.\n             Not persisted. Selection format: <notebook>:<identifier>\n  status     Print the archival status of the current notebook or\n             notebook <name>.\n  show       Show and return information about a specified notebook.\n  unarchive  Remove \"archived\" status from the current notebook or notebook <name>.\n  use        Switch to a notebook.\n\n    1. https://ranger.github.io/\n    2. https://en.wikipedia.org/wiki/Midnight_Commander\n    3. https://vifm.info/\n    4. https://github.com/kamiyaa/joshuto\n    5. https://github.com/lsd-rs/lsd\n    6. https://github.com/eza-community/eza\n\nDescription:\n  Manage notebooks.\n\nRead More:\n  https://github.com/xwmx/nb#-notebooks\n\nSee Also:\n  nb help archive\n  nb help history\n  nb help move\n  nb help remote\n  nb help status\n  nb help sync\n  nb help unarchive\n  nb help use\n\nExamples:\n  nb notebooks --names\n  nb notebooks add sample\n  nb notebooks add example https://github.com/example/example.git\n  nb nb current --path\n  nb nb archive example\n\nShortcut Aliases:\n  nb n\n  nb nb\n```\n\n#### `open`\n\n[↑](#-help) · See also:\n[Viewing Bookmarks](#viewing-bookmarks),\n[Images](#-images),\n[`bookmark`](#bookmark),\n[`browse`](#browse),\n[`peek`](#peek),\n[`show`](#show)\n\n```text\nUsage:\n  nb open ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nDescription:\n  Open an item or notebook. When the item is a bookmark, open the bookmarked\n  page in your system's primary web browser. When the item is in a text format\n  or any other file type, `open` is the equivalent of `edit`. `open`\n  with a notebook opens the notebook folder in the system's file browser.\n\nRead More:\n  https://github.com/xwmx/nb#viewing-bookmarks\n\nSee also:\n  nb help bookmark\n  nb help browse\n  nb help peek\n  nb help show\n\nExamples:\n  nb open 3\n  nb open example.bookmark.md\n  nb 3 open\n  nb example:open 12\n  nb open example:12\n  nb example:12 open\n  nb o 3\n  nb 3 o\n  nb o example:12\n  nb example:12 o\n\nShortcut Alias:\n  nb o\n```\n\n#### `peek`\n\n[↑](#-help) · See also:\n[Viewing Bookmarks](#viewing-bookmarks),\n[`bookmark`](#bookmark),\n[`browse`](#browse),\n[`open`](#open),\n[`show`](#show)\n\n```text\nUsage:\n  nb peek ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nDescription:\n  View an item or notebook in the terminal. When the item is a bookmark, view\n  the bookmarked page in your terminal web browser. When the note is in a text\n  format or any other file type, `peek` is the equivalent of `show`. When\n  used with a notebook, `peek` opens the notebook folder first tool found in\n  the following list: `ranger` [1], `mc` [2], `vifm` [3], `joshuto` [4],\n  `lsd` [5], eza` [6], or `ls`.\n\n    1. https://ranger.github.io/\n    2. https://en.wikipedia.org/wiki/Midnight_Commander\n    3. https://vifm.info/\n    4. https://github.com/kamiyaa/joshuto\n    5. https://github.com/lsd-rs/lsd\n    6. https://github.com/eza-community/eza\n\nRead More:\n  https://github.com/xwmx/nb#viewing-bookmarks\n\nSee also:\n  nb help bookmark\n  nb help browse\n  nb help open\n  nb help show\n\nExamples:\n  nb peek 3\n  nb peek example.bookmark.md\n  nb 3 peek\n  nb example:peek 12\n  nb peek example:12\n  nb example:12 peek\n  nb p 3\n  nb 3 p\n  nb p example:12\n  nb example:12 p\n\nAlias:\n  nb preview\n\nShortcut Alias:\n  nb p\n```\n\n#### `pin`\n\n[↑](#-help) · See also:\n[Pinning](#-pinning),\n[`browse`](#browse),\n[`list`](#list),\n[`ls`](#ls),\n[`unpin`](#unpin)\n\n```text\nUsage:\n  nb pin ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nDescription:\n  Pin an item so it appears first in lists.\n\nRead More:\n  https://github.com/xwmx/nb#-pinning\n\nSee Also:\n  nb help browse\n  nb help list\n  nb help ls\n  nb help unpin\n\nExamples:\n  nb pin 123\n  nb pin example:sample/321\n```\n\n#### `plugins`\n\n[↑](#-help) · See also:\n[Plugins](#-plugins),\n[Plugin Help](#plugin-help),\n[`subcommands`](#subcommands-1)\n\n```text\nUsage:\n  nb plugins [<name>] [--paths] [--force]\n  nb plugins install [<path> | <url>] [--force]\n  nb plugins uninstall <name>\n\nOptions:\n  --paths  Print the full path to each plugin.\n\nSubcommands:\n  (default)  List plugins.\n  install    Install a plugin from a <path> or <url>.\n  uninstall  Uninstall the specified plugin.\n\nDescription:\n  Manage plugins and themes.\n\nRead More:\n  https://github.com/xwmx/nb#-plugins\n\nPlugin Extensions:\n  .nb-theme   Plugins defining color themes.\n  .nb-plugin  Plugins defining new subcommands and functionality.\n\nSee Also:\n  nb help subcommands\n\nAlias:\n  nb plugin\n```\n\n#### `remote`\n\n[↑](#-help) · See also:\n[Git Sync](#-git-sync),\n[History](#-revision-history),\n[`history`](#history),\n[`notebooks`](#notebooks),\n[`status`](#status),\n[`sync`](#sync)\n\n```text\nUsage:\n  nb remote\n  nb remote branches [<url>]\n  nb remote delete <branch-name>\n  nb remote remove\n  nb remote rename [<branch-name>] <name>\n  nb remote reset <branch-name>\n  nb remote set <url> [<branch-name>]\n\nSubcommands:\n  (default)  Print the remote URL and branch for the notebook.\n  branches   List branches on the current or given remote.\n  delete     Delete <branch-name> from the remote.\n             Caveat: only orphan branches can be deleted.\n  remove     Remove the remote URL from the notebook.\n             Alias: `unset`\n  rename     Rename the current orphan branch or <branch-name> to <name>.\n             Caveat: only orphan branches can be renamed.\n  reset      Reset <branch-name> on the remote to a blank initial state.\n  set        Set the remote URL and branch for the notebook.\n\nDescription:\n  Configure the remote repository URL and branch for the current notebook.\n\nRead More:\n  https://github.com/xwmx/nb#-git-sync\n  https://github.com/xwmx/nb#-revision-history\n\nSee Also:\n  nb help history\n  nb help notebooks\n  nb help status\n  nb help sync\n\nExamples:\n  nb remote set https://github.com/example/example.git\n  nb remote remove\n  nb example-notebook:remote set https://github.com/example/example.git\n```\n\n#### `run`\n\n[↑](#-help) · See also: [`git`](#git), [`shell`](#shell)\n\n```text\nUsage:\n  nb run <command> [<arguments>...]\n\nDescription:\n  Run shell commands within the current notebook directory.\n\nSee Also:\n  nb help git\n  nb help shell\n\nExamples:\n  nb run ls -la\n  nb run find . -name 'example*'\n  nb run rg example\n```\n\n#### `search`\n\n[↑](#-help) · See also:\n[Search](#-search),\n[`browse`](#browse),\n[`list`](#list),\n[`ls`](#ls)\n\n```text\nUsage:\n  nb search ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <query>... [-a | --all] [--and <query>] [--not <query>] [--or <query>]\n            [-l | --list] [--path] [-t <tag1>,<tag2>... | --tag <tag1>,<tag2>...]\n            [-t | --tags] [--type <type> | --<type>] [--utility <name>]\n\nOptions:\n  -a, --all                     Search all unarchived notebooks.\n  --and <query>                 Add a AND query.\n  -l, --list                    Print the id, filename, and title listing for\n                                each matching file, without the excerpt.\n  --not <query>                 Add a NOT query.\n  --or  <query>                 Add an OR query.\n  --path                        Print the full path for each matching file.\n  -t, --tag <tag1>,<tag2>...    A comma-separated list of tags.\n  -t, --tags                    List all tags found in the notebook.\n  --type <type>, --<type>       Search items of <type>. <type> can be a file\n                                extension or one of the following types:\n                                archive, audio, book, bookmark, document,\n                                folder, image, note, text, video\n  --utility <name>              The name of the search utility to search with.\n\nDescription:\n  Perform a full text search.\n\n  Multiple query arguments are treated as AND queries, returning items that\n  match all queries. AND queries can also be specified with the --and <query>\n  option. The --or <query> option can be used to specify an OR query,\n  returning items that match at least one of the queries. --not <query>\n  excludes items matching <query>.\n\n  `nb search` is powered by Git's built-in `git grep` tool. `nb` also\n  supports performing searches with alternative search tools using the\n  --utility <name> option.\n\n  Supported alternative search tools:\n    1. `rga`   https://github.com/phiresky/ripgrep-all\n    2. `rg`    https://github.com/BurntSushi/ripgrep\n    3. `ag`    https://github.com/ggreer/the_silver_searcher\n    4. `ack`   https://beyondgrep.com/\n    5. `grep`  https://en.wikipedia.org/wiki/Grep\n\nRead More:\n  https://github.com/xwmx/nb#-search\n\nSee Also:\n  nb help browse\n  nb help list\n  nb help ls\n\nExamples:\n  # search current notebook for \"example query\"\n  nb search \"example query\"\n\n  # search the notebook \"example\" for \"example query\"\n  nb search example: \"example query\"\n\n  # search all notebooks for \"example query\" and list matching items\n  nb search \"example query\" --all --list\n\n  # search for items matching \"Example\" AND \"Demo\"\n  nb search \"Example\" \"Demo\"\n  nb search \"Example\" --and \"Demo\"\n\n  # search for items matching \"Example\" OR \"Sample\"\n  nb search \"Example|Sample\"\n  nb search \"Example\" --or \"Sample\"\n\n  # search for items matching both \"Example\" AND \"Sample\", and NOT \"Demo\"\n  nb search \"Example\" --and \"Sample\" --not \"Demo\"\n\n  # search with a regular expression\n  nb search \"\\d\\d\\d-\\d\\d\\d\\d\"\n\n  # search for tags\n  nb search --tag tag1 -t tag2\n\n  # search the current notebook for \"example query\"\n  nb q \"example query\"\n\n  # search all notebooks for \"example query\" and list matching items\n  nb q -la \"example query\"\n\nShortcut Alias:\n  nb q\n```\n\n#### `settings`\n\n[↑](#-help) · See also:\n[`set` & `settings`](#%EF%B8%8F-set--settings),\n[Variables](#-variables),\n[`unset`](#unset)\n\n```text\nUsage:\n  nb set [<name> [<value>] | <number> [<value>]]\n  nb settings colors [<number> | themes]\n  nb settings edit\n  nb settings get   (<name> | <number>)\n  nb settings list  [--long]\n  nb settings set   (<name> | <number>) <value>\n  nb settings show  (<name> | <number>)\n  nb settings unset (<name> | <number>)\n\nSubcommands:\n  (default)  Open the settings prompt, to <name> or <number>, if present.\n             When <value> is also present, assign <value> to the setting.\n  colors     Print a table of available colors and their xterm color numbers.\n             When <number> is provided, print the number in its color.\n             `settings colors themes` prints a list of installed themes.\n  edit       Open the `nb` configuration file in `$EDITOR`.\n  get        Print the value of a setting.\n  list       List information about available settings.\n  set        Assign <value> to a setting.\n  show       Print the help information and current value of a setting.\n  unset      Unset a setting, returning it to the default value.\n\nDescription:\n  Configure `nb`. Use `nb settings set` to customize a setting and\n  `nb settings unset` to restore the default for a setting.\n\n  Use the `nb set` alias to quickly assign values to settings:\n\n    nb set color_theme blacklight\n    nb set limit 40\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-set--settings\n\nSee Also:\n  nb help unset\n\nExamples:\n  nb settings\n  nb set 5 \"org\"\n  nb set color_primary 105\n  nb set unset color_primary\n  nb set color_secondary unset\n  nb settings colors\n  nb settings colors 105\n  nb set limit 15\n\nAlias:\n  nb set\n```\n\n##### `auto_sync`\n\n[↑](#-help) · See also: [Git Sync](#-git-sync)\n\n```text\n[1]  auto_sync\n     ---------\n     By default, operations that trigger a git commit like `add`, `edit`,\n     and `delete` will sync notebook changes to the remote repository, if\n     the notebook's remote is set. To disable this behavior, set this to \"0\".\n\n     • Default Value: 1\n```\n\n##### `color_primary`\n\n[↑](#-help) · See also: [Color Themes](#-color-themes), [Custom Color Themes](#custom-color-themes)\n\n```text\n[2]  color_primary\n     -------------\n     The primary color used to highlight identifiers and messages.\n\n     • Supported Values: xterm color numbers 0 through 255.\n     • Default Value:    68 (blue) for 256 color terminals,\n                         4  (blue) for  8  color terminals.\n```\n\n##### `color_secondary`\n\n[↑](#-help) · See also: [Color Themes](#-color-themes), [Custom Color Themes](#custom-color-themes)\n\n```text\n[3]  color_secondary\n     ---------------\n     The color used for lines and footer elements.\n\n     • Supported Values: xterm color numbers 0 through 255.\n     • Default Value:    8\n```\n\n##### `color_theme`\n\n[↑](#-help) · See also: [Color Themes](#-color-themes)\n\n```text\n[4]  color_theme\n     -----------\n     The color theme.\n\n     To view screenshots of the built-in themes, visit:\n\n         https://git.io/nb-docs-color-themes\n\n     `nb` supports custom, user-defined themes. To learn more, run:\n\n         nb help --colors\n\n     To change the syntax highlighting theme, use:\n\n         nb set syntax_theme\n\n     • Available themes:\n\n         blacklight\n         console\n         desert\n         electro\n         forest\n         nb\n         ocean\n         raspberry\n         smoke\n         unicorn\n         utility\n\n     • Default Value: nb\n```\n\n##### `default_extension`\n\n[↑](#-help) · See also: [Adding](#adding)\n\n```text\n[5]  default_extension\n     -----------------\n     The default extension to use for note files. Change to \"org\" for\n     Org files, \"rst\" for reStructuredText, \"txt\" for plain text, or\n     whatever you prefer.\n\n     • Default Value: md\n```\n\n##### `editor`\n\n[↑](#-help) · See also: [Editing](#editing), [Adding](#adding)\n\n```text\n[6]  editor\n     ------\n     The command line text editor used by `nb`.\n\n     • Example Values:\n\n         atom\n         code\n         emacs\n         hx\n         macdown\n         mate\n         micro\n         nano\n         pico\n         subl\n         vi\n         vim\n```\n\n##### `encryption_tool`\n\n[↑](#-help) · See also: [Password-Protected Encrypted Notes and Bookmarks](#password-protected-encrypted-notes-and-bookmarks)\n\n```text\n[7]  encryption_tool\n     ---------------\n     The tool used for encrypting notes.\n\n     • Supported Values: openssl, gpg\n     • Default Value:    openssl\n```\n\n##### `footer`\n\n[↑](#-help) · See also: [Listing & Filtering](#listing--filtering)\n\n```text\n[8]  footer\n     ------\n     By default, `nb` and `nb ls` include a footer with example commands.\n     To hide this footer, set this to \"0\".\n\n     • Default Value: 1\n```\n\n##### `header`\n\n[↑](#-help) · See also: [Listing & Filtering](#listing--filtering)\n\n```text\n[9]  header\n     ------\n     By default, `nb` and `nb ls` include a header listing available notebooks.\n     Set the alignment, or hide the header with \"0\".\n\n     • Supported Values:\n\n         0  Hide Header\n         1  Dynamic Alignment\n              - Left justified when list is shorter than terminal width.\n              - Center aligned when list is longer than terminal width.\n         2  Center Aligned (default)\n         3  Left Justified\n\n     • Default Value: 1\n```\n\n##### `limit`\n\n[↑](#-help) · See also: [Listing & Filtering](#listing--filtering)\n\n```text\n[10] limit\n     -----\n     The maximum number of items included in the `nb` and `nb ls` lists.\n     Set to `auto` to automatically limit output to the current terminal height.\n     Set a maximum auto limit with `auto^<max>`, e.g., `auto^15`.\n     Subtract an auto limit offset for multiline prompts with `auto-<offset>`.\n     Add an auto limit offet with `auto+<offset>`.\n     Combine both modifiers with `auto-<offset>^<max>` or `auto+<offset>^<max>`.\n\n     • Example Values:\n\n       15\n       auto\n       auto^15\n       auto-2\n       auto+2\n       auto-2^15\n       auto+2^15\n\n     • Default Value: 15\n```\n\n##### `nb_dir`\n\n[↑&nbsp;](#-help)\n\n```text\n[11] nb_dir\n     ------\n     The location of the directory that contains the notebooks.\n\n     For example, to sync all notebooks with Dropbox, create a folder at\n     `~/Dropbox/Notes` and run: `nb settings set nb_dir ~/Dropbox/Notes`\n\n     • Default Value: ~/.nb\n```\n\n##### `syntax_theme`\n\n[↑](#-help) · See also: [Terminal Syntax Highlighting](#terminal-syntax-highlighting-theme)\n\n```text\n[12] syntax_theme\n     ------------\n     The syntax highlighting theme. View examples with:\n\n         bat --list-themes\n\n     • Available themes:\n\n         1337\n         DarkNeon\n         Dracula\n         GitHub\n         Monokai Extended\n         Monokai Extended Bright\n         Monokai Extended Light\n         Monokai Extended Origin\n         Nord\n         OneHalfDark\n         OneHalfLight\n         Solarized (dark)\n         Solarized (light)\n         Sublime Snazzy\n         TwoDark\n         ansi-dark\n         ansi-light\n         base16\n         base16-256\n         gruvbox\n         gruvbox-light\n         gruvbox-white\n         zenburn\n\n     • Default Value: base16\n```\n\n#### `shell`\n\n[↑](#-help) · See also:\n[Interactive Shell](#-interactive-shell),\n[`run`](#run)\n\n```text\nUsage:\n  nb shell [<subcommand> [<options>...] | --clear-history]\n\nOptions:\n  --clear-history  Clear the `nb` shell history.\n\nDescription:\n  Start the `nb` interactive shell. Type \"exit\" to exit.\n\n  `nb shell` recognizes all `nb` subcommands and options, providing\n  a streamlined, distraction-free approach for working with `nb`.\n\n  When <subcommand> is present, the command will run as the shell is opened.\n\nRead More:\n  https://github.com/xwmx/nb#-interactive-shell\n\nSee Also:\n  nb help run\n\nExample:\n  $ nb shell\n  nb> ls 3\n  [3] Example\n\n  nb> edit 3 --content \"New content.\"\n  Updated: [3] Example\n\n  nb> notebook\n  home\n\n  nb> exit\n  $\n```\n\n#### `show`\n\n[↑](#-help) · See also:\n[Viewing](#viewing),\n[Images](#-images),\n[`browse`](#browse),\n[`open`](#open),\n[`peek`](#peek)\n\n```text\nUsage:\n  nb show ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[-a | --added] | [--authors] | [-b | --browse] | --filename | --id |\n          --info-line | --path | [-p | --print] | --relative-path | [-r |\n          --render] | --title | --type [<type>] | [-u | --updated]] [--no-color]\n  nb show <notebook>\n\nOptions:\n  -a, --added      Print the date and time when the item was added.\n  --authors        List the git commit authors of an item.\n  -b, --browse     Open the item with `nb browse`.\n  --filename       Print the filename of the item.\n  --id             Print the id number of the item.\n  --info-line      Print the id, filename, and title of the item.\n  --no-color       Show without syntax highlighting.\n  --path           Print the full path of the item.\n  -p, --print      Print to standard output / terminal.\n  --relative-path  Print the item's path relative within the notebook.\n  -r, --render     Use `pandoc` [1] to render the file to HTML and display\n                   in the terminal web browser. If either `pandoc` or a\n                   browser are unavailable, `-r` / `--render` is ignored.\n  --title          Print the title of the note.\n  --type [<type>]  Print the file extension or, when <type> is specified,\n                   return true if the item matches <type>. <type> can be a\n                   file extension or one of the following types:\n                   archive, audio, bookmark, document, folder, image,\n                   text, video\n  -u, --updated    Print the date and time of the last recorded change.\n\nDescription:\n  Show an item or notebook. Notes in text file formats can be rendered or\n  printed to standard output. Non-text files are opened in your system's\n  preferred app or program for that file type.\n\n  By default, the item is opened using `less` or the program configured\n  in the `$PAGER` environment variable. Use the following keys to navigate\n  in `less` (see `man less` for more information):\n\n    Key               Function\n    ---               --------\n    mouse scroll      Scroll up or down\n    arrow up or down  Scroll one line up or down\n    f                 Jump forward one window\n    b                 Jump back one window\n    d                 Jump down one half window\n    u                 Jump up one half window\n    /<query>          Search for <query>\n    n                 Jump to next <query> match\n    q                 Quit\n\n  To skip the pager and print to standard output, use the `-p` / `--print`\n  option.\n\n  `-r` / `--render` automatically uses either `w3m` [2] or `links` [3].\n  To specify a preferred browser, set the `$BROWSER` environment variable\n  in your .bashrc, .zshrc, or equivalent, e.g.: export BROWSER=\"links\"\n\n  If `bat` [4], `highlight` [5], or Pygments [6] is installed, notes are\n  printed with syntax highlighting.\n\n    1. https://pandoc.org/\n    2. https://en.wikipedia.org/wiki/W3m\n    3. https://en.wikipedia.org/wiki/Links_(web_browser)\n    4. https://github.com/sharkdp/bat\n    5. http://www.andre-simon.de/doku/highlight/en/highlight.php\n    6. https://pygments.org/\n\nRead More:\n  https://github.com/xwmx/nb#viewing\n\nSee Also:\n  nb help browse\n  nb help open\n  nb help peek\n\nExamples:\n  nb show 1\n  nb show example.md --render\n  nb show \"A Document Title\" --print --no-color\n  nb 1 show\n  nb example:show 12\n  nb show example:12\n  nb example:12 show\n  nb s 1\n  nb 1 s\n  nb s example:12\n  nb example:12 s\n\nAlias:\n  nb view\n\nShortcut Alias:\n  nb s\n```\n\n#### `status`\n\n[↑](#-help) · See also:\n[Git Sync](#-git-sync),\n[History](#-revision-history),\n[`archive`](#archive),\n[`history`](#history),\n[`notebooks`](#notebooks),\n[`remote`](#remote),\n[`sync`](#sync),\n[`unarchive`](#unarchive)\n\n```text\nUsage:\n  nb status [<notebook>]\n\nDescription:\n  Print archival, git, and remote status for the current notebook or <notebook>.\n\nRead More:\n  https://github.com/xwmx/nb#-git-sync\n  https://github.com/xwmx/nb#-revision-history\n\nSee Also:\n  nb help archive\n  nb help history\n  nb help notebooks\n  nb help remote\n  nb help sync\n  nb help unarchive\n\nExamples:\n  nb status\n  nb status example\n\nShortcut Alias:\n  nb st\n```\n\n#### `subcommands`\n\n[↑](#-help) · See also:\n[Plugins](#-plugins),\n[`plugins`](#plugins)\n\n```text\nUsage:\n  nb subcommands [add <name>...] [alias <name> <alias>]\n                 [describe <name> <usage>]\n\nSubcommands:\n  add       Add a new subcommand.\n  alias     Create an <alias> of a given subcommand <name>, with linked help.\n            Note that aliases must also be added with `subcommands add`.\n  describe  Set the usage text displayed with `nb help <subcommand>`.\n            This can be assigned as a heredoc, which is recommended, or\n            as a string argument.\n\nDescription:\n  List, add, alias, and describe subcommands. New subcommands, aliases, and\n  descriptions are not persisted, so `add`, `alias`, `describe` are\n  primarily for plugins.\n\nRead More:\n  https://github.com/xwmx/nb#-plugins\n\nSee Also:\n  nb help plugins\n```\n\n#### `sync`\n\n[↑](#-help) · See also:\n[Git Sync](#-git-sync),\n[History](#-revision-history),\n[`history`](#history),\n[`notebooks`](#notebooks),\n[`remote`](#remote),\n[`status`](#status)\n\n```text\nUsage:\n  nb sync [-a | --all]\n\nOptions:\n  -a, --all   Sync all unarchived notebooks.\n\nDescription:\n  Sync the current notebook with its remote.\n\nPrivate Repositories and Git Credentials:\n  Syncing with private repositories requires configuring git to not prompt\n  for credentials.\n\n  For repositories cloned over HTTPS, credentials can be cached with git.\n  For repositories cloned over SSH, keys can be added to the ssh-agent.\n\n  More Information:\n    https://github.com/xwmx/nb#private-repositories-and-git-credentials\n\nSync Conflict Resolution:\n  When `nb sync` encounters a conflict in a text file and can't merge\n  overlapping local and remote changes, both versions are saved in the\n  file, separated by git conflict markers. Use `nb edit` to remove the\n  conflict markers and delete any unwanted text.\n\n  When `nb sync` encounters a conflict in a binary file, such as an\n  encrypted note or bookmark, both versions of the file are saved in the\n  notebook as individual files, one with `--conflicted-copy` appended to\n  the filename.\n\n  More Information:\n    https://github.com/xwmx/nb#sync-conflict-resolution\n\nRead More:\n  https://github.com/xwmx/nb#-git-sync\n  https://github.com/xwmx/nb#-revision-history\n\nSee Also:\n  nb help history\n  nb help notebooks\n  nb help remote\n  nb help status\n\nExamples:\n  nb sync\n  nb sync --all\n```\n\n#### `tasks`\n\n[↑](#-help) · See also:\n[Tasks](#%EF%B8%8F-tasks),\n[Todos](#-todos),\n[`do`](#do),\n[`todo`](#todo),\n[`undo`](#undo)\n\n```text\nUsage:\n  nb tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n           [open | closed] [--pager]\n\nOptions:\n  --pager  Display output in the pager.\n\nDescription:\n  List tasks in todos, notebooks, folders, and other items.\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-tasks\n  https://github.com/xwmx/nb#-todos\n\nSee Also:\n  nb help do\n  nb help todo\n  nb help undo\n\nExamples:\n  nb tasks\n  nb tasks open\n  nb tasks closed\n  nb tasks 123\n  nb example:tasks open\n  nb tasks closed sample/\n  nb tasks closed demo:456\n\nShortcut Alias:\n  nb t\n```\n\n#### `todo`\n\n[↑](#-help) · See also:\n[Todos](#-todos),\n[`do`](#do),\n[`tasks`](#tasks),\n[`undo`](#undo)\n\n```text\nUsage:\n  nb todo add [<notebook>:][<folder-path>/][<filename>] <title>\n              [--description <description>] [--due <date>]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]\n              [--tags <tag1>,<tag2>...] [--task <title>...]\n  nb todo delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb todo do   ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  nb todo undo ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  nb todos [<notebook>:][<folder-path>/] [open | closed] [--pager]\n               [--tags <tag1>,<tag2>...]\n  nb todos tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n                 [open | closed] [--pager]\n\nOptions:\n  --description <description>         Description for the todo.\n  --due <date>                        Due date and / or time for the todo.\n  --pager                             Display output in the pager.\n  -r, --related (<url> | <selector>)  Related URL or selector.\n  --tags <tag1>,<tag2>...             Comma-separated list of tags.\n  --task <title>                      Task to add to the tasklist.\n\nSubcommands:\n  (default)   List todos.\n  add         Add a new todo.\n              Shortcut Aliases: `nb todo a`, `nb todo +`\n  delete      Delete a todo.\n              Shortcut Aliases: `nb todo -`\n  do          Mark a todo or task as done.\n  tasks       List tasks in todos, notebooks, folders, and other item.\n  undo        Unmark a todo or task as done.\n\nDescription:\n  Manage todos and tasks.\n\nRead More::\n  https://github.com/xwmx/nb#-todos\n\nSee Also:\n  nb help do\n  nb help tasks\n  nb help undo\n\nExamples:\n  nb todo add \"Example todo title.\"\n  nb todo add Example todo title.\n  nb todo add \"Sample title.\" --tags tag1,tag2 --related demo:567\n  nb todos\n  nb todos open\n  nb todos closed\n  nb example:todos open\n  nb todos closed sample/\n\nAlias:\n  nb todos\n\nShortcut Alias:\n  nb to\n```\n\n#### `unarchive`\n\n[↑](#-help) · See also:\n[Archiving Notebooks](#archiving-notebooks),\n[`archive`](#archive),\n[`notebooks`](#notebooks),\n[`status`](#status)\n\n```text\nUsage:\n  nb unarchive [<name>]\n\nDescription:\n  Remove \"archived\" status from the current notebook or notebook <name>.\n\n  This is an alias for `nb notebooks unarchive`.\n\nRead More:\n  https://github.com/xwmx/nb#archiving-notebooks\n\nSee Also:\n  nb help archive\n  nb help notebooks\n  nb help status\n\nExamples:\n  nb unarchive\n  nb unarchive example\n\nShortcut Alias:\n  nb unar\n```\n\n#### `undo`\n\n[↑](#-help) · See also:\n[Todos](#-todos),\n[Tasks](#%EF%B8%8F-tasks),\n[`do`](#do),\n[`tasks`](#tasks),\n[`todo`](#todo)\n\n```text\nUsage:\n  nb undo ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [<task-number>]\n\nDescription:\n  Mark a todo or task as not done.\n\nRead More:\n  https://github.com/xwmx/nb#-todos\n\nSee Also:\n  nb help do\n  nb help tasks\n  nb help todo\n\nExamples:\n  nb undo 123\n  nb undo example:sample/321\n  nb undo 543 7\n```\n\n#### `unpin`\n\n[↑](#-help) · See also:\n[Pinning](#-pinning),\n[`browse`](#browse),\n[`list`](#list),\n[`ls`](#ls),\n[`pin`](#pin)\n\n```text\nUsage:\n  nb unpin ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\nDescription:\n  Unpin a pinned item.\n\nRead More:\n  https://github.com/xwmx/nb#-pinning\n\nSee Also:\n  nb help browse\n  nb help list\n  nb help ls\n  nb help pin\n\nExamples:\n  nb unpin 123\n  nb unpin example:sample/321\n```\n\n#### `unset`\n\n[↑](#-help) · See also:\n[`set` & `settings`](#%EF%B8%8F-set--settings),\n[`settings`](#settings)\n\n```text\nUsage:\n  nb unset (<name> | <number>)\n\nDescription:\n  Unset a setting, returning it to the default value.\n\n  This is an alias for `nb settings unset`.\n\nRead More:\n  https://github.com/xwmx/nb#%EF%B8%8F-set--settings\n\nSee Also:\n  nb help settings\n\nExamples:\n  nb unset color_primary\n  nb unset 2\n\nAlias:\n  nb reset\n```\n\n#### `update`\n\n[↑](#-help) · See also:\n[Installation](#installation),\n[`env`](#env),\n[`version`](#version)\n\n```text\nUsage:\n  nb update\n\nDescription:\n  Update `nb` to the latest version. You will be prompted for\n  your password if administrator privileges are required.\n\n  If `nb` was installed using a package manager like npm or\n  Homebrew, use the package manager's upgrade functionality instead\n  of this command.\n\nRead More:\n  https://github.com/xwmx/nb#installation\n\nSee Also:\n  nb help env\n  nb help version\n```\n\n#### `use`\n\n[↑](#-help) · See also:\n[Notebooks](#-notebooks),\n[`notebooks`](#notebooks)\n\n```text\nUsage:\n  nb use <notebook>\n\nDescription:\n  Switch to the specified notebook. Shortcut for `nb notebooks use`.\n\nRead More:\n  https://github.com/xwmx/nb#-notebooks\n\nSee Also:\n  nb help notebooks\n\nExample:\n  nb use example\n\nShortcut Alias:\n  nb u\n```\n\n#### `version`\n\n[↑](#-help) · See also:\n[Installation](#installation),\n[`env`](#env),\n[`update`](#update)\n\n```text\nUsage:\n  nb version\n\nDescription:\n  Display version information.\n\nSee Also:\n  nb help env\n  nb help update\n```\n\n### Plugin Help\n\n<p>\n  <sup>\n    <a href=\"#-help\">↑</a> ·\n    <a href=\"#-plugins\">Plugins</a>,\n    <a href=\"#plugins\"><code>nb plugins</code></a>\n  </sup>\n</p>\n\n<div align=\"center\">\n  <a href=\"#backlink\">backlink</a>&nbsp;·\n  <a href=\"#bump\">bump</a>&nbsp;·\n  <a href=\"#clip\">clip</a>&nbsp;·\n  <a href=\"#daily\">daily</a>&nbsp;·\n  <a href=\"#ebook\">ebook</a>&nbsp;·\n  <a href=\"#example\">example</a>&nbsp;·\n  <a href=\"#weather\">weather</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#-help\">&nbsp;↑&nbsp;</a>\n</div>\n\n#### `backlink`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/backlink.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb backlink [--force]\n\nDescription:\n  Add backlinks to notes. Crawl notes in a notebook for [[wiki-style links]]\n  and append a \"Backlinks\" section to each linked file that lists passages\n  referencing the note.\n\n  To link to a note from within another note, surround the title of the\n  target note in double square brackets:\n\n      Example with link to [[Target Note Title]] in content.\n\n  Depends on note-link-janitor:\n    https://github.com/andymatuschak/note-link-janitor\n\n    Requirement: every note in the notebook must have a title.\n```\n\n#### `bump`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/bump.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb bump [<notebook>:][<folder-path>/][<id>][<filename>][<title>]\n\nDescription:\n  Bump an item to the top of the list.\n\n  `bump` updates the item's modification timestamp without editing the item\n  or creating a new commit.\n\nExamples:\n  nb bump 123\n  nb bump example:sample/456\n\nAlias:\n  nb touch\n```\n\n#### `clip`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/clip.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb clip [<notebook>:][<id> | <filename> | <path> | <title> | <extension>]\n\nDescription:\n  Save the clipboard contents and copy contents of text or markdown items to\n  the clipboard.\n\n  When called with no arguments or when no matching file is found, the text\n  content on the clipboard is saved to a new file, pending a prompt.\n\nExamples:\n  # copy the content of item 123 to the clipboard\n  nb clip 123\n\n  # save the clipboard contents to a new file with a `.js` file extension\n  nb clip .js\n\n  # save the clipboard contents as a new `.cr` file in the \"snippets\" notebook\n  nb snippets:clip .cr\n```\n\n#### `daily`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/daily.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb daily [<content>] [--prev [<number>]]\n\nOptions:\n  --prev [<number>]   List previous days and show day by previous <number>.\n\nDescription:\n  Add notes to a daily log. When called without arguments, the current day's\n  log is displayed. When passed `<content>`, a new timestamped entry is added\n  to the current day's log, which is created if it doesn't yet exist.\n\n  Previous day's logs can be listed with the `--prev` option. View a previous\n  day's log by passing its `<number>` in the list.\n\nExamples:\n  nb daily \"Example note content.\"\n  nb daily\n  nb daily --prev\n  nb daily --prev 3\n```\n\n#### `ebook`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/ebook.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb ebook new <name>\n  nb ebook publish\n\nSubcommands:\n  ebook new      Create a new notebook initialized with placeholder files for\n                 authoring an ebook.\n  ebook publish  Generate a .epub file using the current notebook contents.\n\nDescription:\n  Ebook authoring with `nb`.\n\n  `nb ebook new` creates a notebook populated with initial placeholder files\n  for creating an ebook. Edit the title page and chapters using normal `nb`\n  commands, then use `nb ebook publish` to generate an epub file.\n\n  Chapters are expected to be markdown files with sequential numeric\n  filename prefixes for ordering:\n\n    01-example.md\n    02-sample.md\n    03-demo.md\n\n  Create new chapters with `nb add`:\n\n    nb add --filename \"04-chapter4.md\"\n\n  title.txt contains the book metadata in a YAML block. For more information\n  about the fields for this file, visit:\n\n    https://pandoc.org/MANUAL.html#epub-metadata\n\n  stylesheet.css contains base styling for the generated ebook. It can be used\n  as it is and can also be edited using `nb edit`.\n\n  As with all `nb` notebooks, changes are recorded automatically in git,\n  providing automatic version control for all ebook content, source, and\n  metadata files.\n\n  Generated epub files are saved in the notebook and can be previewed in the\n  terminal with `nb show`. Export a generated epub file with `nb export`:\n\n    nb export 12 .\n\nMore info:\n  https://pandoc.org/epub.html\n```\n\n#### `example`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/example.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb example\n\nDescription:\n  Print \"Hello, World!\"\n```\n\n#### `weather`\n\n[↑&nbsp;](#plugin-help)\n\n##### Install\n\n```bash\nnb plugins install https://github.com/xwmx/nb/blob/master/plugins/weather.nb-plugin\n```\n\n##### Help\n\n```text\nUsage:\n  nb weather [<option>...]\n\nDescription:\n  Display weather information from wttr.in.\n\nMore Info:\n  https://github.com/chubin/wttr.in\n  https://wttr.in\n\nExamples:\n  nb weather\n  nb weather Tokyo\n  nb weather lax\n\nShortcut Alias:\n  nb w\n```\n\n### `$` Variables\n\n<p>\n  <sup>\n    <a href=\"#overview\">↑</a> ·\n    <a href=\"#%EF%B8%8F-set--settings\"><code>set</code>&<code>settings</code></a>,\n    <a href=\"#settings\"><code>nb settings</code></a>\n  </sup>\n</p>\n\n<div align=\"center\">\n  <sup>\n    <a href=\"#editor-1\"><code>$EDITOR</code></a>&nbsp;·\n    <a href=\"#nb_ace_enabled\"><code>$NB_ACE_ENABLED</code></a>&nbsp;·\n    <a href=\"#nb_ace_md_gutter\"><code>$NB_ACE_MD_GUTTER</code></a>&nbsp;·\n    <a href=\"#nb_ace_relative_line_numbers\"><code>$NB_ACE_RELATIVE_LINE_NUMBERS</code></a>&nbsp;·\n    <a href=\"#nb_ace_soft_tabs\"><code>$NB_ACE_SOFT_TABS</code></a>&nbsp;·\n    <a href=\"#nb_ace_keyboard\"><code>$NB_ACE_KEYBOARD</code></a>&nbsp;·\n    <a href=\"#nb_audio_tool\"><code>$NB_AUDIO_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_auto_sync\"><code>$NB_AUTO_SYNC</code></a>&nbsp;·\n    <a href=\"#nb_auto_sync_seconds\"><code>$NB_AUTO_SYNC_SECONDS</code></a>&nbsp;·\n    <a href=\"#nb_bookmark_content_cleanup_tool\"><code>$NB_BOOKMARK_CONTENT_CLEANUP_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_bookmark_content_conversion_tool\"><code>$NB_BOOKMARK_CONTENT_CONVERSION_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_browse_markdown_reader\"><code>$NB_BROWSE_MARKDOWN_READER</code></a>&nbsp;·\n    <a href=\"#nb_browse_server_tool\"><code>$NB_BROWSE_SERVER_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_browse_support_links\"><code>$NB_BROWSE_SUPPORT_LINKS</code></a>&nbsp;·\n    <a href=\"#nb_browser\"><code>$NB_BROWSER</code></a>&nbsp;·\n    <a href=\"#nb_color_primary\"><code>$NB_COLOR_PRIMARY</code></a>&nbsp;·\n    <a href=\"#nb_color_secondary\"><code>$NB_COLOR_SECONDARY</code></a>&nbsp;·\n    <a href=\"#nb_color_theme\"><code>$NB_COLOR_THEME</code></a>&nbsp;·\n    <a href=\"#nb_custom_css\"><code>$NB_CUSTOM_CSS</code></a>&nbsp;·\n    <a href=\"#nb_custom_css_url\"><code>$NB_CUSTOM_CSS_URL</code></a>&nbsp;·\n    <a href=\"#nb_custom_javascript\"><code>$NB_CUSTOM_JAVASCRIPT</code></a>&nbsp;·\n    <a href=\"#nb_custom_javascript_url\"><code>$NB_CUSTOM_JAVASCRIPT_URL</code></a>&nbsp;·\n    <a href=\"#nb_data_tool\"><code>$NB_DATA_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_default_extension\"><code>$NB_DEFAULT_EXTENSION</code></a>&nbsp;·\n    <a href=\"#nb_default_template\"><code>$NB_DEFAULT_TEMPLATE</code></a>&nbsp;·\n    <a href=\"#nb_dir-1\"><code>$NB_DIR</code></a>&nbsp;·\n    <a href=\"#nb_directory_tool\"><code>$NB_DIRECTORY_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_editor\"><code>$NB_EDITOR</code></a>&nbsp;·\n    <a href=\"#nb_encryption_tool\"><code>$NB_ENCRYPTION_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_folders_first\"><code>$NB_FOLDERS_FIRST</code></a>&nbsp;·\n    <a href=\"#nb_footer\"><code>$NB_FOOTER</code></a>&nbsp;·\n    <a href=\"#nb_gui_browser\"><code>$NB_GUI_BROWSER</code></a>&nbsp;·\n    <a href=\"#nb_header\"><code>$NB_HEADER</code></a>&nbsp;·\n    <a href=\"#nb_image_tool\"><code>$NB_IMAGE_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_indicator_audio\"><code>$NB_INDICATOR_AUDIO</code></a>&nbsp;·\n    <a href=\"#nb_indicator_bookmark\"><code>$NB_INDICATOR_BOOKMARK</code></a>&nbsp;·\n    <a href=\"#nb_indicator_document\"><code>$NB_INDICATOR_DOCUMENT</code></a>&nbsp;·\n    <a href=\"#nb_indicator_ebook\"><code>$NB_INDICATOR_EBOOK</code></a>&nbsp;·\n    <a href=\"#nb_indicator_encrypted\"><code>$NB_INDICATOR_ENCRYPTED</code></a>&nbsp;·\n    <a href=\"#nb_indicator_folder\"><code>$NB_INDICATOR_FOLDER</code></a>&nbsp;·\n    <a href=\"#nb_indicator_image\"><code>$NB_INDICATOR_IMAGE</code></a>&nbsp;·\n    <a href=\"#nb_indicator_pinned\"><code>$NB_INDICATOR_PINNED</code></a>&nbsp;·\n    <a href=\"#nb_indicator_todo\"><code>$NB_INDICATOR_TODO</code></a>&nbsp;·\n    <a href=\"#nb_indicator_todo_done\"><code>$NB_INDICATOR_TODO_DONE</code></a>&nbsp;·\n    <a href=\"#nb_indicator_video\"><code>$NB_INDICATOR_VIDEO</code></a>&nbsp;·\n    <a href=\"#nb_limit\"><code>$NB_LIMIT</code></a>&nbsp;·\n    <a href=\"#nb_mathjax_enabled\"><code>$NB_MATHJAX_ENABLED</code></a>&nbsp;·\n    <a href=\"#nb_markdown_tool\"><code>$NB_MARKDOWN_TOOL</code></a>&nbsp;·\n    <a href=\"#nb_pinned_pattern\"><code>$NB_PINNED_PATTERN</code></a>&nbsp;·\n    <a href=\"#nb_server_host\"><code>$NB_SERVER_HOST</code></a>&nbsp;·\n    <a href=\"#nb_server_port\"><code>$NB_SERVER_PORT</code></a>&nbsp;·\n    <a href=\"#nb_syntax_theme\"><code>$NB_SYNTAX_THEME</code></a>&nbsp;·\n    <a href=\"#nb_user_agent\"><code>$NB_USER_AGENT</code></a>&nbsp;·\n    <a href=\"#nbrc_path\"><code>$NBRC_PATH</code></a>\n    </sup>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#overview\">&nbsp;↑&nbsp;</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n[Settings](#%EF%B8%8F-set--settings) are set in the `~/.nbrc` configuration\nfile using environment variables. Settings can be set through `nb`\nusing [`set` & `settings`](#%EF%B8%8F-set--settings) or by\nassigning a value to the variable directly in the `~/.nbrc` file, which\ncan be opened in your `$EDITOR` with [`nb settings edit`](#settings).\n\nExample assignment:\n\n```bash\nexport NB_INDICATOR_PINNED=\"🔮\"\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$EDITOR`\n\n```text\nThe terminal editor command for editing items.\n\nSee also: `$NB_EDITOR`\n\nExample Values: 'code', 'emacs', 'hx', 'vim'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_ENABLED`\n\n```text\nDefault: '0'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_MD_GUTTER`\n\n```text\nDefault: '1'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_RELATIVE_LINE_NUMBERS`\n\n```text\nDefault: '0'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_SOFT_TABS`\n\n```text\nDefault: '0'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ACE_KEYBOARD`\n\n```text\nDefault: 'ace'\n\nExample Values: 'emacs', 'sublime', 'vim', 'vscode'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_AUDIO_TOOL`\n\n```text\nDefault: '' (first available)\n\nExample Values: 'mplayer', 'afplay'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_AUTO_SYNC`\n\n```text\nDefault: '1'\n\nWhen set to '1', each `_git checkpoint()` call will automativally run\n`$_ME sync`. To disable this behavior, set the value to '0'.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_AUTO_SYNC_SECONDS`\n\n```text\nDefault: '60'\n\nThe minimum number of seconds between automatic Git sync operations when\n`$NB_AUTO_SYNC` is enabled.\n\nSupported Values: '0' or any positive integer\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BOOKMARK_CONTENT_CLEANUP_TOOL`\n\n```text\nDefault: 'readability'\n\nThe tool used to clean up HTML content before conversion to markdown\nwhen creating bookmarks.\n\nSupported Tools:\n\n- https://www.npmjs.com/package/readability-cli\n- https://github.com/eafer/rdrview\n\nSupported Values: '', 'rdrview', 'readability'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BOOKMARK_CONTENT_CONVERSION_TOOL`\n\n```text\nDefault: 'pandoc'\n\nThe tool used to convert HTML content to markdown when creating\nbookmarks.\n\nSupported Tools:\n\n- https://github.com/JohannesKaufmann/html-to-markdown\n- https://github.com/microsoft/markitdown\n- https://pandoc.org\n\nSupported Values: '', 'html-to-markdown', 'markitdown', 'pandoc'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BROWSE_MARKDOWN_READER`\n\n```text\n$NB_BROWSE_MARKDOWN_READER\n\nDefault: 'markdown+emoji+raw_html+east_asian_line_breaks'\n\nThe Pandoc reader, including extensions, to use for converting Markdown to\nHTML in `nb browse`.\n\nMore information:\n  https://pandoc.org/MANUAL.html#extensions\n  https://pandoc.org/MANUAL.html#general-options-1\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BROWSE_SERVER_TOOL`\n\n```text\nDefault: first available: 'ncat', 'socat', 'netcat', 'bash' (5.2+ only), ''\n\nThe tool used to listen on the server host and port and respond to\nincoming requests.\n\nSupported Values: 'accept', 'bash', 'nc', 'ncat', netcat', 'socat'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BROWSE_SUPPORT_LINKS`\n\n```text\nDefault: '1'\n\nSet to '0' to hide the 'Donate' and 'Sponsor' links in `nb browse`.\n\nSupported Values: '0' '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_BROWSER`\n\n```text\nDefault: value of $BROWSER\n\nExample Values: 'links', 'w3m'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_COLOR_PRIMARY`\n\n```text\nDefault: Value depends on terminal capabilities.\n\nSet highlighting color. This should be set to an xterm color number, usually\na value between 1 and 256. For a table of common colors and their numbers\nrun:\n\n  nb settings colors\n\nSupported Values: [0..255+]\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_COLOR_SECONDARY`\n\n```text\nDefault: '8'\n\nColor for lines and other accents. This should be set to an xterm color\nnumber, usually a value between 1 and 256. For a table of common colors and\ntheir numbers, run:\n\n  nb settings colors\n\nSupported Values: [0..255+]\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_COLOR_THEME`\n\n```text\nDefault: 'nb'\n\nThe color theme.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_CUSTOM_CSS`\n\n```text\nDefault: ''\n\nA style sheet to be included inline in a `<style>` element on pages\nrendered by `nb browse`.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_CUSTOM_CSS_URL`\n\n```text\nDefault: ''\n\nA URL to a style sheet to be included in a `<link rel=\"stylesheet\">`\nelement on pages rendered by `nb browse`.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_CUSTOM_JAVASCRIPT`\n\n```text\nDefault: ''\n\nA block of JavaScript code to be included inline in a `<script>` element\non pages rendered by `nb browse`.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_CUSTOM_JAVASCRIPT_URL`\n\n```text\nDefault: ''\n\nA URL to a JavaScript file to be included in a `<script src=//url>`\nelement on pages rendered by `nb browse`.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DATA_TOOL`\n\n```text\nDefault: '' (first available)\n\nExample Values: 'visidata', 'sc-im'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DEFAULT_EXTENSION`\n\n```text\nDefault: 'md'\n\nExample Values: 'md' 'org'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DEFAULT_TEMPLATE`\n\n```text\nDefault: ''\n\nA string template or a path to a template file.\n\nExample Values: '/path/to/template/file' '# {{title}} {{content}}'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DIR`\n\n```text\nDefault: `$HOME/.nb`\n\nThe location of the directory that contains the notebooks.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_DIRECTORY_TOOL`\n\n```text\nDefault: '' (nb browse)\n\nExample Values: 'ranger', 'mc'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_EDITOR`\n\n```text\nDefault: the value of `$EDITOR`\n\nThe terminal editor command for editing items. Overrides the value of\n`$EDITOR` in the environment.\n\nSee also: `$EDITOR`\n\nExample Values: 'code', 'emacs', 'hx', 'vim'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_ENCRYPTION_TOOL`\n\n```text\nDefault: 'openssl'\n\nSupported Values: 'gpg' 'openssl'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_FOLDERS_FIRST`\n\n```text\nDefault: '0'\n\nWhen set to '1', folders are printed before other items in `nb`, `nb ls`,\nand `nb browse`.\n\nSupported Values: '0' '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_FOOTER`\n\n```text\nDefault: '1'\n\nSupported Values: '0' '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_GUI_BROWSER`\n\n```text\nDefault: ''\n\nExample Value: 'firefox'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_HEADER`\n\n```text\nDefault: '2'\n\nSupported Values: '0' '1' '2' '3'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_IMAGE_TOOL`\n\n```text\nDefault: '' (first available)\n\nExample Values: 'imgcat', 'catimg'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_AUDIO`\n\n```text\nDefault: 🔉\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_BOOKMARK`\n\n```text\nDefault: 🔖\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_DOCUMENT`\n\n```text\nDefault: 📄\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_EBOOK`\n\n```text\nDefault: 📖\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_ENCRYPTED`\n\n```text\nDefault: 🔒\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_FOLDER`\n\n```text\nDefault: 📂\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_IMAGE`\n\n```text\nDefault: 🌄\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_PINNED`\n\n```text\nDefault: 📌\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_TODO`\n\n```text\nDefault: ✔️\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_TODO_DONE`\n\n```text\nDefault: ✅\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_INDICATOR_VIDEO`\n\n```text\nDefault: 📹\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_LIMIT`\n\n```text\nDefault: '15'\n\nSet to a positive number to limit the output of `nb` and `nb ls` to that value.\nSet to \"auto\" to automatically limit output to the current terminal height.\nSet a maximum auto limit with `auto^<max>`, e.g., `auto^15`.\nSubtract an auto limit offset for multiline prompts with `auto-<offset>`.\nAdd an auto limit offet with `auto+<offset>`.\nCombine both modifiers with `auto-<offset>^<max>` or `auto+<offset>^<max>`.\n\nSupported Values:\n  - <max>\n  - auto\n  - auto^<max>\n  - auto-<offset>\n  - auto+<offset>\n  - auto-<offset>^<max>\n  - auto+<offset>^<max>\n\nExample Values:\n  - 15\n  - auto\n  - auto^15\n  - auto-2\n  - auto+2\n  - auto-2^15\n  - auto+2^15\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_MATHJAX_ENABLED`\n\n```text\nDefault: '0'\n\nExample Values: '0', '1'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_MARKDOWN_TOOL`\n\n```text\nDefault: '' (default pager)\n\nSupported Values: 'bat', 'glow', 'lowdown', 'mdcat', 'mdless', 'mdv'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_PINNED_PATTERN`\n\n```text\nExample Value: '#pinned'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_SERVER_HOST`\n\n```text\nDefault: 'localhost'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_SERVER_PORT`\n\n```text\nDefault: '6789'\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_SYNTAX_THEME`\n\n```text\nDefault: 'base16'\n\nSupported Values: Theme names listed with `bat --list-themes`\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NB_USER_AGENT`\n\n```text\nDefault: '' (`curl` or `wget` default user agent)\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n##### `$NBRC_PATH`\n\n```text\nDefault: `$HOME/.nbrc`\n\nThe location of the .nbrc configuration file.\n```\n\n<p>\n  <sup>\n    <a href=\"#-variables\">↑</a>\n  </sup>\n</p>\n\n## Specifications\n\n<div align=\"center\">\n  <a href=\"#nb-markdown-bookmark-file-format\">Bookmark File Format</a>&nbsp;·\n  <a href=\"#nb-markdown-todo-file-format\">Todo File Format</a>&nbsp;·\n  <a href=\"#nb-notebook-specification\">Notebook Specification</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n<div align=\"center\">\n  <a href=\"#-help\">&nbsp;↑&nbsp;</a>\n</div>\n\n<p align=\"center\"></p><!-- spacer -->\n\n### `nb` Markdown Bookmark File Format\n\n<p>\n  <sup>\n    <a href=\"#specifications\">↑</a> ·\n    <a href=\"#-bookmarks\">Bookmarks</a>,\n    <a href=\"#bookmark\"><code>nb bookmark</code></a>\n  </sup>\n</p>\n\n#### Extension\n\n`.bookmark.md`\n\n#### Description\n\n`nb` bookmarks are Markdown documents created using a combination of\nuser input and data from the bookmarked page. The `nb` bookmark format\nis intended to be readable, editable, convertible, renderable, and\nclearly organized for greatest accessibility.\n\nBookmarks are identified by a `.bookmark.md` file extension. The\nbookmark URL is the first URL in the file within `<` and `>` characters.\nTo create a minimally valid bookmark file with [`nb add`](#add):\n\n```bash\nnb add example.bookmark.md --content \"<https://example.com>\"\n```\n\nThis creates a file with the name `example.bookmark.md` containing:\n\n```markdown\n<https://example.com>\n```\n\nIn a full bookmark, information is separated into sections,\nwith each bookmark section indicated by a Markdown `h2` heading.\n\n#### Example\n\n````markdown\n# Example Title (example.com)\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Quote\n\n> Example quote line one.\n>\n> Example quote line two.\n\n## Comment\n\nExample comment.\n\n## Related\n\n- <https://example.net>\n- <https://example.org>\n- [[example:123]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\nExample Title\n=============\n\nThis domain is for use in illustrative examples in documents. You may\nuse this domain in literature without prior coordination or asking for\npermission.\n\n[More information\\...](https://www.iana.org/domains/example)\n\n## Source\n\n```html\n<!doctype html>\n<html>\n  <head>\n    <title>Example Title</title>\n    <meta name=\"description\" content=\"Example description.\" />\n  </head>\n\n  <body>\n    <h1>Example Title</h1>\n    <p>\n      This domain is for use in illustrative examples in documents. You may\n      use this domain in literature without prior coordination or asking for\n      permission.\n    </p>\n    <p>\n      <a href=\"https://www.iana.org/domains/example\">More information...</a>\n    </p>\n  </body>\n</html>\n```\n````\n\n#### Elements\n\n##### Title\n\n`Optional`\n\nA [Markdown atx-style `h1` heading\n](https://daringfireball.net/projects/markdown/syntax#header)\ncontaining the content of the bookmarked page's\nHTML `<title>` or [`og:title`](https://ogp.me/) tag, if present, followed by\nthe domain within parentheses.\n\n###### Examples\n\n```markdown\n# Example Title (example.com)\n```\n```markdown\n# (example.com)\n```\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### URL\n\n`Required`\n\nThe URL of the bookmarked resource, with surrounding angle brackets\n(`<`, `>`).\n\nThis is the only required element.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Description`\n\n`Optional`\n\nA text element containing the content of the bookmarked page's meta description\nor [`og:description`](https://ogp.me/) tag, if present.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Quote`\n\n`Optional`\n\nA markdown quote block containing a user-specified excerpt from the bookmarked\nresource.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Comment`\n\n`Optional`\n\nA text element containing a comment written by the user.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Related`\n\n`Optional`\n\nA Markdown list of\nangle bracketed (`<`, `>`) URLs and\n[[[wiki-style links]]](#-linking)\nthat are related to the bookmarked resource.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Tags`\n\n`Optional`\n\nA list of [#tags](#-tagging)\nrepresented as `#hashtags`\nseparated by individual spaces.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Content`\n\n`Optional`\n\nThe full content of the bookmarked page, converted to Markdown.\n\nThe `## Content` section makes the page content available locally for\nfull-text search and viewing of page content. The source HTML is converted\nto inline Markdown to reduce the amount of markup, make it more readable,\nand make page content easily viewable in the terminal as markdown and\nstreamlined HTML in web browsers.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Source`\n\n`Optional`\n\nA fenced code block with `html` language identifier containing the source HTML\nfrom the bookmarked page.\n\n`nb` does not save the page source by default. `nb` uses this section to save\nthe source HTML page content when `pandoc` is not available to convert it to\nMarkdown.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-bookmark-file-format\">↑</a>\n  </sup>\n</p>\n\n### `nb` Markdown Todo File Format\n\n<p>\n  <sup>\n    <a href=\"#specifications\">↑</a> ·\n    <a href=\"#-todos\">Todos</a>,\n    <a href=\"#todo\"><code>nb todo</code></a>\n  </sup>\n</p>\n\n#### Extension\n\n`.todo.md`\n\n#### Description\n\n`nb` todos are Markdown documents identified by a `.todo.md` file extension.\nTodos contain a Markdown `h1` heading\nstarting with a Markdown checkbox (`[ ]` / `[x]`) indicating\nthe todo completion state, followed by the todo title.\n\n#### Example\n\n```markdown\n# [x] Example todo title.\n\n## Due\n\n2100-01-01\n\n## Description\n\nExample description.\n\n## Tasks\n\n- [ ] One\n- [x] Two\n- [ ] Three\n\n## Related\n\n- [[example:123]]\n- <https://example.org>\n\n## Tags\n\n#tag1 #tag2\n```\n\n#### Elements\n\n##### Title\n\n`Required`\n\nA [Markdown atx-style `h1` heading\n](https://daringfireball.net/projects/markdown/syntax#header)\ncontaining a Markdown checkbox followed by the todo title.\nAn `x` within the checkbox (`[ ]`) indicates that the todo is done.\n\n###### Examples\n\n```markdown\n# [ ] Example undone / open todo title.\n```\n```markdown\n# [x] Example done / closed todo title.\n```\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Due`\n\n`Optional`\n\nA text element containing a value referencing\na due date and / or time for the todo.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Description`\n\n`Optional`\n\nA text element containing a description for the todo.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Tasks`\n\n`Optional`\n\nA markdown tasklist containing sub-tasks for the todo.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Related`\n\n`Optional`\n\nA Markdown list of\nangle bracketed (`<`, `>`) URLs and\n[[[wiki-style links]]](#-linking)\nthat are related to the todo.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n##### `## Tags`\n\n`Optional`\n\nA list of [#tags](#-tagging)\nrepresented as `#hashtags`\nseparated by individual spaces.\n\n<p>\n  <sup>\n    <a href=\"#nb-markdown-todo-file-format\">↑</a>\n  </sup>\n</p>\n\n### `nb` Notebook Specification\n\n<p>\n  <sup>\n    <a href=\"#specifications\">↑</a> ·\n    <a href=\"#-notebooks\">Notebooks</a>,\n    <a href=\"#notebooks\"><code>nb notebooks</code></a>\n  </sup>\n</p>\n\nAn `nb` notebook is a directory that contains a valid `.git` directory,\nindicating that it has been initialized as a git repository, and a `.index`\nfile in the root directory.\n\n#### `.index` Files\n\nA notebook folder index is a text file named `.index` in any folder\nwithin the notebook directory. `.index` contains a list of visible\nfilenames within the folder, one per line, and the line number of each\nfilename represents the id. `.index` files are included in the git repository\nso ids are preserved across systems.\n\n##### Operations\n\n<dl>\n  <dt><code>add</code></dt>\n  <dd>Append a new line containing the filename to <code>.index</code>.</dd>\n  <dt><code>update</code></dt>\n  <dd>Overwrite the existing filename in <code>.index</code> with the new filename.</dd>\n  <dt><code>delete</code></dt>\n  <dd>Delete the filename, preserving the newline, leaving the line blank.</dd>\n  <dt><code>reconcile</code></dt>\n  <dd>Remove duplicate lines, preserving existing blank lines, <code>add</code> entries for new files, and <code>delete</code> entries for deleted files.</dd>\n  <dt><code>rebuild</code></dt>\n  <dd>Delete and rebuild <code>.index</code>, listing files by most recently modified, reversed.</dd>\n</dl>\n\n##### `index` Subcommand\n\n`nb` manages the `.index` of each folder within a notebook using an internal\n`index` subcommand.\n\n###### `nb help index`\n\n```text\nUsage:\n  nb index add <filename>\n  nb index delete <filename>\n  nb index edit\n  nb index get_basename <id>\n  nb index get_id <filename>\n  nb index get_max_id\n  nb index rebuild [--ancestors]\n  nb index reconcile [--ancestors] [--commit]\n  nb index show\n  nb index update <existing-filename> <new-filename>\n  nb index verify\n  nb index <subcommand> <options>... [<folder-path>]\n\nOptions:\n  --ancestors   Perform the action on all folders within the notebook that\n                are ancestors of the current folder.\n  --commit      Commit changes to git.\n\nSubcommands:\n  add           Add <filename> to the index.\n  delete        Delete <filename> from the index.\n  edit          Open the index file in `$EDITOR`.\n  get_basename  Print the filename / basename at the specified <id>.\n  get_id        Get the id for <filename>.\n  get_max_id    Get the maximum id for the folder.\n  rebuild       Rebuild the index, listing files by last modified, reversed.\n                Some ids will change. Prefer `nb index reconcile`.\n  reconcile     Remove duplicates and update index for added and deleted files.\n  show          Print the index.\n  update        Overwrite the <existing-filename> entry with <new-filename>.\n  verify        Verify that the index matches the folder contents.\n\nDescription:\n  Manage the index for the current folder or the folder at <folder-path>,\n  which can be passed as the final argument to any `index` subcommand.\n\n  `index` is used internally by `nb` and using it manually will\n  probably corrupt the index. If something goes wrong with an index,\n  fix it with `nb index reconcile`.\n\n  An index is a text file named '.index' in any folder within a notebook.\n  .index contains a list of filenames and the line number of each filename\n  represents the id. .index files are included in the git repository so\n  ids are preserved across systems.\n```\n\n<p>\n  <sup>\n    <a href=\"#nb-notebook-specification\">↑</a>\n  </sup>\n</p>\n\n#### `.pindex` Files\n\nAny folder may contain an optional plain text file named `.pindex`\ncontaining a list of basenames from that folder, one per line, that should\nbe treated as [pinned](#-pinning), meaning they appear first in some\nlist operations, including `nb` and [`nb ls`](#ls). Entries are added to a\n`.pindex` file with [`nb pin`](#pin) and removed with [`nb unpin`](#unpin).\n\n<p>\n  <sup>\n    <a href=\"#nb-notebook-specification\">↑</a>\n  </sup>\n</p>\n\n#### Archived Notebooks\n\nA notebook is considered [archived](#archiving-notebooks)\nwhen it contains a file named `.archived`\nat the root level of the notebook directory.\n\n<p>\n  <sup>\n    <a href=\"#nb-notebook-specification\">↑</a>\n  </sup>\n</p>\n\n## Tests\n\nWith more than 2,200 tests spanning tens of thousands of lines,\n`nb` is really mostly a\n[test suite](https://github.com/xwmx/nb/tree/master/test).\nTests run continuously [via GitHub Actions](https://github.com/xwmx/nb/actions)\non recent versions of both Ubuntu and macOS to account for differences between\nBSD and GNU tools and Bash versions.\nTo run the tests locally, install\n[Bats](https://github.com/bats-core/bats-core)\nand the [recommended dependencies](#optional),\nthen run `bats test` within the project root directory. Run groups of\ntests with globbing, e.g., `bats test/browse*` and `bats test/folders*`.\n\n<div align=\"center\">\n  <span>\n  <a href=\"#overview\">&nbsp;↑&nbsp;</a>\n  </span>\n\n  <br/>\n</div>\n\n---\n\n<div align=\"center\">\n  <span>\n  Copyright (c) 2015-present ·\n  <a href=\"https://www.williammelody.com/\">William Melody</a> ·\n  <a href=\"https://github.com/xwmx/nb/blob/master/LICENSE\">AGPLv3</a>\n  </span>\n\n  <br/>\n  <br/>\n</div>\n\n<div align=\"center\">\n  <span>\n  <a href=\"https://xwmx.github.io/nb\">xwmx.github.io/nb</a>&nbsp;·\n  <a href=\"https://github.com/xwmx/nb\">github.com/xwmx/nb</a>\n  </span>\n\n  <br/>\n  <br/>\n</div>\n\n<div align=\"center\">\n  <span>\n  📝🔖🔒🔍📔\n  </span>\n\n  <br/>\n  <br/>\n</div>\n"
  },
  {
    "path": "docs/index.previous.html",
    "content": "<!DOCTYPE html>\n<!--\n__          _\n\\ \\   _ __ | |__\n \\ \\ | '_ \\| '_ \\\n / / | | | | |_) |\n/_/  |_| |_|_.__/\n-->\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"x-ua-compatible\" content=\"ie=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n\n    <title>nb • cli plain text note-taking, bookmarking, and archiving.</title>\n\n    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css\" integrity=\"sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk\" crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.5.0/css/all.css\" integrity=\"sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU\" crossorigin=\"anonymous\">\n    <link href=\"https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400;1,700&display=block\" rel=\"stylesheet\">\n\n    <style>\n      html {\n        height: 100%;\n        min-width: 0;\n      }\n\n      body {\n        background-color: #fff;\n        color: #fff;\n        font-family: 'Courier Prime', 'monospace', sans-serif;\n        height: auto;\n        min-height: 100%;\n        padding: 2rem;\n      }\n\n      a,\n      a:hover {\n        color: #fff;\n        text-decoration: none;\n      }\n\n      .content {\n        -webkit-animation:  color-animation 30s ease infinite;\n        -moz-animation:     color-animation 30s ease infinite;\n        -o-animation:       color-animation 30s ease infinite;\n        animation:          color-animation 30s ease infinite;\n        background: linear-gradient(135deg,\n          #0E889C,\n          #0ACC99\n        );\n        background-size: 3000% 3000%;\n        min-height: 100%;\n        padding: 0;\n        text-align: center;\n        width: 100%;\n      }\n\n      @-webkit-keyframes color-animation {\n        0%    { background-position: 0%   0%;   }\n        50%   { background-position: 100% 100%; }\n        100%  { background-position: 0%   0%;   }\n      }\n      @-moz-keyframes color-animation {\n        0%    { background-position: 0%   0%;   }\n        50%   { background-position: 100% 100%; }\n        100%  { background-position: 0%   0%;   }\n      }\n      @-o-keyframes color-animation {\n        0%    { background-position: 0%   0%;   }\n        50%   { background-position: 100% 100%; }\n        100%  { background-position: 0%   0%;   }\n      }\n      @keyframes color-animation {\n        0%    { background-position: 0%   0%;   }\n        50%   { background-position: 100% 100%; }\n        100%  { background-position: 0%   0%;   }\n      }\n\n\n      .command-name {\n        display: inline-block;\n        font-size: 12rem;\n        line-height: 0.9em;\n        margin: 0;\n        padding: 0.3em 0 0;\n        word-break: break-all;\n      }\n\n      @media only screen and (min-width: 550px) {\n        .command-name {\n          font-size: 18rem;\n        }\n      }\n\n      @media only screen and (min-width: 768px) {\n        .command-name {\n          font-size: 23rem;\n        }\n      }\n\n      .description {\n        font-size: 1rem;\n        margin: 1rem 0;\n        padding: 0 2em;\n        text-align: left;\n      }\n\n      @media only screen and (min-width: 768px) {\n        .description {\n          font-size: 1.25rem;\n        }\n      }\n\n      .links {\n        list-style-type: none;\n        margin-bottom: 0;\n        padding-bottom: 5rem;\n        padding-top: 2rem;\n      }\n\n      @media only screen and (min-width: 550px) {\n        .links {\n          padding: 4rem;\n        }\n      }\n\n      .links li {\n        font-size: 6rem;\n        padding: 0 0.25em;\n      }\n\n      ::selection {\n        background: #fff;\n        color: #fff;\n      }\n\n      ::-moz-selection {\n        background: #fff;\n        color: #fff;\n      }\n    </style>\n  </head>\n  <body>\n    <div class=\"content\">\n      <div class=\"container\">\n        <div class=\"row\">\n          <div class=\"col\">\n            <a href=\"https://github.com/xwmx/nb\">\n              <h1 class=\"command-name\">\n                nb\n              </h1>\n            </a>\n          </div> <!-- .col -->\n        </div> <!-- .row -->\n\n        <div class=\"row\">\n          <div class=\"col-lg-8 offset-lg-2\">\n            <p class=\"description\">\n              Command line note-taking, bookmarking, and archiving with\n              plain text data storage,\n              encryption,\n              filtering and search,\n              Git-backed versioning and syncing,\n              Pandoc-backed conversion,\n              global and local notebooks,\n              customizable color themes,\n              and more, all in a single portable, user-friendly script.\n            </p>\n          </div> <!-- .col-* -->\n        </div> <!-- .row -->\n\n        <div class=\"row\">\n          <div class=\"col\">\n            <ul class=\"links list-inline\">\n              <li class=\"list-inline-item\">\n                <a href=\"https://github.com/xwmx/nb\" arial-label=\"github\">\n                  <i aria-hidden class=\"fab fa-github\"></i>\n                </a>\n              </li>\n            </ul>\n          </div> <!-- .col    -->\n        </div> <!-- .row      -->\n      </div> <!-- .container  -->\n    </div> <!-- .content      -->\n  </body>\n</html>\n\n"
  },
  {
    "path": "etc/README.md",
    "content": "# `nb` Tab Completion\n\n## Homebrew\n\nInstalling via Homebrew with `brew install nb` will also\ninstall the completion scripts.\n\nA one-time setup might be needed to [enable completion for all Homebrew\nprograms](https://docs.brew.sh/Shell-Completion).\n\n## npm, bpkg, Make\n\nWhen `nb` is installed with `npm`, `bpkg`, or Make, an install hook will\ncheck the environment and attempt to install completions. If it's successful,\nyou should see a message similar to:\n\n```bash\nCompletion script installed: /usr/local/etc/bash_completion.d/nb\nCompletion script installed: /usr/local/share/fish/vendor_completions.d/nb.fish\nCompletion script installed: /usr/local/share/zsh/site-functions/_nb\n```\n\nIf completion is working after installing through any of these methods, then\nyou don't need to do anything else.\n\n## `nb completions`\n\nThe `nb completions` subcommand can be used for installing and uninstalling\ncompletion scripts. Depending on your configuration, you might need to use\n`sudo` to install completion scripts easily:\n\n```bash\n> sudo nb completions check\nCompletion scripts not found.\n\n> sudo nb completions install\nCompletion script installed: /usr/share/bash-completion/completions/nb\nCompletion script installed: /usr/local/share/fish/vendor_completions.d/nb.fish\nCompletion script installed: /usr/local/share/zsh/site-functions/_nb\n\n> sudo nb completions check\nExists: /usr/share/bash-completion/completions/nb\nExists: /usr/local/share/fish/vendor_completions.d/nb.fish\nExists: /usr/local/share/zsh/site-functions/_nb\n\n> sudo nb completions uninstall\nCompletion script removed: /usr/share/bash-completion/completions/nb\nCompletion script removed: /usr/local/share/fish/vendor_completions.d/nb.fish\nCompletion script removed: /usr/local/share/zsh/site-functions/_nb\n```\n\nIf you installed `nb` manually by downloading just the `nb` script,\nthe completion scripts won't be immediately available for\n`nb completions install`. You can try installing the completions with\nthe `--download` flag, which will get the latest version from GitHub:\n\n```bash\nsudo nb completions install --download\n```\n\n`nb completions` will try to determine the completion script directories\nfrom your environment. If `nb completions` isn't able to install\nthe completion scripts, you can try installing them manually.\n\n## Manual Installation\n\n### bash\n\n#### Linux\n\nOn a current Linux OS (in a non-minimal installation), bash completion should\nbe available.\n\nPlace the completion script in `/etc/bash_completion.d/`:\n\n```bash\nsudo curl -L https://raw.githubusercontent.com/xwmx/nb/master/etc/nb-completion.bash -o /etc/bash_completion.d/nb\n```\n\n#### macOS\n\nIf you aren't installing with homebrew, source the completion script in\n`.bash_profile`:\n\n```sh\nif [[ -f /path/to/nb-completion.bash ]]\nthen\n  source /path/to/nb-completion.bash\nfi\n```\n\n### zsh\n\nPlace the completion script in your `/path/to/zsh/completion` (typically\n`~/.zsh/completion/`):\n\n```bash\n$ mkdir -p ~/.zsh/completion\n$ curl -L https://raw.githubusercontent.com/xwmx/nb/master/etc/nb-completion.zsh > ~/.zsh/completion/_nb\n```\nInclude the directory in your `$fpath` by adding in `~/.zshrc`:\n\n```bash\nfpath=(~/.zsh/completion $fpath)\n```\n\nMake sure `compinit` is loaded or do it by adding in `~/.zshrc`:\n\n```bash\nautoload -Uz compinit && compinit -i\n```\n\nThen reload your shell:\n\n```bash\nexec $SHELL -l\n```\n"
  },
  {
    "path": "etc/Vagrantfile",
    "content": "# frozen_string_literal: true\n\n# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\n# rubocop:disable all\n\n# NOTE: Uncomment box config block for `vagrant up` / `vagrant provision`.\n\n# All Vagrant configuration is done below. The \"2\" in Vagrant.configure\n# configures the configuration version (we support older styles for\n# backwards compatibility). Please don't change it unless you know what\n# you're doing.\nVagrant.configure(\"2\") do |config|\n  # The most common configuration options are documented and commented below.\n  # For a complete reference, please see the online documentation at\n  # https://docs.vagrantup.com.\n\n  #############################################################################\n  # VMs & Boxes\n  # -----------\n  #\n  # Resources:\n  # https://www.vagrantup.com/docs/multi-machine\n  # https://www.vagrantup.com/docs/provisioning/shell\n  #\n  # Every Vagrant development environment requires a box. You can search for\n  # boxes at https://vagrantcloud.com/search.\n\n  #############################################################################\n  # Arch Boxes\n\n  $arch_setup = <<-HEREDOC\nsudo su root\n\n# https://bbs.archlinux.org/viewtopic.php?id=282796\npacman --noconfirm -Sy archlinux-keyring && pacman --noconfirm -Syu\n\n# install nvm (https://github.com/nvm-sh/nvm)\ncurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash\n\n# add project root to $PATH\nif grep -q -v vagrant \"${HOME}/.bashrc\"\nthen\n  printf \"\\\\nexport PATH=\\\"/vagrant:\\${PATH}\\\"\\\\n\" >> \"${HOME}/.bashrc\"\nfi\n\nsudo pacman       \\\n  --noconfirm     \\\n  -Syu            \\\n  bash-bats       \\\n  elinks          \\\n  fish            \\\n  git             \\\n  lynx            \\\n  nmap            \\\n  pandoc-cli      \\\n  python-pygments \\\n  vim             \\\n  w3m\nHEREDOC\n\n  ######\n  # Arch\n  #\n  # https://app.vagrantup.com/archlinux/boxes/archlinux\n\n  # config.vm.define \"arch\" do |arch|\n  #   arch.vm.box = \"archlinux/archlinux\"\n  #   arch.vm.provision :shell, inline: $arch_setup, privileged: false\n  # end\n\n  #############################################################################\n  # CentOS Boxes\n\n  $centos_setup = <<-HEREDOC\n# install nvm (https://github.com/nvm-sh/nvm)\ncurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash\n\n# add project root to $PATH\nif grep -q -v vagrant \"${HOME}/.bashrc\"\nthen\n  printf \"\\\\nexport PATH=\\\"/vagrant:\\${PATH}\\\"\\\\n\" >> \"${HOME}/.bashrc\"\nfi\nHEREDOC\n\n  ##########\n  # CentOS 8\n\n  # config.vm.define \"centos8\" do |centos8|\n  #   centos8.vm.box = \"centos/8\"\n  #   centos8.vm.box_version = \"1905.1\"\n  #   centos8.vm.provision :shell, inline: $centos_setup, privileged: false\n  # end\n\n  ##########\n  # CentOS 7\n\n  # config.vm.define \"centos7\" do |centos7|\n  #   centos7.vm.box = \"centos/7\"\n  #   centos7.vm.provision :shell, inline: $centos_setup, privileged: false\n  # end\n\n  #############################################################################\n  # Debian Boxes\n\n  $debian_setup = <<-HEREDOC\n# install node and npm\n# sudo apt update -y\n# sudo apt install nodejs -y\n# sudo apt install npm -y\n\n# install nvm (https://github.com/nvm-sh/nvm)\ncurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash\n\n# add project root to $PATH\nif grep -q -v vagrant \"${HOME}/.bashrc\"\nthen\n  printf \"\\\\nexport PATH=\\\"/vagrant:\\${PATH}\\\"\\\\n\" >> \"${HOME}/.bashrc\"\nfi\n\n# install dependencies\nsudo apt-get update\nsudo apt-get install bats   -y\nsudo apt-get install elinks -y\nsudo apt-get install lynx   -y\nsudo apt-get install ncat   -y\nsudo apt-get install python3-pygments -y\nsudo apt-get install w3m    -y\n\n# install latest pandoc\ncurl -LO https://github.com/jgm/pandoc/releases/download/3.1.11.1/pandoc-3.1.11.1-1-amd64.deb\nsudo dpkg -i pandoc-3.1.11.1-1-amd64.deb\n\n# install latest bat\ncurl -LO https://github.com/sharkdp/bat/releases/download/v0.16.0/bat_0.16.0_amd64.deb\nsudo dpkg -i bat_0.16.0_amd64.deb\n\n# install latest git\nsudo add-apt-repository ppa:git-core/ppa\nsudo apt update\nsudo apt install git -y\n\ngit config --global user.name   \"Example Name\"\ngit config --global user.email  \"example@example.test\"\n\n# set locale\nsudo apt-get clean\nsudo apt-get update\nsudo apt-get install locales -y\nsudo locale-gen en_US.UTF-8\n\nprintf \"%s\\\\n\" \"LANG=en_US.UTF-8\" | sudo tee /etc/default/locale > /dev/null\nHEREDOC\n\n  # config.vm.define \"debian12\" do |debian12|\n  #   debian12.vm.box = \"debian/bookworm64\"\n  #   debian12.vm.provision :shell, inline: $debian_setup, privileged: false\n  # end\n\n  #############################################################################\n  # EndeavorOS Boxes\n\n  # NOTE: uses $arch_setup\n\n  # config.vm.define \"endeavor\" do |endeavor|\n  #   endeavor.vm.box = \"altafsaljooq/EndeavousOS\"\n  #   endeavor.vm.provision :shell, inline: $arch_setup, privileged: false\n  # end\n\n  #############################################################################\n  # Fedora Boxes\n\n  $fedora_setup = <<-HEREDOC\n# install dependencies\nsudo dnf -y update\nsudo dnf -y install bats\nsudo dnf -y install elinks\nsudo dnf -y install git\nsudo dnf -y install lynx\nsudo dnf -y install nmap-ncat\nsudo dnf -y install pandoc\nsudo dnf -y install python3-pygments\nsudo dnf -y install w3m\n\n# install nvm (https://github.com/nvm-sh/nvm)\ncurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash\n\n# add project root to $PATH\nif [[ -f \"${HOME}/.bashrc\" ]] && grep -q -v vagrant \"${HOME}/.bashrc\"\nthen\n  touch \"${HOME}/.bashrc\"\n  printf \"\\\\nexport PATH=\\\"/vagrant:\\${PATH}\\\"\\\\n\" >> \"${HOME}/.bashrc\"\nfi\nHEREDOC\n\n  ###########\n  # Fedora 41\n\n  # https://app.vagrantup.com/fedora/boxes/41-cloud-base\n  # config.vm.define \"fedora41\" do |fedora41|\n  #   fedora41.vm.box = \"fedora/41-cloud-base\"\n  #   fedora41.vm.provision :shell, inline: $fedora_setup, privileged: false\n  # end\n\n  ###########\n  # Fedora 38\n\n  # https://app.vagrantup.com/fedora/boxes/38-cloud-base\n  # config.vm.define \"fedora38\" do |fedora38|\n  #   fedora38.vm.box         = \"fedora/38-cloud-base\"\n  #   fedora38.vm.box_version = \"38.20230413.1\"\n  #   fedora38.vm.provision :shell, inline: $fedora_setup, privileged: false\n  # end\n\n  ###########\n  # Fedora 36\n\n  # https://app.vagrantup.com/fedora/boxes/36-cloud-base\n  # config.vm.define \"fedora36\" do |fedora36|\n  #   fedora36.vm.box         = \"fedora/36-cloud-base\"\n  #   fedora36.vm.box_version = \"36-20220504.1\"\n  #   fedora36.vm.provision :shell, inline: $fedora_setup, privileged: false\n  # end\n\n  #############################################################################\n  # FreeBSD Boxes\n\n  $freebsd_setup = <<-HEREDOC\nsudo pkg update -f\nsudo pkg install -y git\nHEREDOC\n\n  ##############\n  # FreeBSD 12.5\n\n  # config.vm.define \"freebsd124\" do |freebsd124|\n  #   freebsd124.vm.box = \"freebsd/FreeBSD-12.4-STABLE\"\n  #   freebsd124.vm.provision :shell, inline: $freebsd_setup, privileged: false\n  # end\n\n  #############################################################################\n  # NixOS Boxes\n\n  $nixos_setup = <<-HEREDOC\n# install git\nnix-env -iA nixos.pkgs.gitAndTools.gitFull\n\n# install nvm (https://github.com/nvm-sh/nvm)\ncurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash\n\n# add project root to $PATH\nif [[ -f \"${HOME}/.bashrc\" ]] && grep -q -v vagrant \"${HOME}/.bashrc\"\nthen\n  touch \"${HOME}/.bashrc\"\n  printf \"\\\\nexport PATH=\\\"/vagrant:\\${PATH}\\\"\\\\n\" >> \"${HOME}/.bashrc\"\nfi\nHEREDOC\n\n  #############\n  # NixOS 24.11\n\n  # config.vm.define \"nixos2411\" do |nixos2411|\n  #   nixos2411.vm.box          = \"boxen/nixos-24.11\"\n  #   nixos2411.vm.box_version  = \"2025.04.02.21\"\n  #   nixos2411.vm.provision :shell, inline: $nixos_setup, privileged: false\n  # end\n\n  #############\n  # NixOS 24.05\n\n  # config.vm.define \"nixos2405\" do |nixos2405|\n  #   nixos2405.vm.box          = \"nixbox/nixos\"\n  #   nixos2405.vm.box_version  = \"24.05\"\n  #   nixos2405.vm.provision :shell, inline: $nixos_setup, privileged: false\n  # end\n\n  #############\n  # NixOS 23.11\n\n  # config.vm.define \"nixos2311\" do |nixos2311|\n  #   nixos2311.vm.box          = \"nixbox/nixos\"\n  #   nixos2311.vm.box_version  = \"23.11\"\n  #   nixos2311.vm.provision :shell, inline: $nixos_setup, privileged: false\n  # end\n\n  #############\n  # NixOS 23.05\n\n  # https://license.hashicorp.com/boxen/boxes/nixos-23.05-x86_64\n  # config.vm.define \"nixos2305\" do |nixos2305|\n  #   nixos2305.vm.box         = \"boxen/nixos-23.05-x86_64\"\n  #   nixos2305.vm.box_version = \"2023.8.14.0\"\n  #   nixos2305.vm.provision :shell, inline: $nixos_setup, privileged: false\n  # end\n\n  #############\n  # NixOS 20.03\n\n  # https://app.vagrantup.com/nixos/boxes/nixos-20.03-test\n  # config.vm.define \"nixos2003\" do |nixos2003|\n  #   nixos2003.vm.box = \"nixos/nixos-20.03-test\"\n  #   nixos2003.vm.box_version = \"0.0.1\"\n  #   nixos2003.vm.provision :shell, inline: $nixos_setup, privileged: false\n  # end\n\n  #############\n  # NixOS 18.03\n\n  # https://app.vagrantup.com/nixos/boxes/nixos-18.03-i686\n  # config.vm.define \"nixos1803\" do |nixos1803|\n  #   nixos1803.vm.box = \"nixos/nixos-18.03-i686\"\n  #   nixos1803.vm.provision :shell, inline: $nixos_setup, privileged: false\n  # end\n\n  #############################################################################\n  # OpenBSD Boxes\n\n  $openbsd_setup = <<-HEREDOC\n# TODO\n# sudo su\n# echo \"https://ftp.eu.OpenBSD.org/pub/OpenBSD\" > /etc/installurl\n# pkg_add git\n# pkg_add bash\n# pkg_add vim\nHEREDOC\n\n  ###########\n  # OpenBSD 7\n\n  # https://app.vagrantup.com/fnichol/boxes/openbsd-7.0\n  # https://app.vagrantup.com/generic/boxes/openbsd7\n  # https://app.vagrantup.com/roboxes/boxes/openbsd7\n  # https://app.vagrantup.com/twingly/boxes/openbsd-7.1-amd64\n  # config.vm.define \"openbsd7\" do |openbsd7|\n  #   # openbsd7.vm.box = \"fnichol/openbsd-7.0\"\n  #   # openbsd7.vm.box = \"generic/openbsd7\"\n  #   # openbsd7.vm.box = \"jcmdln/openbsd\"\n  #   # openbsd7.vm.box = \"roboxes/openbsd7\"\n  #   openbsd7.vm.box = \"twingly/openbsd-7.1-amd64\"\n  #   openbsd7.vm.provision :shell, inline: $openbsd_setup, privileged: false\n  # end\n\n  ###########\n  # OpenBSD 6\n\n  # https://app.vagrantup.com/twingly/boxes/openbsd-6.9-amd64\n  # config.vm.define \"openbsd6\" do |openbsd6|\n  #   openbsd6.vm.box = \"twingly/openbsd-6.9-amd64\"\n  #   openbsd6.vm.provision :shell, inline: $openbsd_setup, privileged: false\n  # end\n\n  #############################################################################\n  # Ubuntu Boxes:\n  #\n  # https://app.vagrantup.com/ubuntu\n\n  $ubuntu_setup = <<-HEREDOC\n# install node and npm\n# sudo apt update -y\n# sudo apt install nodejs -y\n# sudo apt install npm -y\n\n# install nvm (https://github.com/nvm-sh/nvm)\ncurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash\n\n# add project root to $PATH\nif grep -q -v vagrant \"${HOME}/.bashrc\"\nthen\n  printf \"\\\\nexport PATH=\\\"/vagrant:\\${PATH}\\\"\\\\n\" >> \"${HOME}/.bashrc\"\nfi\n\n# install dependencies\nsudo apt-get update\nsudo apt-get install bat    -y\nsudo apt-get install bats   -y\nsudo apt-get install elinks -y\nsudo apt-get install lynx   -y\nsudo apt-get install ncat   -y\nsudo apt-get install python3-pygments -y\nsudo apt-get install w3m    -y\n\n# install latest pandoc\ncurl -LO https://github.com/jgm/pandoc/releases/download/3.1.11.1/pandoc-3.1.11.1-1-amd64.deb\nsudo dpkg -i pandoc-3.1.11.1-1-amd64.deb\n\n# install latest git\nsudo add-apt-repository ppa:git-core/ppa\nsudo apt update\nsudo apt install git -y\n\ngit config --global user.name   \"Example Name\"\ngit config --global user.email  \"example@example.test\"\nHEREDOC\n\n  ##############\n  # Ubuntu 24.04\n\n  # config.vm.define \"ubuntu2404\" do |ubuntu2404|\n  #   ubuntu2404.vm.box = \"ubuntu/noble64\"\n  #   ubuntu2404.vm.provision :shell, inline: $ubuntu_setup, privileged: false\n  # end\n\n  ##############\n  # Ubuntu 22.10\n\n  # config.vm.define \"ubuntu2210\" do |ubuntu2210|\n  #   ubuntu2210.vm.box = \"ubuntu/kinetic64\"\n  #   ubuntu2210.vm.provision :shell, inline: $ubuntu_setup, privileged: false\n  # end\n\n  ##############\n  # Ubuntu 22.04\n\n  # config.vm.define \"ubuntu2204\" do |ubuntu2204|\n  #   ubuntu2204.vm.box = \"ubuntu/jammy64\"\n  #   ubuntu2204.vm.provision :shell, inline: $ubuntu_setup, privileged: false\n  # end\n\n  ##############\n  # Ubuntu 20.10\n\n  # config.vm.define \"ubuntu2010\" do |ubuntu2010|\n  #   ubuntu2010.vm.box = \"ubuntu/impish64\"\n  #   ubuntu2010.vm.provision :shell, inline: $ubuntu_setup, privileged: false\n  # end\n\n  ##################\n  # Ubuntu 20.04 LTS\n\n  # config.vm.define \"ubuntu2004\" do |ubuntu2004|\n  #   ubuntu2004.vm.box = \"ubuntu/focal64\"\n  #   ubuntu2004.vm.provision :shell, inline: $ubuntu_setup, privileged: false\n  # end\n\n  ##################\n  # Ubuntu 18.04 LTS\n\n  # config.vm.define \"ubuntu1804\" do |ubuntu1804|\n  #   ubuntu1804.vm.box = \"hashicorp/bionic64\"\n  #   ubuntu1804.vm.provision :shell, inline: $ubuntu_setup, privileged: false\n  # end\n\n  ################\n  # Ubuntu Desktop\n\n  # config.vm.define \"ubuntu_desktop\" do |ubuntu_desktop|\n  #   # https://app.vagrantup.com/gusztavvargadr/boxes/ubuntu-desktop\n  #   ubuntu_desktop.vm.box = \"gusztavvargadr/ubuntu-desktop\"\n  #   ubuntu_desktop.vm.provision :shell, inline: $ubuntu_setup, privileged: false\n  # end\n\n  ######################\n  # Ubuntu 20.04 Desktop\n\n  # config.vm.define \"ubuntu_desktop\" do |ubuntu_desktop|\n  #   # https://app.vagrantup.com/peru/boxes/ubuntu-20.04-desktop-amd64\n  #   ubuntu_desktop.vm.box = \"peru/ubuntu-20.04-desktop-amd64\"\n  #   ubuntu_desktop.vm.provision :shell, inline: $ubuntu_setup, privileged: false\n  # end\n\n  #############################################################################\n  # Configuration\n  # -------------\n\n  # Link project root to /vagrant in guest.\n  config.vm.synced_folder \"../\", \"/vagrant\"\n\n  #############################################################################\n\n  # Disable automatic box update checking. If you disable this, then\n  # boxes will only be checked for updates when the user runs\n  # `vagrant box outdated`. This is not recommended.\n  # config.vm.box_check_update = false\n\n  # Create a forwarded port mapping which allows access to a specific port\n  # within the machine from a port on the host machine. In the example below,\n  # accessing \"localhost:8080\" will access port 80 on the guest machine.\n  # NOTE: This will enable public access to the opened port\n  # config.vm.network \"forwarded_port\", guest: 80, host: 8080\n\n  # Create a forwarded port mapping which allows access to a specific port\n  # within the machine from a port on the host machine and only allow access\n  # via 127.0.0.1 to disable public access\n  # config.vm.network \"forwarded_port\", guest: 80, host: 8080, host_ip: \"127.0.0.1\"\n\n  # Create a private network, which allows host-only access to the machine\n  # using a specific IP.\n  # config.vm.network \"private_network\", ip: \"192.168.33.10\"\n\n  # Create a public network, which generally matched to bridged network.\n  # Bridged networks make the machine appear as another physical device on\n  # your network.\n  # config.vm.network \"public_network\"\n\n  # Share an additional folder to the guest VM. The first argument is\n  # the path on the host to the actual folder. The second argument is\n  # the path on the guest to mount the folder. And the optional third\n  # argument is a set of non-required options.\n  # config.vm.synced_folder \"../data\", \"/vagrant_data\"\n\n  # Provider-specific configuration so you can fine-tune various\n  # backing providers for Vagrant. These expose provider-specific options.\n  # Example for VirtualBox:\n  #\n  # config.vm.provider \"virtualbox\" do |vb|\n  #   # Display the VirtualBox GUI when booting the machine\n  #   vb.gui = true\n  #\n  #   # Customize the amount of memory on the VM:\n  #   vb.memory = \"1024\"\n  # end\n  #\n  # View the documentation for the provider you are using for more\n  # information on available options.\n\n  # Enable provisioning with a shell script. Additional provisioners such as\n  # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the\n  # documentation for more information about their specific syntax and use.\n  # config.vm.provision \"shell\", inline: <<-SHELL\n  #   apt-get update\n  #   apt-get install -y apache2\n  # SHELL\nend\n"
  },
  {
    "path": "etc/debian/changelog",
    "content": "nb (4.1.5-1) unstable; urgency=medium\n\n  * Initial release.\n\n -- William Melody <hi@williammelody.com>  Sun, 24 May 2020 04:48:17 +0000\n"
  },
  {
    "path": "etc/debian/control",
    "content": "Source: nb\nSection: misc\nPriority: optional\nMaintainer: William Melody <hi@williammelody.com>\nBuild-Depends: debhelper-compat (= 12)\nStandards-Version: 4.4.1\nHomepage: https://github.com/xwmx/nb\nVcs-Browser: https://github.com/xwmx/nb\nVcs-Git: https://github.com/xwmx/nb.git\n\nPackage: nb\nArchitecture: all\nDepends: bash-completion, pandoc, python3-pygments, ripgrep, tig, w3m, ${misc:Depends}\nDescription: CLI note-taking, bookmarking, and archiving.\n CLI note-taking, bookmarking, and archiving with encryption,\n search, Git-backed versioning and syncing, tagging, and more in a single\n portable script.\n"
  },
  {
    "path": "etc/debian/copyright",
    "content": "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\nUpstream-Name: nb\nUpstream-Contact: William Melody <hi@williammelody.com>\nSource: https://github.com/xwmx/nb\n\nFiles: *\nCopyright: 2015 William Melody <hi@williammelody.com>\nLicense: AGPL-3\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as\n published by the Free Software Foundation, either version 3 of the\n License, or (at your option) any later version.\n .\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n GNU Affero General Public License for more details.\n .\n You should have received a copy of the GNU Affero General Public License\n along with this program.  If not, see <https://www.gnu.org/licenses/>.\n"
  },
  {
    "path": "etc/debian/rules",
    "content": "#!/usr/bin/make -f\n# See debhelper(7) (uncomment to enable)\n# output every command that modifies files on the build system.\n#export DH_VERBOSE = 1\n\n\n# see FEATURE AREAS in dpkg-buildflags(1)\n#export DEB_BUILD_MAINT_OPTIONS = hardening=+all\n\n# see ENVIRONMENT in dpkg-buildflags(1)\n# package maintainers to append CFLAGS\n#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic\n# package maintainers to append LDFLAGS\n#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed\n\n\n%:\n\tdh $@\n\n\n# dh_make generated override targets\n# This is example for Cmake (See https://bugs.debian.org/641051 )\n#override_dh_auto_configure:\n#\tdh_auto_configure -- #\t-DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)\n\n"
  },
  {
    "path": "etc/nb-completion.bash",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# __          _\n# \\ \\   _ __ | |__\n#  \\ \\ | '_ \\| '_ \\\n#  / / | | | | |_) |\n# /_/  |_| |_|_.__/\n#\n# [nb] Command line and local web note-taking, bookmarking, and archiving with\n# plain text data storage, encryption, filtering and search, pinning, #tagging,\n# Git-backed versioning and syncing, Pandoc-backed conversion, global and local\n# notebooks, customizable color themes, [[wiki-style linking]], plugins, and\n# more in a single portable, user-friendly script.\n#\n# https://github.com/xwmx/nb\n###############################################################################\n\n_nb_subcommands() {\n  # _nb_cache_completions()\n  #\n  # Usage:\n  #   _nb_cache_completions <path>\n  #\n  # Description:\n  #   Cache completions for `nb`. Generating completions can be slow and\n  #   native shell caching doesn't appear to help.\n  _nb_cache_completions() {\n    local _cache_path=\"${1:-}\"\n\n    [[ -z \"${_cache_path:-}\" ]] && return 0\n\n    # Remove outdated cache files.\n\n    local _base_cache_path=\"${_cache_path%-*}\"\n\n    local __suffix=\n    for   __suffix in \"zsh\" \"v1\"\n    do\n      if [[ -e \"${_base_cache_path:?}-${__suffix:?}\" ]]\n      then\n        \\rm -f  \"${_base_cache_path:?}-${__suffix:?}\"\n      fi\n    done\n\n    # Rebuild completion cache.\n\n    local _commands=()\n    IFS=$'\\n' _commands=($(nb subcommands))\n\n    local _notebooks=()\n    IFS=$'\\n' _notebooks=($(nb notebooks --names --no-color --unarchived))\n\n    local _completions=()\n    IFS=$'\\n' _completions=(${_commands[@]})\n\n    local _commands_cached=\n    local _notebooks_cached=\n\n    if [[ -e \"${_cache_path}\"       ]]\n    then\n      local _counter=0\n\n      while IFS= read -r __line\n      do\n        _counter=$((_counter+1))\n\n        if [[   \"${_counter}\" == 1  ]]\n        then\n          _commands_cached=\"${__line}\"\n        elif [[ \"${_counter}\" == 2  ]]\n        then\n          _notebooks_cached=\"${__line}\"\n        else\n          break\n        fi\n      done < \"${_cache_path}\"\n    fi\n\n    if [[ \"${_commands_cached}\"  != \"${_commands[*]:-}\"   ]] ||\n       [[ \"${_notebooks_cached}\" != \"${_notebooks[*]:-}\"  ]]\n    then\n      # Construct <notebook>:<subcommand> completions.\n      local __notebook=\n      for   __notebook in \"${_notebooks[@]}\"\n      do\n        local __command=\n        for   __command in \"${_commands[@]}\"\n        do\n          if [[ -n \"${__notebook:-}\"  ]] &&\n             [[ -n \"${__command:-}\"   ]]\n          then\n            _completions+=(\"${__notebook}:${__command}\")\n          fi\n        done\n      done\n\n      local _directory_path=\n      _directory_path=\"$(dirname \"${_cache_path}\")\"\n\n      mkdir -p \"${_directory_path}\"\n\n      if [[ -f \"${_cache_path:?}\" ]]\n      then\n        \\rm -f \"${_cache_path:?}\"\n      fi\n\n      touch \"${_cache_path:?}\"\n\n      {\n        (IFS=$' '; printf \"%s\\\\n\" \"${_commands[*]}\")\n        (IFS=$' '; printf \"%s\\\\n\" \"${_notebooks[*]}\")\n        printf \"%s\\\\n\" \"${_completions[@]}\"\n      } >> \"${_cache_path}\"\n    fi\n  }\n\n  local _nb_dir=\n  _nb_dir=\"$(nb env | grep 'NB_DIR' | cut -d = -f 2)\"\n\n  if [[ -z \"${_nb_dir:?}\" ]] ||\n     [[ ! -e \"${_nb_dir}\" ]]\n  then\n    return 0\n  elif [[ -L \"${_nb_dir}\" ]]\n  then\n    if hash \"realpath\" 2>/dev/null\n    then\n      _nb_dir=\"$(realpath \"${_nb_dir}\")\"\n    else\n      _nb_dir=\"$(readlink \"${_nb_dir}\")\"\n    fi\n  fi\n\n  if [[ ! -d \"${_nb_dir}\" ]]\n  then\n    return 0\n  fi\n\n  local _cache_path=\"${_nb_dir:?}/.cache/nb-completion-cache-v2\"\n  local _completions_cached=()\n\n  if [[ ! -e \"${_cache_path}\"   ]]\n  then\n    _nb_cache_completions \"${_cache_path}\"\n  fi\n\n  if [[ -e \"${_cache_path}\"     ]]\n  then\n    local _counter=0\n\n    local              __line=\n    while IFS= read -r __line\n    do\n      _counter=$((_counter+1))\n\n      if [[ \"${_counter}\" -gt 2 ]]\n      then\n        _completions_cached+=(\"${__line}\")\n      fi\n    done < \"${_cache_path}\"\n\n    (_nb_cache_completions \"${_cache_path}\" &)\n  fi\n\n  local _current=\"${COMP_WORDS[COMP_CWORD]}\"\n  COMPREPLY=()\n\n  COMPREPLY=($(compgen -W \"${_completions_cached[*]}\" -- \"${_current}\"))\n}\n\ncomplete -F _nb_subcommands nb\n"
  },
  {
    "path": "etc/nb-completion.fish",
    "content": "#!/usr/bin/env fish\n###############################################################################\n# __          _\n# \\ \\   _ __ | |__\n#  \\ \\ | '_ \\| '_ \\\n#  / / | | | | |_) |\n# /_/  |_| |_|_.__/\n#\n# [nb] Command line and local web note-taking, bookmarking, and archiving with\n# plain text data storage, encryption, filtering and search, pinning, #tagging,\n# Git-backed versioning and syncing, Pandoc-backed conversion, global and local\n# notebooks, customizable color themes, [[wiki-style linking]], plugins, and\n# more in a single portable, user-friendly script.\n#\n# https://github.com/xwmx/nb\n###############################################################################\n\nfunction _nb_subcommands\n  # _cache_completions()\n  #\n  # Usage:\n  #   _cache_completions [-e/--erase file] <path>\n  #\n  # Description:\n  #   Cache completions for `nb`. Generating completions can be slow and\n  #   native shell caching doesn't appear to help.\n  #\n  #   This function will be written into a temporary file and executed.\n  #   You can remove the file after executing itself by the -e/--erase option.\n  function _cache_completions\n    argparse -n _cache_completions -N 1 \"e/erase=\" -- $argv\n      or return 1\n    set _cache_path $argv[1]\n\n    set _commands (nb subcommands)\n    set _notebooks (nb notebooks --names --no-color --unarchived)\n\n    if test -e $_cache_path\n      set __lines (head -n2 $_cache_path)\n      set _commands_cached $__lines[1]\n      set _notebooks_cached $__lines[2]\n    end\n\n    if test \"$_commands_cached\" != (string join \" \" $_commands)\n      or test \"$_notebooks_cached\" != (string join \" \" $_notebooks)\n\n      # Construct <nootbook>:<subcommand> completions.\n      for __notebook in $_notebooks\n        for __command in $_commands\n          if test -n $__notebook\n            and test -n $__command\n            if eval set -q __desc_$__command\n              eval set -a _completions \\$__notebook:\\$__command\\\\t\\$__desc_$__command\n            else\n              set -a _completions $__notebook:$__command\n            end\n          end\n        end\n      end\n\n      set _directory_path (dirname $_cache_path)\n      mkdir -p $_directory_path\n\n      begin\n        echo $_commands\n        echo $_notebooks\n        printf \"%s\\n\" $_completions\n      end > $_cache_path\n    end\n\n    if set -q _flag_erase\n      rm $_flag_erase\n    end\n  end\n\n  set _nb_dir (nb env | string replace -fr \"^NB_DIR=\" \"\")\n\n  if test -z $_nb_dir\n    or not test -e $_nb_dir\n    return\n  else if test -L $_nb_dir\n    set _nb_dir (realpath $_nb_dir)\n  end\n\n  if not test -d $_nb_dir\n    return\n  end\n\n  set _cache_path $_nb_dir/.cache/nb-completion-cache-v2\n\n  if not test -e $_cache_path\n    _cache_completions $_cache_path\n  end\n\n  if test -e $_cache_path\n    tail -n+3 $_cache_path\n\n    # write the func itself into a temporary file and execute it in background\n    set _tmp_file (mktemp -t nb-completion.XXXXXX)\n    begin\n      functions _cache_completions\n      echo \"_cache_completions -e $_tmp_file $_cache_path\"\n    end > $_tmp_file\n    fish $_tmp_file &\n  end\nend\n\ncomplete -c nb -n \"__fish_use_subcommand\" -fa \"(_nb_subcommands)\"\n"
  },
  {
    "path": "etc/nb-completion.zsh",
    "content": "#compdef nb\n###############################################################################\n# __          _\n# \\ \\   _ __ | |__\n#  \\ \\ | '_ \\| '_ \\\n#  / / | | | | |_) |\n# /_/  |_| |_|_.__/\n#\n# [nb] Command line and local web note-taking, bookmarking, and archiving with\n# plain text data storage, encryption, filtering and search, pinning, #tagging,\n# Git-backed versioning and syncing, Pandoc-backed conversion, global and local\n# notebooks, customizable color themes, [[wiki-style linking]], plugins, and\n# more in a single portable, user-friendly script.\n#\n# https://github.com/xwmx/nb\n###############################################################################\n_nb_subcommands() {\n  # _nb_cache_completions()\n  #\n  # Usage:\n  #   _nb_cache_completions <path>\n  #\n  # Description:\n  #   Cache completions for `nb`. Generating completions can be slow and\n  #   native shell caching doesn't appear to help.\n  _nb_cache_completions() {\n    local _cache_path=\"${1:-}\"\n\n    [[ -z \"${_cache_path:-}\" ]] && return 0\n\n    # Remove outdated cache files.\n\n    local _base_cache_path=\"${_cache_path%-*}\"\n\n    local __suffix=\n    for   __suffix in \"zsh\" \"v1\"\n    do\n      if [[ -e \"${_base_cache_path:?}-${__suffix:?}\" ]]\n      then\n        \\rm -f  \"${_base_cache_path:?}-${__suffix:?}\"\n      fi\n    done\n\n    # Rebuild completion cache.\n\n    local _commands=\n    IFS=$'\\n' _commands=($(nb subcommands))\n\n    local _notebooks=\n    IFS=$'\\n' _notebooks=($(nb notebooks --names --no-color --unarchived))\n\n    local _completions=()\n    IFS=$'\\n' _completions=(${_commands[@]})\n\n    local _commands_cached=\n    local _notebooks_cached=\n\n    if [[ -e \"${_cache_path}\"       ]]\n    then\n      local _counter=0\n\n      local               __line=\n      while IFS= read -r  __line\n      do\n        _counter=$((_counter+1))\n\n        if [[   \"${_counter}\" == 1  ]]\n        then\n          _commands_cached=\"${__line}\"\n        elif [[ \"${_counter}\" == 2  ]]\n        then\n          _notebooks_cached=\"${__line}\"\n        else\n          break\n        fi\n      done < \"${_cache_path}\"\n    fi\n\n    if [[ \"${_commands_cached}\"  != \"${_commands[*]:-}\"   ]] ||\n       [[ \"${_notebooks_cached}\" != \"${_notebooks[*]:-}\"  ]]\n    then\n      # Construct <notebook>:<subcommand> completions.\n      local __notebook=\n      for   __notebook in \"${_notebooks[@]}\"\n      do\n        local __command=\n        for   __command in \"${_commands[@]}\"\n        do\n          if [[ -n \"${__notebook:-}\"  ]] &&\n             [[ -n \"${__command:-}\"   ]]\n          then\n            _completions+=(\"${__notebook}:${__command}\")\n          fi\n        done\n      done\n\n      local _directory_path=\n      _directory_path=\"$(dirname \"${_cache_path}\")\"\n\n      mkdir -p \"${_directory_path}\"\n\n      if [[ -f \"${_cache_path:?}\" ]]\n      then\n        \\rm -f \"${_cache_path:?}\"\n      fi\n\n      touch \"${_cache_path:?}\"\n\n      {\n        (IFS=$' '; printf \"%s\\\\n\" \"${_commands[*]}\")\n        (IFS=$' '; printf \"%s\\\\n\" \"${_notebooks[*]}\")\n        printf \"%s\\\\n\" \"${_completions[@]}\"\n      } >> \"${_cache_path}\"\n    fi\n  }\n\n  local _nb_dir=\n  _nb_dir=\"$(nb env | grep 'NB_DIR' | cut -d = -f 2)\"\n\n  if [[ -z \"${_nb_dir:?}\" ]] ||\n     [[ ! -e \"${_nb_dir}\" ]]\n  then\n    return 0\n  elif [[ -L \"${_nb_dir}\" ]]\n  then\n    if hash \"realpath\" 2>/dev/null\n    then\n      _nb_dir=\"$(realpath \"${_nb_dir}\")\"\n    else\n      _nb_dir=\"$(readlink \"${_nb_dir}\")\"\n    fi\n  fi\n\n  if [[ ! -d \"${_nb_dir}\" ]]\n  then\n    return 0\n  fi\n\n  local _cache_path=\"${_nb_dir:?}/.cache/nb-completion-cache-v2\"\n  local _completions_cached=()\n\n  if [[ ! -e \"${_cache_path}\" ]]\n  then\n    _nb_cache_completions \"${_cache_path}\"\n  fi\n\n  if [[ -e \"${_cache_path}\"   ]]\n  then\n    local _counter=0\n\n    local               __line=\n    while IFS= read -r  __line\n    do\n      _counter=$((_counter+1))\n\n      if [[ \"${_counter}\" -gt 2 ]]\n      then\n        _completions_cached+=(\"${__line}\")\n      fi\n    done < \"${_cache_path}\"\n\n    (_nb_cache_completions \"${_cache_path}\" &)\n  fi\n\n  if [[ \"${?}\" -eq 0            ]]\n  then\n    compadd -- \"${_completions_cached[@]}\"\n    return 0\n  else\n    return 1\n  fi\n}\n\n_nb_subcommands \"$@\"\n"
  },
  {
    "path": "nb",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# __          _\n# \\ \\   _ __ | |__\n#  \\ \\ | '_ \\| '_ \\\n#  / / | | | | |_) |\n# /_/  |_| |_|_.__/\n#\n# [nb] Command line and local web note-taking, bookmarking, and archiving with\n# plain text data storage, encryption, filtering and search, pinning, #tagging,\n# Git-backed versioning and syncing, Pandoc-backed conversion, global and local\n# notebooks, customizable color themes, [[wiki-style linking]], plugins, and\n# more in a single portable, user-friendly script.\n#\n# ❯ https://github.com/xwmx/nb\n# ❯ https://xwmx.github.io/nb\n#\n# Based on Bash Boilerplate: https://github.com/xwmx/bash-boilerplate\n#\n# Copyright (c) 2015-present William Melody ┯ hi@williammelody.com\n#                                           ┕ https://www.williammelody.com\n#\n# Overview\n# ========\n#\n# - Configuration and Setup\n# - Helpers: Group 1 (alphabetical order)\n# - Subcommands: Group 1 (alphabetical order)\n# - Plugins\n# - Option Parsing\n# - _main() / Dispatch\n# - Configuration: Group 2\n# - Helpers: Group 2 (alphabetical order)\n# - Subcommands: Group 2 (alphabetical order)\n# - Subcommands: Group 3 (alphabetical order)\n#\n# Target Bash Version:              5   (target,   recommended)\n# Minimum Recommended Bash Version: 4   (fallback, recommended)\n# Minimum Tested Bash Version:      3.2 (fallback, deprecated)\n#\n# AGPLv3\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Affero General Public License as\n# published by the Free Software Foundation, either version 3 of the\n# License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Affero General Public License for more details.\n#\n# You should have received a copy of the GNU Affero General Public License\n# along with this program.  If not, see <https://www.gnu.org/licenses/>.\n###############################################################################\n\n###############################################################################\n# Shell Options & Strict Mode\n#\n# More Information:\n#   https://github.com/xwmx/bash-boilerplate#bash-strict-mode\n#   https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html\n#   https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html\n#   https://tldp.org/LDP/abs/html/options.html\n###############################################################################\n\nset -o errexit\nset -o noglob\nset -o nounset\nset -o pipefail\n\nset +o noclobber\n\nshopt -s extglob\n\nIFS=$'\\n\\t'\n\n###############################################################################\n# Environment\n###############################################################################\n\n# $_VERSION\n#\n# The most recent program version.\n_VERSION=\"7.25.3\"\n\n# $_ME\n#\n# This program's basename.\n_ME=\"$(basename \"${0}\")\"\n\n# $_MY_DIR\n#\n# The directory containing $_ME.\n_MY_DIR=\"$(cd \"$(dirname \"${0}\")\"; pwd)\"\n\n# $_MY_PATH\n#\n# This program's full path.\n_MY_PATH=\"${_MY_DIR}/${_ME}\"\n\n# $_CURRENT_WORKING_DIR\n#\n# The current working directory in which the program was invoked.\n_CURRENT_WORKING_DIR=\"${PWD}\"\n\n# $_REPO\n#\n# The <user>/<repo> identifier for this project's git repository.\n_REPO=\"xwmx/nb\"\n\n# $_REPO_MAIN_BRANCH\n#\n# The name of the main branch in this project's git repository.\n_REPO_MAIN_BRANCH=\"master\"\n\n# $_REPO_RAW_URL\n#\n# The base URL for raw files.\n_REPO_RAW_URL=\"https://raw.githubusercontent.com/${_REPO}/${_REPO_MAIN_BRANCH}\"\n\n###############################################################################\n# Utilities\n###############################################################################\n\n# _command_exists()\n#\n# Usage:\n#   _command_exists <name>\n#\n# Exit / Error / Return Status:\n#   0 (success, true) If a command <name> is defined in the current environment.\n#   1 (error,  false) If not.\n#\n# More Information:\n#   http://stackoverflow.com/a/677212\n_command_exists() {\n  if [[ \"${1:-}\" == \"w3m\" ]]\n  then # Detect WSL 1 (https://stackoverflow.com/a/38859331), where w3m errors.\n    [[ -f /proc/version ]] && grep -q Micro /proc/version && return 1\n  fi\n\n  hash \"${1}\" 2>/dev/null\n}\n\n# _contains()\n#\n# Usage:\n#   _contains <query> <list-item>...\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If the item is included in the list.\n#   1 (error,  false)  If not.\n#\n# Example:\n#   _contains \"${_query}\" \"${_list[@]}\"\n_contains() {\n  local _query=\"${1:-}\"\n\n  shift\n\n  if [[ -z \"${_query}\"  ]] ||\n     [[ -z \"${*:-}\"     ]]\n  then\n    return 1\n  fi\n\n  local __element=\n  for   __element in \"${@}\"\n  do\n    [[ \"${__element}\" == \"${_query}\" ]] && return 0\n  done\n\n  return 1\n}\n\n# _resolve_symlink()\n#\n# Usage:\n#   _resolve_symlink <path>\n#\n# Description:\n#   Resolve the real path or target for a symbolic link.\n_resolve_symlink() {\n  if hash \"realpath\" 2>/dev/null\n  then\n    realpath \"${@:-}\"\n  else\n    readlink \"${@:-}\"\n  fi\n}\n\n# _sed_i()\n#\n# Usage:\n#   _sed_i <sed-argument>...\n#\n# Description:\n#   `sed -i` takes an extension on macOS, but that extension can cause errors\n#   in GNU `sed`. Detect which `sed` is available and call it with the\n#   appropriate arguments.\n#\n# More Information:\n#   https://stackoverflow.com/q/43171648\n#   https://stackoverflow.com/a/16746032\n_sed_i() {\n  local _usage=\n\n  if _usage=\"$(sed --help 2>&1 || false)\"\n  then # GNU\n    sed -i      \"${@}\"\n  else # BSD\n    if [[ \"${_usage:-}\" =~ unknown\\ option ]]\n    then # OpenBSD\n      sed -i''  \"${@}\"\n    else # FreeBSD, macOS\n      sed -i '' \"${@}\"\n    fi\n  fi\n}\n\n# _tput()\n#\n# Usage:\n#   _tput <tput options>...\n#\n# Description:\n#   Run `tput` commands, with fallbacks to termcap names for FreeBSD and\n#   `stty` and escape sequences when `tput` is not found.\n_tput() {\n  if _command_exists \"tput\"\n  then\n    # More info: https://stackoverflow.com/a/64214019\n    case \"${1:-}\" in\n      cols)\n        if tput cols  &>/dev/null\n        then\n          tput cols\n        elif tput co  &>/dev/null\n        then\n          tput co\n        else\n          printf \"80\\\\n\"\n        fi\n\n        return 0\n        ;;\n      lines)\n        if tput lines &>/dev/null\n        then\n          tput lines\n        elif tput li  &>/dev/null\n        then\n          tput li\n        else\n          printf \"20\\\\n\"\n        fi\n\n        return 0\n        ;;\n      setaf|smul)\n        ((${_COLOR_ENABLED:-1}))  || return 0\n        ;;\n    esac\n\n    tput \"${@:-}\" 2>/dev/null     || {\n      case \"${1:-}\" in\n        sgr0)\n          tput me\n          ;;\n        smul)\n          tput us\n          ;;\n        setaf)\n          tput AF \"${@:2}\"\n          ;;\n      esac\n    } 2>/dev/null || printf \"\"\n  else\n    case \"${1:-}\" in\n      cols|lines)\n        {\n          stty size 2>/dev/null   || printf \"20 80\\\\n\"\n        } | if [[ \"${1:-}\" == \"cols\" ]]\n            then\n              cut -d \" \" -f 2\n            else\n              cut -d \" \" -f 1\n            fi\n        ;;\n      setaf)\n        printf '\\033[38;5;%sm'  \"${2:-}\"\n        ;;\n      sgr0)\n        printf '\\033[m'\n        ;;\n      smul)\n        printf '\\033[4m'\n        ;;\n    esac\n  fi\n}\n\n###############################################################################\n# Debug\n###############################################################################\n\n# _debug()\n#\n# Usage:\n#   _debug <command> <options>...\n#\n# Description:\n#   Execute a command and print to standard error. The command is expected to\n#   print a message and should typically be either `echo`, `printf`, or `cat`.\n#\n# Example:\n#   _debug printf \"Debug info. Variable: %s\\\\n\" \"$0\"\n__DEBUG_COUNTER=0\n__DEBUG_START_TIME=\n_debug() {\n  # Usage: __debug_get_timestamp\n  __debug_get_timestamp() {\n    if hash \"gdate\" 2>/dev/null\n    then\n      gdate +%s%3N\n    elif date --version >/dev/null 2>&1\n    then\n      date +%s%3N\n    else\n      return 1\n    fi\n  }\n\n  if ((${_USE_DEBUG:-0}))\n  then\n    __DEBUG_COUNTER=$((__DEBUG_COUNTER+1))\n    printf \"🐛  %s\" \"${__DEBUG_COUNTER} \"\n\n    \"${@}\"\n\n    if [[ -n \"${__DEBUG_START_TIME:-}\" ]]\n    then\n      printf \"⏱  %s\\\\n\" \"$(($(__debug_get_timestamp)-__DEBUG_START_TIME))\"\n    elif __DEBUG_START_TIME=\"$(__debug_get_timestamp)\"\n    then\n      printf \"⏱  0\\\\n\"\n    fi\n\n    printf \"―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\\\\n\"\n  fi 1>&2\n}\n\n###############################################################################\n# Error Messages\n###############################################################################\n\n# _exit_1()\n#\n# Usage:\n#   _exit_1 <command>\n#\n# Description:\n#   Exit with status 1 after executing the specified command with output\n#   redirected to standard error. The command is expected to print a message\n#   and should typically be either `echo`, `printf`, or `cat`.\n_exit_1() {\n  {\n    [[ \"${1:-}\" == \"_help\" ]] || printf \"%s \" \"$(_tput setaf 1)!$(_tput sgr0)\"\n\n    \"${@}\"\n  } 1>&2\n\n  exit 1\n}\n\n# _warn()\n#\n# Usage:\n#   _warn <command>\n#\n# Description:\n#   Print the specified command with output redirected to standard error.\n#   The command is expected to print a message and should typically be either\n#   `echo`, `printf`, or `cat`.\n_warn() {\n  {\n    printf \"%s \" \"$(_tput setaf 1)!$(_tput sgr0)\"\n\n    \"${@}\"\n  } 1>&2\n}\n\n###############################################################################\n# Option Helpers\n###############################################################################\n\n# _option_get_value()\n#\n# Usage:\n#   _option_get_value <option> <value>\n#\n# Description:\n#   Given a flag (e.g., -e | --example) return the value or exit 1 if value\n#   is blank or appears to be another option.\n_option_get_value() {\n  local _option=\"${1:-}\"\n  local _value=\"${2:-}\"\n\n  if [[ -n \"${_value:-}\" ]] && [[ ! \"${_value:-}\" =~ ^- ]]\n  then\n    {\n      printf \"%s\\\\n\" \"${_value}\"\n    } | {\n      if _command_exists \"iconv\"\n      then\n        iconv -c -t utf-8\n      else\n        cat\n      fi\n    }\n  else\n    _exit_1 printf                          \\\n      \"%s requires a valid argument.\\\\n\"    \\\n      \"$(_color_primary \"${_option}\")\"\n  fi\n}\n\n# _option_value_is_present()\n#\n# Usage:\n#   _option_value_is_present <value>\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  The argument is present and does not match as an option\n#                      flag.\n#   1 (error,  false)  The argument is blank or matches as an option flag.\n_option_value_is_present() {\n  [[ -n \"${1:-}\" ]] && [[ ! \"${1:-}\" =~ ^-  ]]\n}\n\n###############################################################################\n# Configuration\n###############################################################################\n\n# Configuration File ####################################### Configuration File\n\n# $NBRC_PATH\n#\n# Default: `$HOME/.nbrc`\n#\n# The location of the .nbrc configuration file.\nexport NBRC_PATH=\"${NBRC_PATH:-\"${HOME}/.${_ME}rc\"}\"\n\n# Handle symlinked NBRC_PATH.\nif [[ -L \"${NBRC_PATH}\" ]]\nthen\n  NBRC_PATH=\"$(_resolve_symlink \"${NBRC_PATH}\")\"\nfi\n\n# Source rc file.\nif [[ -e \"${NBRC_PATH}\" ]]\nthen\n  source \"${NBRC_PATH}\"\nfi\n\n# NB_DIR ############################################################### NB_DIR\n\n# $NB_DIR\n#\n# Default: `$HOME/.nb`\n#\n# The location of the directory that contains the notebooks.\nexport NB_DIR=\"${NB_DIR:-\"${HOME}/.${_ME}\"}\"\n\n# Handle symlinked NB_DIR.\nif [[ -L \"${NB_DIR:-}\"      ]]\nthen\n  NB_DIR=\"$(_resolve_symlink \"${NB_DIR}\")\"\nfi\n\n# Validate that NB_DIR exists and is writable.\nif [[ -z \"${NB_DIR:?}\"      ]] ||\n   [[    \"${NB_DIR}\" == \"/\" ]] ||\n   {\n     [[   -e \"${NB_DIR}\"    ]] &&\n     [[ ! -w \"${NB_DIR}\"    ]]\n   }\nthen\n  _exit_1 cat <<HEREDOC\nNB_DIR is not valid:\n  ${NB_DIR}\n\nRemove any NB_DIR settings in .${_ME}rc to reset to default:\n  ${NBRC_PATH}\n\nNB_DIR settings prompt:\n  ${_ME} settings nb_dir\nHEREDOC\nfi\n\n# Current Notebook ########################################### Current Notebook\n\n# $NB_NOTEBOOK_PATH\n#\n# Default: ''\n#\n# The path to the current notebook.\nexport NB_NOTEBOOK_PATH=\"${NB_NOTEBOOK_PATH:-}\"\n\n# $_GLOBAL_NOTEBOOK_PATH\n#\n# The path of the current global notebook.\nexport _GLOBAL_NOTEBOOK_PATH=\n\n# $_LOCAL_NOTEBOOK_PATH\n#\n# The path of the local notebook, if one is found. The current working\n# directory and all parents are searched.\nexport _LOCAL_NOTEBOOK_PATH=\n\n# __set_notebook_paths()\n#\n# Usage:\n#   __set_notebook_paths\n#\n# Description:\n#   Set the notebook path variables to reflect the current environment.\n__set_notebook_paths() {\n  __set_local_notebook_path() {\n    if [[ \"${PWD}\" == \"/\" ]]\n    then\n      cd \"${_CURRENT_WORKING_DIR}\"\n\n      return 0\n    elif [[ -d \"${PWD}/.git\"    ]] &&\n         [[ -f \"${PWD}/.index\"  ]]\n    then\n      _LOCAL_NOTEBOOK_PATH=\"${PWD}\"\n\n      cd \"${_CURRENT_WORKING_DIR}\"\n\n      return 0\n    else\n      cd ..\n      __set_local_notebook_path\n    fi\n  }; __set_local_notebook_path\n\n  __set_global_notebook_path() {\n    if [[ -n \"${NB_NOTEBOOK_PATH:-}\"  ]]\n    then\n      _GLOBAL_NOTEBOOK_PATH=\"${NB_NOTEBOOK_PATH}\"\n    elif [[ -e \"${NB_DIR}/.current\"   ]]\n    then\n      local _global_notebook_name=\n      _global_notebook_name=\"$(<\"${NB_DIR}/.current\")\"\n\n      if [[ -d \"${NB_DIR}/${_global_notebook_name}\" ]]\n      then\n        _GLOBAL_NOTEBOOK_PATH=\"${NB_DIR}/${_global_notebook_name}\"\n      fi\n    else\n      _GLOBAL_NOTEBOOK_PATH=\"${NB_DIR}/home\"\n    fi\n  }; __set_global_notebook_path\n\n  if [[ -n \"${_LOCAL_NOTEBOOK_PATH:-}\" ]]\n  then\n    NB_NOTEBOOK_PATH=\"${_LOCAL_NOTEBOOK_PATH}\"\n  else\n    NB_NOTEBOOK_PATH=\"${_GLOBAL_NOTEBOOK_PATH}\"\n  fi\n}; __set_notebook_paths\n\n# Source notebook configuration file.\n\nif [[ -e \"${NB_NOTEBOOK_PATH}/.nbrc\" ]]\nthen\n  # shellcheck disable=SC1091\n  source \"${NB_NOTEBOOK_PATH}/.nbrc\"\nfi\n\n# Base Configuration ####################################### Base Configuration\n\n# $NB_AUDIO_TOOL\n#\n# Default: '' (first available)\n#\n# Example Values: 'mplayer', 'afplay'\nexport NB_AUDIO_TOOL=\"${NB_AUDIO_TOOL:-}\"\n\n# $NB_AUTO_SYNC\n#\n# Default: '1'\n#\n# When set to '1', each `_git checkpoint()` call will automativally run\n# `$_ME sync`. To disable this behavior, set the value to '0'.\nexport NB_AUTO_SYNC=\"${NB_AUTO_SYNC:-1}\"\n\n# $NB_AUTO_SYNC_SECONDS\n#\n# Default: '60'\n#\n# The minimum number of seconds between automatic Git sync operations when\n# `$NB_AUTO_SYNC` is enabled.\nexport NB_AUTO_SYNC_SECONDS=\"${NB_AUTO_SYNC_SECONDS:-60}\"\n\n# $NB_BROWSER\n#\n# Default: value of $BROWSER\n#\n# Example Values: 'links', 'w3m'\nexport NB_BROWSER=\"${NB_BROWSER:-${BROWSER:-}}\"\n\n# $NB_DATA_TOOL\n#\n# Default: '' (first available)\n#\n# Example Values: 'visidata', 'sc-im'\nexport NB_DATA_TOOL=\"${NB_DATA_TOOL:-}\"\n\n# $NB_DEFAULT_EXTENSION\n#\n# Default: 'md'\n#\n# Example Values: 'md' 'org'\nexport NB_DEFAULT_EXTENSION=\"${NB_DEFAULT_EXTENSION:-md}\"\n\n# $NB_DEFAULT_TEMPLATE\n#\n# Default: ''\n#\n# A string template or a path to a template file.\n#\n# Example Values: '/path/to/template/file' '# {{title}} {{content}}'\nexport NB_DEFAULT_TEMPLATE=\"${NB_DEFAULT_TEMPLATE:-}\"\n\n# $NB_DIRECTORY_TOOL\n#\n# Default: '' (nb browse)\n#\n# Example Values: 'ranger', 'mc'\nexport NB_DIRECTORY_TOOL=\"${NB_DIRECTORY_TOOL:-}\"\n\n# $NB_ENCRYPTION_TOOL\n#\n# Default: 'openssl'\n#\n# Supported Values: 'gpg' 'openssl'\nexport NB_ENCRYPTION_TOOL=\"${NB_ENCRYPTION_TOOL:-openssl}\"\n\n# $NB_FOOTER\n#\n# Default: '1'\n#\n# Supported Values: '0' '1'\nexport NB_FOOTER=\"${NB_FOOTER:-1}\"\n\n# $NB_GUI_BROWSER\n#\n# Default: ''\n#\n# Example Value: 'firefox'\nexport NB_GUI_BROWSER=\"${NB_GUI_BROWSER:-}\"\n\n# $NB_HEADER\n#\n# Default: '2'\n#\n# Supported Values: '0' '1' '2' '3'\nexport NB_HEADER=\"${NB_HEADER:-2}\"\n\n# $NB_IMAGE_TOOL\n#\n# Default: '' (first available)\n#\n# Example Values: 'imgcat', 'catimg'\nexport NB_IMAGE_TOOL=\"${NB_IMAGE_TOOL:-}\"\n\n# $NB_SERVER_HOST\n#\n# Default: 'localhost'\nexport NB_SERVER_HOST=\"${NB_SERVER_HOST:-localhost}\"\n\n# $NB_SERVER_PORT\n#\n# Default: '6789'\nexport NB_SERVER_PORT=\"${NB_SERVER_PORT:-6789}\"\n\n# $NB_SYNTAX_THEME\n#\n# Default: 'base16'\n#\n# Supported Values: Theme names listed with `bat --list-themes`\nexport NB_SYNTAX_THEME=\"${NB_SYNTAX_THEME:-base16}\"\n\n# $_GIT_ENABLED\n#\n# Default: '1'\n#\n# Supported Values: '0' '1'\nexport _GIT_ENABLED=\"${_GIT_ENABLED:-1}\"\n\n# limit ################################################################# limit\n\n# $NB_LIMIT\n#\n# Default: '15'\n#\n# Set to a positive number to limit the output of `nb` and `nb ls` to that value.\n# Set to \"auto\" to automatically limit output to the current terminal height.\n# Set a maximum auto limit with `auto^<max>`, e.g., `auto^15`.\n# Subtract an auto limit offset for multiline prompts with `auto-<offset>`.\n# Add an auto limit offet with `auto+<offset>`.\n# Combine both modifiers with `auto-<offset>^<max>` or `auto+<offset>^<max>`.\n#\n# Supported Values:\n#   - <max>\n#   - auto\n#   - auto^<max>\n#   - auto-<offset>\n#   - auto+<offset>\n#   - auto-<offset>^<max>\n#   - auto+<offset>^<max>\n#\n# Example Values:\n#   - 15\n#   - auto\n#   - auto^15\n#   - auto-2\n#   - auto+2\n#   - auto-2^15\n#   - auto+2^15\n\nexport _AUTO_LIMIT=\nexport _AUTO_LIMIT_MAX=\n\ncase \"${NB_LIMIT:-}\" in\n  auto*)\n    _AUTO_LIMIT=\"${NB_LIMIT#auto}\"\n    _AUTO_LIMIT=\"${_AUTO_LIMIT%^*}\"\n    _AUTO_LIMIT=\"${_AUTO_LIMIT:-0}\"\n\n    if [[ \"${NB_LIMIT:-}\" =~ \\^     ]]\n    then\n      _AUTO_LIMIT_MAX=\"${NB_LIMIT#*^}\"\n    fi\n\n    export NB_LIMIT=\"${NB_LIMIT}\"\n    ;;\n  *)\n    export _AUTO_LIMIT=\n    export NB_LIMIT=\"${NB_LIMIT:-15}\"\n  ;;\nesac\n\n# $EDITOR ############################################################# $EDITOR\n\n# $NB_EDITOR\n#\n# Default: value of $EDITOR or $VISUAL\n#\n# Example Values: 'vim', `code`'\nNB_EDITOR=\"${NB_EDITOR:-${EDITOR:-${VISUAL:-}}}\"\n\n__set_editor() {\n  local _editors=(\n    editor\n    code\n    subl\n    hx\n    micro\n    mate\n    macdown\n    nano\n    pico\n    vim\n    vi\n    emacs\n  )\n\n  if [[   -z \"${NB_EDITOR:-}\" ]]\n  then\n    local __editor=\n    for   __editor in \"${_editors[@]}\"\n    do\n      if hash \"${__editor}\" 2>/dev/null\n      then\n        NB_EDITOR=\"${__editor}\"\n\n        break\n      fi\n    done\n\n    if [[ -z \"${NB_EDITOR:-}\" ]]\n    then\n      cat <<HEREDOC\nCommand line text editor not found. Set the \\$EDITOR variable in your\nenvironment or in the \\`${_ME}\\` configuration file located at:\n  ${NBRC_PATH}\n\nMore information about setting \\$EDITOR:\n  https://askubuntu.com/q/432524\n\n\\`${_ME}\\` uses text editors with command line support, such as:\n\n- Visual Studio Code\n    https://code.visualstudio.com\n- Sublime Text\n    https://www.sublimetext.com\n- Atom\n    https://atom.io\n- MacDown\n    https://macdown.uranusjr.com\n- Vim\n    https://en.wikipedia.org/wiki/Vim_(text_editor)\n- Emacs\n    https://en.wikipedia.org/wiki/Emacs\n- TextMate\n    https://macromates.com\n- Helix\n    https://helix-editor.com\n- micro\n    https://github.com/zyedidia/micro\n- nano\n    https://en.wikipedia.org/wiki/GNU_nano\n- or many of these:\n    https://en.wikipedia.org/wiki/List_of_text_editors\nHEREDOC\n      exit 1\n    fi\n  fi\n}; __set_editor\n\n# Indicators ####################################################### Indicators\n\n# $NB_INDICATOR_<type>\n#\n# Description:\n#   Reassign or turn off file type indicator icons.\n#\n# Examples:\n#   # reassign pinned indicator\n#   export NB_INDICATOR_PINNED=\"💖\"\n#\n#   # turn off bookmark indicators\n#   export NB_INDICATOR_BOOKMARK=\"\"\n#\n# Parameter Expansion:\n#   |    | set / not blank | set / blank |    unset    |\n#   ----------------------------------------------------\n#   | -  |    parameter    |    blank    | replacement |\n#   | :+ |   replacement   |    blank    |    blank    |\n\n# $NB_INDICATOR_AUDIO\nexport  NB_INDICATOR_AUDIO=\"${NB_INDICATOR_AUDIO-🔉}\"\nexport _NB_INDICATOR_AUDIO=\"${NB_INDICATOR_AUDIO:+\"${NB_INDICATOR_AUDIO} \"}\"\n\n# $NB_INDICATOR_BOOKMARK\nexport  NB_INDICATOR_BOOKMARK=\"${NB_INDICATOR_BOOKMARK-🔖}\"\nexport _NB_INDICATOR_BOOKMARK=\"${NB_INDICATOR_BOOKMARK:+\"${NB_INDICATOR_BOOKMARK} \"}\"\n\n# $NB_INDICATOR_DOCUMENT\nexport  NB_INDICATOR_DOCUMENT=\"${NB_INDICATOR_DOCUMENT-📄}\"\nexport _NB_INDICATOR_DOCUMENT=\"${NB_INDICATOR_DOCUMENT:+\"${NB_INDICATOR_DOCUMENT} \"}\"\n\n# $NB_INDICATOR_EBOOK\nexport  NB_INDICATOR_EBOOK=\"${NB_INDICATOR_EBOOK-📖}\"\nexport _NB_INDICATOR_EBOOK=\"${NB_INDICATOR_EBOOK:+\"${NB_INDICATOR_EBOOK} \"}\"\n\n# $NB_INDICATOR_ENCRYPTED\nexport  NB_INDICATOR_ENCRYPTED=\"${NB_INDICATOR_ENCRYPTED-🔒}\"\nexport _NB_INDICATOR_ENCRYPTED=\"${NB_INDICATOR_ENCRYPTED:+\"${NB_INDICATOR_ENCRYPTED} \"}\"\n\n# $NB_INDICATOR_FOLDER\nexport  NB_INDICATOR_FOLDER=\"${NB_INDICATOR_FOLDER-📂}\"\nexport _NB_INDICATOR_FOLDER=\"${NB_INDICATOR_FOLDER:+\"${NB_INDICATOR_FOLDER} \"}\"\n\n# $NB_INDICATOR_IMAGE\nexport  NB_INDICATOR_IMAGE=\"${NB_INDICATOR_IMAGE-🌄}\"\nexport _NB_INDICATOR_IMAGE=\"${NB_INDICATOR_IMAGE:+\"${NB_INDICATOR_IMAGE} \"}\"\n\n# $NB_INDICATOR_PINNED\nexport  NB_INDICATOR_PINNED=\"${NB_INDICATOR_PINNED-📌}\"\nexport _NB_INDICATOR_PINNED=\"${NB_INDICATOR_PINNED:+\"${NB_INDICATOR_PINNED} \"}\"\n\n# $NB_INDICATOR_TODO\nexport  NB_INDICATOR_TODO=\"${NB_INDICATOR_TODO-✔️ }\"\nexport _NB_INDICATOR_TODO=\"${NB_INDICATOR_TODO:+\"${NB_INDICATOR_TODO} \"}\"\n\n# $NB_INDICATOR_TODO_DONE\nexport  NB_INDICATOR_TODO_DONE=\"${NB_INDICATOR_TODO_DONE-✅}\"\nexport _NB_INDICATOR_TODO_DONE=\"${NB_INDICATOR_TODO_DONE:+\"${NB_INDICATOR_TODO_DONE} \"}\"\n\n# $NB_INDICATOR_VIDEO\nexport  NB_INDICATOR_VIDEO=\"${NB_INDICATOR_VIDEO-📹}\"\nexport _NB_INDICATOR_VIDEO=\"${NB_INDICATOR_VIDEO:+\"${NB_INDICATOR_VIDEO} \"}\"\n\n# Color ################################################################# Color\n\n# $_COLOR_ENABLED\n#\n# Default: '1'\n#\n# Supported Values: '0' '1'\nexport _COLOR_ENABLED=\"${_COLOR_ENABLED:-1}\"\n\n# $NB_COLOR_THEME\n#\n# Default: 'nb'\n#\n# The color theme.\nexport NB_COLOR_THEME=\"${NB_COLOR_THEME:-nb}\"\n\ncase \"${NB_COLOR_THEME}\" in\n  nb)\n    : # Colors assigned as default values below.\n    ;;\n  blacklight)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-39}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-56}\"\n    ;;\n  console)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-40}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-28}\"\n    ;;\n  desert)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-179}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-95}\"\n    ;;\n  electro)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-200}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-62}\"\n    ;;\n  forest)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-29}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-59}\"\n    ;;\n  lavender)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-183}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-61}\"\n    ;;\n  mage)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-199}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-55}\"\n    ;;\n  mint)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-43}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-60}\"\n    ;;\n  ocean)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-75}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-26}\"\n    ;;\n  raspberry)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-162}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-90}\"\n    ;;\n  smoke|monochrome)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-248}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-241}\"\n    ;;\n  unicorn)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-183}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-153}\"\n    ;;\n  utility)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-227}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-8}\"\n    ;;\n  1)\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-164}\"\n    export NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-60}\"\n    ;;\nesac\n\nexport _NB_COLOR_THEMES=(\n  blacklight\n  console\n  desert\n  electro\n  forest\n  nb\n  ocean\n  raspberry\n  smoke\n  unicorn\n  utility\n)\n\n# User defined themes can be installed in the $NB_DIR/.plugins directory.\n# Themes have an .nb-theme extension and contain a single if statement\n# assigning the color environment variables to tput ANSI color numbers.\n#\n# Example:\n#\n#     # filename: ~/.nb/.plugins/example.nb-theme\n#     if [[ \"${NB_COLOR_THEME}\" == \"example\" ]]\n#     then\n#       export NB_COLOR_PRIMARY=68\n#       export NB_COLOR_SECONDARY=8\n#     fi\n#\n#  To view a list of available color numbers, run `nb settings colors`\n__load_themes() {\n  if [[   -d \"${NB_DIR}/.themes\"  ]] &&\n     [[ ! -e \"${NB_DIR}/.plugins\" ]]\n  then # migrate legacy .themes directory. TODO: Remove.\n    mv \"${NB_DIR}/.themes\" \"${NB_DIR}/.plugins\"\n  fi\n\n  if [[ -d \"${NB_DIR}/.plugins\"   ]]\n  then\n    set +f\n    local __file=\n    for   __file in \"${NB_DIR}/.plugins\"/*.\"${_ME}\"-theme*\n    do\n      if [[ -e \"${__file}\"        ]]\n      then\n        local _basename=\n        _basename=\"$(basename \"${__file}\")\"\n\n        local _name=\"${_basename%%.*}\"\n\n        _NB_COLOR_THEMES+=(\"${_name}\")\n\n        source \"${__file}\"\n      fi\n    done\n    set -f\n  fi\n}; __load_themes\n\n# $NB_COLOR_PRIMARY\n#\n# Default: Value depends on terminal capabilities.\n#\n# Set highlighting color. This should be set to an xterm color number, usually\n# a value between 1 and 256. For a table of common colors and their numbers\n# run:\n#\n#   nb settings colors\n#\n# Supported Values: [0..255+]\n__set_color_primary() {\n  local _colors=\n  _colors=\"$(_tput colors)\"\n\n  if [[ -n \"${_colors}\" ]] && [[ \"${_colors}\" -gt 8 ]]\n  then\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-69}\"\n  else\n    export NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-4}\"\n  fi\n}; __set_color_primary\n\n# $NB_COLOR_SECONDARY\n#\n# Default: '8'\n#\n# Color for lines and other accents. This should be set to an xterm color\n# number, usually a value between 1 and 256. For a table of common colors and\n# their numbers, run:\n#\n#   nb settings colors\n#\n# Supported Values: [0..255+]\nexport NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-8}\"\n\n# Color Variables\n#\n# Avoid multiple tput calls by assigning output to variables.\nexport _TPUT_SGR0=\nif [[ -n \"${TMUX:-}\" ]]\nthen\n  # Avoid `tmux` and `less` quirks: https://unix.stackexchange.com/a/446541\n  _TPUT_SGR0=\"$(printf '\\033[m')\"\nelse\n  _TPUT_SGR0=\"$(_tput sgr0)\"\nfi\n\nexport _TPUT_COLOR_PRIMARY=\n       _TPUT_COLOR_PRIMARY=\"$(_tput setaf \"${NB_COLOR_PRIMARY}\")\"\n\nexport _TPUT_COLOR_SECONDARY=\n       _TPUT_COLOR_SECONDARY=\"$(_tput setaf \"${NB_COLOR_SECONDARY}\")\"\n\nexport _TPUT_SETAF_8=\n       _TPUT_SETAF_8=\"$(_tput setaf 8)\"\n\nexport _TPUT_SMUL=\n       _TPUT_SMUL=\"$(_tput smul)\"\n\n# _color_brackets()\n#\n# Usage:\n#   _color_brackets <string>\n#\n# Description:\n#   Print <string> with surrounding color brackets.\n_color_brackets() {\n  if ! ((_COLOR_ENABLED))\n  then\n    printf \"[%s]\" \"${1:-}\"\n\n    return 0\n  fi\n\n  printf \"%s%s[%s%s%s]%s\"     \\\n    \"${_TPUT_SGR0}\"           \\\n    \"${_TPUT_SETAF_8}\"        \\\n    \"${_TPUT_COLOR_PRIMARY}\"  \\\n    \"${1:-}\"                  \\\n    \"${_TPUT_SETAF_8}\"        \\\n    \"${_TPUT_SGR0}\"\n}\n\n# _color_muted()\n#\n# Usage:\n#   _color_muted <string>\n#\n# Print the given string with the muted color.\n_color_muted() {\n  if ! ((_COLOR_ENABLED))\n  then\n    printf \"%s\" \"${1:-}\"\n\n    return 0\n  fi\n\n  printf \"%s%s%s%s\"     \\\n    \"${_TPUT_SGR0}\"     \\\n    \"${_TPUT_SETAF_8}\"  \\\n    \"${1:-}\"            \\\n    \"${_TPUT_SGR0}\"\n}\n\n# _color_primary()\n#\n# Usage:\n#   _color_primary <string> [--underline]\n#\n# Description:\n#   Use `tput` to highlight the given string.\n_color_primary() {\n  if ! ((_COLOR_ENABLED))\n  then\n    printf \"%s\\\\n\" \"${1:-}\"\n\n    return 0\n  fi\n\n  if [[ \"${2:-}\" == \"--underline\" ]]\n  then\n    printf \"%s%s%s%s%s\\\\n\"        \\\n      \"${_TPUT_SGR0}\"             \\\n      \"${_TPUT_SMUL}\"             \\\n      \"${_TPUT_COLOR_PRIMARY}\"    \\\n      \"${1:-}\"                    \\\n      \"${_TPUT_SGR0}\"\n  else\n    printf \"%s%s%s%s\\\\n\"          \\\n      \"${_TPUT_SGR0}\"             \\\n      \"${_TPUT_COLOR_PRIMARY}\"    \\\n      \"${1:-}\"                    \\\n      \"${_TPUT_SGR0}\"\n  fi\n}\n\n# _color_secondary()\n#\n# Usage:\n#   _color_secondary <string>\n#\n# Description:\n#   Highlight the given string using the accent color.\n_color_secondary() {\n  if ! ((_COLOR_ENABLED))\n  then\n    printf \"%s\\\\n\" \"${1:-}\"\n\n    return 0\n  fi\n\n  printf \"%s%s%s\\\\n\" \"${_TPUT_COLOR_SECONDARY}\" \"${1:-}\" \"${_TPUT_SGR0}\"\n}\n\n# Unset CLICOLOR_FORCE to avoid unexpected color output in `ls` et al.\nunset CLICOLOR_FORCE\n\n# Cache & Temp ################################################### Cache & Temp\n\n# $_NB_CACHE_PATH\n#\n# The full path to the cache directory.\nexport _NB_CACHE_PATH=\"${NB_DIR}/.cache\"\n\nif [[   -d \"${NB_DIR}\"          ]] &&\n   [[ ! -e \"${_NB_CACHE_PATH}\"  ]]\nthen\n  mkdir -p \"${_NB_CACHE_PATH}\"\nfi\n\n# $TMPDIR\n#\n# Reset $TMPDIR if it's set to the current working directory by npm.\nif [[ \"${TMPDIR:-}\" == \"${PWD}\" ]]\nthen\n  export TMPDIR=\"/tmp\"\nfi\n\n# $_NB_TEMP_DIRECTORY\n#\n# The full path to the temp directory.\nexport _NB_TEMP_DIRECTORY\n_NB_TEMP_DIRECTORY=\"$(mktemp -d)\"\n\n# $_NB_TEMP_PIDS\n#\n# A list of PIDS that should be terminated on exit.\n_NB_TEMP_PIDS=()\n\n# _temp()\n#\n# Usage:\n#   _temp cache [clear]\n#   _temp cleanup\n#   _temp directory\n#   _temp file [<basename> | <relative-path> | <extension>] [--touch]\n#   _temp pid <pid>\n#\n# Subcommands:\n#   cache       Print the full path to the cache directory, or optionally clear\n#               the cache.\n#   cleanup     Force delete the temp directory.\n#   directory   Print the full path the the temp directory.\n#   file        Initialize a temporary file path.\n#   pid         Specify a process ID that should be terminated on exit.\n#\n# Description:\n#   Manage temp and cache files and directories.\n_temp() {\n  # Usage: _temp_validate_path <path>\n  _temp_validate_path() {\n    [[ -n \"${1:?}\"              ]] &&\n    [[    \"${1}\" != \"/\"         ]] &&\n    [[    \"${1}\" != \"${HOME}\"   ]] &&\n    [[    \"${1}\" != \"${PWD}\"    ]] &&\n    [[ -e \"${1}\"                ]]\n  }\n\n  local _subcommand=\"${1:-}\"\n\n  case \"${_subcommand}\" in\n    cache)\n      if [[ \"${2:-}\" == \"clear\" ]]\n      then\n        if _temp_validate_path \"${_NB_CACHE_PATH:?}\"\n        then\n          rm -r \"${_NB_CACHE_PATH:?}\"\n          mkdir -p \"${_NB_CACHE_PATH}\"\n        fi\n      else\n        printf \"%s\\\\n\" \"${_NB_CACHE_PATH}\"\n      fi\n      ;;\n    cleanup)\n      if _temp_validate_path \"${_NB_TEMP_DIRECTORY:?}\"\n      then\n        rm -rf \"${_NB_TEMP_DIRECTORY:?}\"\n      fi\n\n      local __pid=\n      for   __pid in \"${_NB_TEMP_PIDS[@]:-}\"\n      do\n        [[ -n \"${__pid:-}\" ]] || continue\n\n        kill \"${__pid}\" 2>/dev/null || :\n      done\n      ;;\n    dir|directory)\n      printf \"%s\\\\n\" \"${_NB_TEMP_DIRECTORY:-}\"\n      ;;\n    file)\n      local _extension=\n      local _relative_path=\n      local _touch=0\n\n      local __arg=\n      for   __arg in \"${2:-}\" \"${3:-}\"\n      do\n        case \"${__arg}\" in\n          \"\")       :                           ;;\n          --touch)  _touch=1                    ;;\n          \\.*)      _extension=\"${__arg:-}\"     ;;\n          *)        _relative_path=\"${__arg:-}\" ;;\n        esac\n      done\n\n      local _temp_file_path=\n\n      if [[ -z  \"${_relative_path:-}\"       ]]\n      then\n        _temp_file_path=\"${_NB_TEMP_DIRECTORY}/${RANDOM}${_extension:-}\"\n      else\n        _temp_file_path=\"${_NB_TEMP_DIRECTORY}/${_relative_path:-}\"\n      fi\n\n      if [[     \"${_relative_path:-}\" =~ /  ]]\n      then\n        mkdir -p \"${_temp_file_path%/*}\"\n      fi\n\n      if ((_touch))\n      then\n        touch \"${_temp_file_path}\"\n      fi\n\n      printf \"%s\\\\n\" \"${_temp_file_path:-}\"\n      ;;\n    pid)\n      _NB_TEMP_PIDS+=(\"${2:?}\")\n      ;;\n  esac\n}\n\ntrap \"_temp cleanup\"                        EXIT\ntrap \"exit\"                                 INT\ntrap 'printf \"\\\\n\"; _temp cleanup; exit 0'  SIGINT\ntrap 'printf \"\\\\n\"; _temp cleanup; exit 0'  SIGTERM\n\n###############################################################################\n# Configuration Validation\n###############################################################################\n\n# _validate_configuration()\n#\n# Usage:\n#   _validate_configuration\n#\n# Description:\n#   Check the runtime environment and display an error message when running in\n#   an unsupported configuration.\n_validate_configuration() {\n  if { ((${NB_BASH_UPDATE_PROMPT_ENABLED:-0}))        ||\n       {\n         [[ \"${BASH_VERSINFO[0]:-999999999}\" -lt 4 ]] &&\n         ((${NB_BASH_UPDATE_PROMPT_ENABLED:-1}))\n       }\n     }                                                &&\n     _command_exists \"brew\"                           &&\n     {\n       # command initiated by user\n       [[ -t 1                          ]]            ||\n       ((${NB_TEST_MOCK_TTY:-0}))\n     }\n  then\n    local _config_file_path=\"${NB_DIR}/.nb-bash-3-enabled\"\n\n    if [[ -e \"${_config_file_path}\"     ]]\n    then\n      local _config_file_version=\n      _config_file_version=\"$(head -n 1 \"${_config_file_path:-}\")\"\n\n      if [[ \"${_config_file_version:-}\" != \"${_VERSION}\" ]] ||\n         ((${NB_BASH_UPDATE_PROMPT_ENABLED:-0}))\n      then\n        rm \"${_config_file_path:?}\"\n      fi\n    fi\n\n    if [[ ! -e \"${_config_file_path:-}\" ]]  &&\n       ((${NB_BASH_UPDATE_PROMPT_ENABLED:-1}))\n    then\n      local _color_me=\n      _color_me=\"$(_color_muted '`')$(_color_primary \"${_ME}\")$(_color_muted '`')\"\n\n      {\n        printf \"Update Bash\\\\n\"\n        printf \"%s\\\\n\" \"$(_color_muted  \"-------------\")\"\n\n        cat <<HEREDOC\n${_color_me} works best with the current version of Bash.\n\n${_color_me} can $(_color_primary \"update\") your system to $(_color_primary \"Bash 5\") via Homebrew\nor you can proceed with Bash 3.2.\n\nAnswering $(_color_primary \"y\") or $(_color_primary \"yes\") will run the following command:\n\n  $(_color_primary \"brew install bash\")\n\nThis command could take a minute to run.\nHEREDOC\n      } | _warn printf \"%s\\\\n\" \"$(cat)\"\n\n      while true\n      do\n        local __yn=\n\n        if _contains \"-y\"     \"${@:-}\" ||\n           _contains \"--yes\"  \"${@:-}\"\n        then\n          __yn=\"y\"\n        else\n          printf \"%s\\\\n\" \"$(_color_muted \"------------------------\")\"\n\n          IFS='' read -r -e -d $'\\n' -p   \\\n\"$(_color_primary \"Update\") to Bash 5?  $(_color_brackets \"y/N\") \" __yn\n        fi\n\n        case \"${__yn}\" in\n          [Yy]*)\n            printf \"\\\\n\"\n\n            _warn printf \"Updating Bash%s\\\\n\\\\n\" \"$(_color_muted \"...\")\"\n\n            if brew install bash\n            then\n              printf \"\\\\n\"\n\n              {\n                printf \"%s\\\\n\"    \"$(_color_muted  \"------------------\")\"\n                printf \"  %s to %s!\\\\n\"         \\\n                  \"$(_color_primary \"Updated\")\" \\\n                  \"$(_color_primary \"Bash 5\")\"\n                printf \"  %s\\\\n\"  \"$(_color_muted  \"------------------\")\"\n              } | _warn printf \"%s\\\\n\" \"$(cat)\"\n\n              printf \"\\\\n\"\n            else\n              printf \"\\\\n\"\n\n              _warn printf \"Unable to update to Bash 5.\\\\n\\\\n\"\n            fi\n\n\n            if [[ -e \"${_config_file_path:?}\" ]]\n            then\n              rm \"${_config_file_path:?}\"\n            fi\n\n            break\n            ;;\n          *)\n            cat <<HEREDOC > \"${_config_file_path:?}\"\n${_VERSION}\n\nThis presence of this file indicates that Bash 3 support is enabled.\nHEREDOC\n\n            printf \"\\\\n\"\n\n            {\n              printf \"%s\\\\n\" \"$(_color_muted    \"-------------------------\")\"\n              printf                          \"  Bash 3.2 support enabled.\\\\n\"\n              printf \"%s\\\\n\" \"$(_color_muted  \"  -------------------------\")\"\n            } | _warn printf \"%s\\\\n\" \"$(cat)\"\n\n            printf \"\\\\n\"\n\n            break\n            ;;\n        esac\n      done\n    fi\n  fi\n}\n\nif [[ -e \"${NB_DIR:-}\" ]]\nthen\n  _validate_configuration \"${@:-}\"\nfi\n\n###############################################################################\n# Helpers: Group 1                                             Helpers: Group 1\n# ----------------                                             ----------------\n###############################################################################\n# --------------------------------------------------------------------------- #\n\n# $_BT\n#\n# Backtick with ANSI-C quoting for string building.\n_BT=$'`'\n\n# $_CHEVRON_LEFT\n#\n# A left-pointing chevron character.\n_CHEVRON_LEFT=\"❮\"\n\n# $_CHEVRON_RIGHT\n#\n# A right-pointing chevron character.\n_CHEVRON_RIGHT=\"❯\"\n\n# $_COLUMNS\n#\n# The terminal width in number of columns (characters).\n_COLUMNS=\"$(_tput cols)\"\n\n# $_FILE_TYPES\n#\n# An array of supported aggregate file types.\n_FILE_TYPES=(archive audio bookmark document folder image text video)\n\n# $_IGNORE_PATTERNS\n#\n# An array of filename patterns to ignore, formatted as `sed -e` arguments.\n_IGNORE_PATTERNS=(\n  -e '/~$/d'\n  -e '/^#.*#$/d'\n  -e '/\\.swa?p$/d'\n  -e '/^\\.#*/d'\n  -e '/.*_ltex\\.json$/d' # ltex-utils.nvim\n)\n\n# $_MD\n#\n# Middle dot character.\n_MD=\"·\"\n\n# $_NBSP\n#\n# No-break space character.\n_NBSP=\" \"\n\n# $_NEWLINE\n#\n# Newline with ANSI-C quoting for string building.\n_NEWLINE=$'\\n'\n\n# $_SLASH\n#\n# Slash with ANSI-C quoting for string building support and macOS Bash\n# string substitution.\n_SLASH=$'/'\n\n# _URL_PATTERNS\n#\n# Patterns for matching URLs.\n#\n# https://en.wikipedia.org/wiki/List_of_URI_schemes\nexport _URL_PATTERNS=(\n  \"([.a-z0-9+-]+)://[^[:space:]]+\"\n  \"(afp|attachment|platform):/[^[:space:]]+\"\n  \"aim:[^[:space:]]+\\?[^[:space:]]+\"\n  \"(dab|fm):[^[:space:]]+\\.[^[:space:]]+\\.[^[:space:]]+\"\n  \"(data|geo):[^[:space:]]+,[^[:space:]]+\"\n  \"doi:10\\.[^[:space:]]+\"\n  \"(msnim|things):[^[:space:]]+\\?[^[:space:]]+\"\n  \"(feed|mvn|paparazzi|view-source):https?://[^[:space:]]+\"\n  \"git@[^[:space:]]+:[^[:space:]]+\"\n  \"gtalk:chat[^[:space:]]+\"\n  \"(im|mailto|reload|sips?|xmpp):[^[:space:]]+@[^[:space:]]+\"\n  \"jar:[^[:space:]]+!/[^[:space:]]+\"\n  \"magnet:\\?xt=urn:[^[:space:]]+\"\n  \"maps:q=[^[:space:]]+\"\n  \"(sms|tel):\\+[0-9]+\"\n  \"(jdbc|spotify|urn):[^[:space:]]+:[^[:space:]]+\"\n  \"tag:[^[:space:]]+,[^[:space:]]+:[^[:space:]]+\"\n  \"ymsgr:sendIM?[^[:space:]]+\"\n  # TODO: develop strategy to avoid matching notebook: selectors\n  # \"(apt|amss|barion|bitcoin|callto|cid|dns|drm|fax|gg):[^[:space:]]+\"\n  # \"(go|iax|javascript|message|mid|mvn|news|openpgp4fpr):[^[:space:]]+\"\n  # \"(palm|pres|proxy|psyc|query|session|shc|skype):[^[:space:]]+\"\n  # \"(stuns?|trueconf|turns?|ws|xfire):[^[:space:]]+\"\n  # \"itms:\"\n)\n\n# Fallbacks for non-unicode environments.\nif [[ ! \"${LANG:-x}\" =~ (utf-|UTF-) ]]\nthen\n  _CHEVRON_LEFT=\"<\"\n  _CHEVRON_RIGHT=\">\"\n  _MD=\"-\"\nfi\n\n# _alias_subcommand()\n#\n# Usage:\n#   _alias_subcommand <subcommand> <alias>\n#\n# Description:\n#   Create an <alias> of <subcommand>. NOTE: aliases also have to be added to\n#   the $_SUBCOMMANDS variable.\n_alias_subcommand() {\n  local _alias=\"${2:-}\"\n  local _subcommand=\"${1:-}\"\n\n  if [[ -z \"${_alias:-}\" ]]\n  then\n    return 1\n  fi\n\n  shopt -u extglob\n\n  eval \"_describe_${_alias}() { _describe_${_subcommand}  \\\"\\${@:-}\\\"; }\"\n  eval \"_${_alias}()          { _${_subcommand}           \\\"\\${@:-}\\\"; }\"\n\n  shopt -s extglob\n}\n\n# _bat()\n#\n# Usage:\n#   _bat [--command-exists] [<bat options>]\n#\n# Description:\n#   Wrapper for `bat`, aka `batcat` on debian.\n#\n# Exit / Error / Return Status (--command-exists):\n#   0 (success, true)  If a `bat` or `batcat` exacutable is found on the system.\n#   1 (error,  false)  if not.\n_BAT_COMMAND=\n_bat() {\n  if _command_exists \"batcat\"\n  then\n    _BAT_COMMAND=\"batcat\"\n  elif _command_exists \"bat\"\n  then\n    _BAT_COMMAND=\"bat\"\n  fi\n\n  if [[ \"${1:-}\" == \"--command-exists\"  ]]\n  then\n    if [[ -n \"${_BAT_COMMAND:-}\"        ]]\n    then\n      return 0\n    else\n      return 1\n    fi\n  fi\n\n  \"${_BAT_COMMAND}\" \"${@}\"\n}\n\n# _file_is_archive()\n#\n# Usage:\n#   _file_is_archive <path>\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If file is an archive.\n#   1 (error,  false)  if not.\nexport _ARCHIVE_FILE_EXTENSIONS=(\n  7z\n  apk\n  bz2\n  dmg\n  gz\n  lz\n  rar\n  s7z\n  sit\n  sitx\n  sparsebundle\n  tar\n  tgz\n  tbz2\n  tlz\n  txz\n  xz\n  zip\n  zipx\n  Z\n)\n_file_is_archive() {\n  local _file_path=\"${1:-}\"\n  local _file_type=\"${_file_path##*.}\"\n\n  LC_ALL=C _contains \"${_file_type}\" \"${_ARCHIVE_FILE_EXTENSIONS[@]}\"\n}\n\n# _file_is_audio()\n#\n# Usage:\n#   _file_is_audio (<path> | <filename>)\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If file is an audio file.\n#   1 (error,  false)  if not.\nexport _AUDIO_FILE_EXTENSIONS=(\n  aac\n  aiff\n  flac\n  m4a\n  mp3\n  ogg\n  wav\n)\n_file_is_audio() {\n  local _file_path=\"${1:-}\"\n  local _file_type=\"${_file_path##*.}\"\n\n  LC_ALL=C _contains \"${_file_type}\" \"${_AUDIO_FILE_EXTENSIONS[@]}\"\n}\n\n# _file_is_bookmark()\n#\n# Usage:\n#   _file_is_bookmark (<path> | <filename>)\n#\n# Exit / Error / Return Status:\n#   0 (success, true) If file is a bookmark.\n#   1 (error,  false) if not.\nexport _BOOKMARK_FILE_EXTENSIONS=(\n  bookmark.md\n  bookmark.md.enc\n)\n_file_is_bookmark() {\n  # Use explicit matching for legacy bookmark name support.\n  [[ \"${1:-}\" =~ ([(-|.)]bookmark.md|[(-|.)]bookmark.md.enc) ]]\n}\n\n# _file_is_document()\n#\n# Usage:\n#   _file_is_document (<path> | <filename>)\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If file is a Word, Open Office, PDF, or other document.\n#   1 (error,  false)  if not.\nexport _DOCUMENT_FILE_EXTENSIONS=(\n  doc\n  docx\n  odt\n  pdf\n  rtf\n  xls\n  xlsx\n)\n_file_is_document() {\n  local _file_path=\"${1:-}\"\n  local _file_type=\"${_file_path##*.}\"\n\n  LC_ALL=C _contains \"${_file_type}\" \"${_DOCUMENT_FILE_EXTENSIONS[@]}\"\n}\n\n# _file_is_encrypted()\n#\n# Usage:\n#   _file_is_encrypted <path>\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If file is encrypted.\n#   1 (error,  false)  if not.\nexport _ENCRYPTED_FILE_EXTENSIONS=(\n  enc\n)\n_file_is_encrypted() {\n  local _file_path=\"${1:-}\"\n  local _file_type=\"${_file_path##*.}\"\n\n  # `file` with 'soft' test is slow, so avoid calling it.\n  LC_ALL=C _contains \"${_file_type}\" \"${_ENCRYPTED_FILE_EXTENSIONS[@]}\" ||\n    {\n      ! LC_ALL=C _contains \"${_file_type}\"  \\\n        \"${_TEXT_FILE_EXTENSIONS[@]}\"       \\\n        \"${_IMAGE_FILE_EXTENSIONS[@]}\"      \\\n        \"${_DOCUMENT_FILE_EXTENSIONS[@]}\"   \\\n        \"${_AUDIO_FILE_EXTENSIONS[@]}\"      \\\n        \"${_VIDEO_FILE_EXTENSIONS[@]}\"      &&\n        if _command_exists \"file\"\n        then\n          [[ \"$(file \"${_file_path:-}\"      \\\n                  --exclude=apptype         \\\n                  --exclude=tokens          \\\n                  --exclude=cdf             \\\n                  --exclude=compress        \\\n                  --exclude=elf             \\\n                  --exclude=tar)\" =~ (encrypted|openssl) ]]\n        else\n          return 1\n        fi\n    }\n}\n\n# _file_is_image()\n#\n# Usage:\n#   _file_is_image (<path> | <filename>)\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If file is an image.\n#   1 (error,  false)  if not.\nexport _IMAGE_FILE_EXTENSIONS=(\n  afphoto\n  ai\n  bmp\n  gif\n  heic\n  ind\n  indd\n  jpg\n  jpeg\n  png\n  psd\n  raw\n  svg\n  svgz\n  tif\n  tiff\n  webp\n)\n_file_is_image() {\n  local _file_path=\"${1:-}\"\n  local _file_type=\"${_file_path##*.}\"\n\n  LC_ALL=C _contains \"${_file_type}\" \"${_IMAGE_FILE_EXTENSIONS[@]}\"\n}\n\n# _file_is_text()\n#\n# Usage:\n#   _file_is_text <path>\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If file is text.\n#   1 (error,  false)  if not.\n#\n# Resources:\n#   Markdown: https://superuser.com/a/285878\nexport _TEXT_FILE_EXTENSIONS=(\n  adoc\n  asciidoc\n  bash\n  bib\n  coffee\n  css\n  go\n  html\n  js\n  json\n  jsx\n  latex\n  markdown\n  md\n  mdown\n  mdwn\n  mdtxt\n  mdtext\n  mkd\n  mkdn\n  org\n  py\n  rb\n  Rmd\n  rst\n  scss\n  sh\n  sql\n  tex\n  text\n  textile\n  ts\n  tsx\n  txt\n  xml\n)\n_file_is_text() {\n  local _file_path=\"${1:-}\"\n  local _file_type=\"${_file_path##*.}\"\n\n  # Avoid calling `file` for better performance.\n  LC_ALL=C _contains \"${_file_type}\" \"${_TEXT_FILE_EXTENSIONS[@]}\" ||\n    {\n      ! LC_ALL=C _contains \"${_file_type}\"  \\\n        \"${_IMAGE_FILE_EXTENSIONS[@]}\"      \\\n        \"${_DOCUMENT_FILE_EXTENSIONS[@]}\"   \\\n        \"${_ENCRYPTED_FILE_EXTENSIONS[@]}\"  \\\n        \"${_AUDIO_FILE_EXTENSIONS[@]}\"      \\\n        \"${_VIDEO_FILE_EXTENSIONS[@]}\"      \\\n        \"${_ARCHIVE_FILE_EXTENSIONS[@]}\"        &&\n        [[ !    \"${_file_type}\" =~ \\.epub$  ]]  &&\n        [[ ! -d \"${_file_path:-}\"           ]]  &&\n        if _command_exists \"file\"\n        then\n          [[ \"$(file \"${_file_path:-}\"      \\\n                  --exclude=apptype         \\\n                  --exclude=tokens          \\\n                  --exclude=cdf             \\\n                  --exclude=compress        \\\n                  --exclude=elf             \\\n                  --exclude=tar             \\\n                  -b --mime-type)\" =~ ^text ]]\n        else\n          [[ -f \"${_file_path:-}\"           ]]\n        fi\n    }\n}\n\n# _file_is_todo()\n#\n# Usage:\n#   _file_is_todo (<path> | <filename>)\n#\n# Exit / Error / Return Status:\n#   0 (success, true) If file is a todo.\n#   1 (error,  false) if not.\nexport _TODO_FILE_EXTENSIONS=(\n  todo.md\n  todo.md.enc\n)\n_file_is_todo() {\n  [[ \"${1:-}\" =~ (todo\\.md|todo\\.md\\.enc) ]]\n}\n\n# _file_is_video()\n#\n# Usage:\n#   _file_is_video (<path> | <filename>)\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If file is a video file.\n#   1 (error,  false)  if not.\nexport _VIDEO_FILE_EXTENSIONS=(\n  avi\n  flv\n  m4p\n  m4v\n  mp2\n  mp4\n  mov\n  mpeg\n  mpg\n  qt\n  webm\n  wmv\n)\n_file_is_video() {\n  local _file_path=\"${1:-}\"\n  local _file_type=\"${_file_path##*.}\"\n\n  LC_ALL=C _contains \"${_file_type}\" \"${_VIDEO_FILE_EXTENSIONS[@]}\"\n}\n\n# _get_content()\n#\n# Usage:\n#   _get_content <path> [--title]\n#\n# Options:\n#   --title  Print the title or nothing if a title is not found.\n#\n# Description:\n#   Print the title or first line of the text document at <path>. When a title\n#   is not found, print the first line, prefixed with '__first_line:'.\n#\n#   Supports both Markdown h1 styles, YAML front matter, Org Mode, LaTeX,\n#   and AsciiDoc.\n#\n#   - Markdown\n#     - Supported:\n#       - # This is a Title\n#       - This is a Title\n#         ===============\n#       - ---\n#         title: This is a Title\n#         ---\n#     - https://daringfireball.net/projects/markdown/syntax#header\n#     - https://jekyllrb.com/docs/front-matter/\n#   - Org Mode\n#     - Supported:\n#       - #+TITLE: This is a Title\n#     - https://orgmode.org/guide/Export-Settings.html\n#   - LaTeX\n#     - Supported:\n#       - \\title{This is a Title}\n#   - AsciiDoc\n#     - Supported:\n#       - = This is a Title\n_get_content() {\n  local _counter=0\n  local _first_line=\n  local _in_code_block=0\n  local _in_front_matter=0\n  local _maybe_title=\n  local _path=\"${1:-}\"\n  local _title=\n\n  if [[ \"${2:-}\" == --title ]]\n  then\n    local _only_title=1\n  else\n    local _only_title=0\n  fi\n\n  # turn on case-insensitive matching\n  shopt -s nocasematch\n\n  if [[   -z \"${_path}\" ]]\n  then\n    return 1\n  elif [[ -d \"${_path}\" ]]\n  then\n    return 0\n  elif [[ -e \"${_path}\" ]]\n  then\n\n    # `awk` `_get_first_line` alternative\n    # -----------------------------------\n    #       awk -f - \"${_path}\" <<'HEREDOC'\n    # (state == 0) && /^---$/ { state=1; next }\n    # (state == 1) && /^---$/ { state=0; next }\n    # (state == 0) && /^```/  { state=1; next }\n    # (state == 1) && /^```/  { state=0; next }\n    #\n    # (state == 0) && /^./    { print; exit   }\n    # HEREDOC\n\n    if [[ \"${_path}\" =~ (\\.md$|\\.markdown$) ]]\n    then\n      local               __line=\n      while IFS= read -r  __line || [[ -n \"${__line:-}\"     ]]\n      do\n        if [[ \"${__line}\" =~ ^([[:space:]]*#[[:space:]]+)   ]] &&\n           ! ((_in_code_block))\n        then # line starts with an atx-style H1\n          _title=\"${__line#\"${BASH_REMATCH[1]:-}\"}\"\n\n          if [[ \"${_title}\" =~ ([[:space:]]+#[[:space:]]*)$ ]]\n          then\n            _title=\"${_title%\"${BASH_REMATCH[1]:-}\"}\"\n          fi\n\n          # `sed` alternative\n          # -----------------\n          # _title=\"$(\n          #   printf \"%s\\\\n\" \"${__line}\"    \\\n          #     | sed                       \\\n          #       -e 's/^[[:space:]]*# //'  \\\n          #       -e 's/ #$//'\n          #   )\"\n\n          break\n        elif [[ \"${__line}\" =~ ^---$    ]]\n        then # start or end of front matter block\n          if ((_in_front_matter))\n          then\n            _in_front_matter=0\n          else\n            _in_front_matter=1\n          fi\n        elif [[ \"${__line}\" =~ ^\\`\\`\\`  ]]\n        then # start or end of code block\n          if ((_in_code_block))\n          then\n            _in_code_block=0\n          else\n            _in_code_block=1\n          fi\n        elif ((_in_front_matter))   &&  [[ \"${__line}\" =~ ^title\\:  ]]\n        then # front matter title\n          _title=\"$(printf \"%s\\\\n\" \"${__line}\" | LC_ALL=C sed 's/^title: //')\"\n\n          break\n        elif ! ((_in_front_matter)) && ! ((_in_code_block))\n        then\n          if [[ -z \"${_maybe_title:-}\"  ]]  &&  [[ -n \"${__line:-}\" ]]\n          then  # potential setext-style H1\n            _maybe_title=\"${__line}\"\n          elif [[ -n \"${_maybe_title:-}\"            ]] &&\n               [[ \"${__line}\" =~ ^[[:space:]]*\\=+$  ]]\n          then # underline for setext-style H1 on previous line\n            _title=\"$(\n              printf \"%s\\\\n\" \"${_maybe_title}\" | LC_ALL=C sed 's/^[[:space:]]*//'\n            )\"\n\n            break\n          elif [[ -n \"${_maybe_title:-}\"        ]]\n          then # in normal content, title not found\n            if ! ((_only_title))\n            then\n              if [[ \"${#_maybe_title}\" -gt 500  ]]\n              then\n                _first_line=\"${_maybe_title:0:500}...\"\n              else\n                _first_line=\"${_maybe_title}\"\n              fi\n            fi\n\n            if [[ ! \"${_maybe_title}\"  =~ ^\\[   ]]\n            then # only break with first non-link line\n              break\n            fi\n          else\n            continue\n          fi\n        fi\n      done < \"${_path}\"\n\n      if [[ -z \"${_title:-\"${_first_line:-}\"}\"  ]] &&\n         [[ -n \"${_maybe_title:-}\"              ]]\n      then\n        _first_line=\"${_maybe_title:-}\"\n      fi\n    elif [[ \"${_path}\"    =~ (\\.latex$|\\.tex$)  ]]\n    then\n      local               __line=\n      while IFS= read -r  __line  ||  [[ -n \"${__line:-}\" ]]\n      do\n        _counter=\"$((_counter+1))\"\n\n        if [[ \"${__line}\" =~  ^\\\\title\\{        ]]\n        then\n          _title=\"$(\n            printf \"%s\\\\n\" \"${__line}\" | LC_ALL=C sed 's/\\\\title{\\(.*\\)}/\\1/'\n          )\"\n\n          break\n        elif [[ -n \"${__line:-}\"      ]]\n        then\n          if [[ -z \"${_first_line:-}\" ]]\n          then\n            _first_line=\"${__line}\"\n          fi\n\n          if [[ ! \"${__line}\" =~ ^\\\\  ]] &&\n             [[ \"${_counter}\" -gt 20  ]]\n          then\n            break\n          fi\n        else\n          continue\n        fi\n      done < \"${_path}\"\n    elif [[   \"${_path}\" =~ \\.org$    ]]\n    then\n      local               __line=\n      while IFS= read -r  __line  ||  [[ -n \"${__line}\"   ]]\n      do\n        _counter=\"$((_counter+1))\"\n\n        # NOTE: Titles can be defined with multiple #+TITLE: lines.\n        if [[ \"${__line}\" =~ ^\\#\\+TITLE\\: ]]\n        then\n          if [[ -n \"${_title:-}\"          ]]\n          then\n            _title=\"${_title} \"\n          fi\n\n          _title+=\"$(\n            printf \"%s\\\\n\" \"${__line}\"    \\\n              | LC_ALL=C sed              \\\n                  -e 's/^#+TITLE: //'     \\\n                  -e 's/^#+title: //'\n          )\"\n        elif [[ -n \"${__line:-}\"      ]]\n        then\n\n          if [[ -z \"${_first_line:-}\" ]]\n          then\n            _first_line=\"${__line}\"\n          fi\n\n          if [[ ! \"${__line}\" =~ ^\\#  ]] &&\n             [[ \"${_counter}\" -gt 10  ]]\n          then\n            break\n          fi\n        else\n          continue\n        fi\n      done < \"${_path}\"\n    elif [[ \"${_path}\"    =~ (\\.adoc$|\\.asciidoc$)  ]]\n    then\n      local               __line=\n      while IFS= read -r  __line  ||  [[ -n \"${__line:-}\" ]]\n      do\n        _counter=\"$((_counter+1))\"\n\n        if [[ \"${__line}\" =~  ^=\\     ]]\n        then\n          _title=\"${__line#= }\"\n\n          break\n        elif [[ -n \"${__line:-}\"      ]]\n        then\n          if [[ -z \"${_first_line:-}\" ]]\n          then\n            _first_line=\"${__line}\"\n          fi\n\n          if [[ ! \"${__line}\" =~ ^=\\  ]] &&\n             [[ \"${_counter}\" -gt 20  ]]\n          then\n            break\n          fi\n        else\n          continue\n        fi\n      done < \"${_path}\"\n    elif ! ((_only_title))        &&\n         LC_ALL=C _contains \"${_path##*.}\" \"${_TEXT_FILE_EXTENSIONS[@]}\"\n    then\n      local               __line=\n      while IFS= read -r  __line  ||  [[ -n \"${__line:-}\" ]]\n      do\n        if [[ -n \"${__line:-}\"        ]]\n        then\n          if [[ \"${#__line}\" -gt 500  ]]\n          then\n            _first_line=\"${__line:0:500}...\"\n          else\n            _first_line=\"${__line}\"\n          fi\n\n          break\n        fi\n      done < \"${_path}\"\n    fi\n\n    if [[ -n \"${_title:-}\"    ]]\n    then\n      printf \"%s\\\\n\" \"${_title/%$'\\r'}\"\n    elif ! ((_only_title)) && [[ -n \"${_first_line:-}\"    ]]\n    then\n      printf \"%s\\\\n\" \"__first_line:${_first_line/%$'\\r'}\"\n    fi\n\n    # turn off case-insensitive matching\n    shopt -u nocasematch\n  fi\n}\n\n# _get_id_selector()\n#\n# Usage:\n#   _get_id_selector <path> | <selector> [--notebook]\n#\n# Options:\n#   --notebook  Always include the notebook name in the output.\n#\n# Description:\n#   Convert a <path> or <selector> to valid selector constructed with ids,\n#   which are resolved first during selector resolution. This function gives\n#   precedence to folder names in input.\n_get_id_selector() {\n  local _folder_path=\n  local _id_selector=\n  local _notebook_name=\n  local _notebook_path=\n  local _relative_path=\n  local _selector=\"${1:-}\"\n  local _selector_relative_path=\n  local _trailing_slash=0\n\n  case \"${2:-}\" in\n    --notebook) local _always_include_notebook=1 ;;\n    *)          local _always_include_notebook=0 ;;\n  esac\n\n  if [[ -z \"${_selector:-}\"     ]]\n  then\n    return 0\n  fi\n\n  if [[ \"${_selector:-}\" =~ /$  ]]\n  then\n    _trailing_slash=1\n  fi\n\n  if [[ \"${_selector:-}\" =~ ^/  ]]\n  then # selector is full path\n    if [[ \"${_selector}\" =~ ^${NB_DIR}      ]]\n    then\n      local _path_with_notebook=\"${_selector#\"${NB_DIR}\"/}\"\n      _notebook_name=\"${_path_with_notebook%%/*}\"\n      _notebook_path=\"${NB_DIR}/${_notebook_name}\"\n\n      if [[ \"${_path_with_notebook:-}\" =~ / ]]\n      then\n        _selector_relative_path=\"${_path_with_notebook#*/}\"\n      fi\n    else\n      _notebook_name=\"local\"\n\n      _notebook_path=\"$(\n        cd \"${_selector%/*}\"    &&\n          __set_notebook_paths  &&\n          _notebooks current --path --no-color\n      )\"\n\n      if [[ \"${_selector:-}\" == \"${_notebook_path:-}\" ]]\n      then\n        _selector_relative_path=\n      else\n        _selector_relative_path=\"${_selector#\"${_notebook_path}\"/}\"\n      fi\n    fi\n  else\n    if [[ \"${_selector:-}\" =~ :   ]]\n    then\n      _notebook_name=\"${_selector%%:*}\"\n      _selector_relative_path=\"${_selector#*:}\"\n    else\n      _selector_relative_path=\"${_selector:-}\"\n    fi\n  fi\n\n  if [[ -z \"${_notebook_path:-}\"  ]]\n  then\n    case \"${_notebook_name:-}\" in\n      local) _notebook_path=\"$(_notebooks --local --path --no-color)\" ;;\n      *)     _notebook_path=\"${NB_DIR}/${_notebook_name}\"             ;;\n    esac\n  fi\n\n  local _parent_folder_path=\n\n  if [[ -n \"${_notebook_name:-}\"  ]]\n  then\n    _id_selector+=\"${_notebook_name}:\"\n    _parent_folder_path=\"${_notebook_path:-}\"\n  else\n    _parent_folder_path=\"$(_notebooks current --path)\"\n\n    if ((_always_include_notebook))\n    then\n      if _notebooks current --local\n      then\n        _id_selector+=\"local:\"\n      else\n        _id_selector+=\"${_parent_folder_path##*/}:\"\n      fi\n    fi\n  fi\n\n  local _id_path=\n\n  if [[ -n \"${_selector_relative_path:-}\" ]]\n  then\n    local _selector_segments=()\n\n    IFS=\"/\" read -ra _selector_segments <<< \"${_selector_relative_path:-}\"\n\n    local i=\n    for ((i=0; i < ${#_selector_segments[@]}; i++))\n    do\n      local _segment_id=\n\n      if [[ \"${i}\" -eq \"$((${#_selector_segments[@]} - 1))\" ]]\n      then # it's the last segment\n        if [[ \"${_selector_segments[i]:-}\" =~ ^[0-9]+$      ]] &&\n           ! ((_trailing_slash))\n        then\n          _segment_id=\"${_selector_segments[i]:-}\"\n        fi\n      fi\n\n      if [[ -z \"${_segment_id:-}\"         ]]\n      then\n        _segment_id=\"$(\n          _index get_id                   \\\n            \"${_selector_segments[i]:-}\"  \\\n            \"${_parent_folder_path}\"      || :\n        )\"\n      fi\n\n      local _segment_basename=\n\n      if [[ -z \"${_segment_id:-}\"                     ]] &&\n         [[ \"${_selector_segments[i]:-}\"  =~ ^[0-9]+$ ]]\n      then\n        _segment_basename=\"$(\n          _index get_basename             \\\n            \"${_selector_segments[i]:-}\"  \\\n            \"${_parent_folder_path}\" 2>/dev/null || :\n        )\"\n\n        if [[ -n \"${_segment_basename:-}\" ]]\n        then\n          _segment_id=\"${_selector_segments[i]:-}\"\n        fi\n      fi\n\n      if [[ -z \"${_segment_id:-}\" ]]\n      then\n        return 1\n      fi\n\n      if [[ -z \"${_id_path:-}\"    ]]\n      then\n        _id_path+=\"${_segment_id}\"\n      else\n        _id_path+=\"/${_segment_id}\"\n      fi\n\n      _parent_folder_path+=\"/${_segment_basename:-${_selector_segments[i]:-}}\"\n    done\n  fi\n\n  if [[ -n \"${_id_path:-}\"        ]] &&\n     [[ !  \"${_id_path}\" == \"/\"   ]]\n  then\n    _id_selector+=\"${_id_path}\"\n  fi\n\n  if ((_trailing_slash))\n  then\n    _id_selector+=\"/\"\n  fi\n\n  printf \"%s\\\\n\" \"${_id_selector:-}\"\n}\n\n# _get_last_modified_timestamp()\n#\n# Usage:\n#   _get_last_modified_timestamp <path>\n#\n# Description:\n#   Print the last modified timestamp for the file at <path>.\n_get_last_modified_timestamp() {\n  local _path=\"${1:-}\"\n  local _stat_output=\n\n  [[ -z \"${_path:-}\" ]] && return 1\n\n  if [[ -L \"${_path}\" ]]\n  then\n    _path=\"$(_resolve_symlink \"${_path}\")\"\n  fi\n\n  if ! _stat_output=\"$(\n       stat -c %Y \"${_path}\" 2>/dev/null\n     )\" # GNU\n  then\n    if ! _stat_output=\"$(\n         gstat -c %Y \"${_path}\" 2>/dev/null\n       )\" # GNU prefixed\n    then\n      _stat_output=\"$(\n        stat -f '%m' \"${_path}\"\n      )\" # BSD/macOS\n    fi\n  fi\n\n  if [[ -n \"${_stat_output:-}\" ]]\n  then\n    printf \"%s\\\\n\" \"${_stat_output}\"\n\n    return 0\n  else\n    return 1\n  fi\n}\n\n# _get_visible_length()\n#\n# Usage:\n#   _get_visible_length <string> [<extra-length>]\n#\n# Description:\n#   Calculate the apparent length of <string>, with byte and character\n#   calculations for handling unicode characters.\n#\n# More Information:\n#   https://stackoverflow.com/a/31009961\n_get_visible_length() {\n  local _extra_length=\"${2:-0}\"\n  local _string=\"${1:-}\"\n\n  _LANG=\"${LANG:-}\" _LC_ALL=\"${LC_ALL:-}\"\n\n  local _length_chars=\n  _length_chars=\"${#_string}\"\n\n  LANG=C LC_ALL=C\n\n  local _length_bytes=\n  _length_bytes=\"${#_string}\"\n\n  LANG=\"${_LANG:-}\" LC_ALL=\"${_LC_ALL:-}\"\n\n  local _difference=\n  _difference=$(((_length_bytes-_length_chars)/3))\n\n  local _calculated_length=\n  _calculated_length=$((_length_chars+_difference))\n\n  if ((_extra_length))\n  then\n    _calculated_length=$((_calculated_length+_extra_length))\n  fi\n\n  printf \"%s\\\\n\" \"${_calculated_length:-0}\"\n}\n\n# _grep_supports_color()\n#\n# Usage:\n#   _grep_supports_color\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If grep supports the --color option.\n#   1 (error,  false)  if not.\n_grep_supports_color() {\n  printf \"\\\\n\" | grep --color=never \"\" >/dev/null 2>&1\n}\n\n# _highlight_syntax_if_available()\n#\n# Usage:\n#   _highlight_syntax_if_available [<path> | <extension>]\n#\n# Description:\n#   If `bat` or Pygments is available, use it to highlight syntax. When neither\n#   is available, pipe through `cat`.\n#\n# References:\n#   https://github.com/sharkdp/bat\n#   https://pygments.org/\n_highlight_syntax_if_available() {\n  # Usage: _highlight_syntax_with_extension <extension>\n  _highlight_syntax_with_extension() {\n    ! _contains \"${1:-}\" \"db\" # TODO\n  }\n\n  local _extension=\n  local _path=\n\n  if [[ \"${1:-}\" =~ / ]]\n  then\n    _path=\"${1}\"\n  elif [[ -n \"${1:-}\" ]]\n  then\n    _extension=\"${1}\"\n  else\n    _extension=\"md\"\n  fi\n\n  if ! ((_COLOR_ENABLED))\n  then\n    if [[ -n \"${_path:-}\"   ]]\n    then\n      cat \"${_path}\"\n    else\n      cat\n    fi\n\n    return 0\n  fi\n\n  if _bat --command-exists\n  then\n    local _arguments=()\n\n    if [[ -n \"${_path:-}\"   ]]\n    then\n      _arguments+=(\"${_path}\")\n    elif _highlight_syntax_with_extension \"${_extension}\"\n    then\n      _arguments+=(\"--language\" \"${_extension}\")\n\n      if ! printf \"\" | _bat  --color     always          \\\n                            --language  \"${_extension}\" \\\n                            --paging    never           \\\n                            --plain                     \\\n                            2>/dev/null\n      then\n        cat\n\n        return 0\n      fi\n    fi\n\n    _bat \"${_arguments[@]}\"  \\\n      --color   always      \\\n      --paging  never       \\\n      --plain               \\\n      --theme \"${NB_SYNTAX_THEME:-base16}\"\n  elif hash \"highlight\" 2>/dev/null\n  then\n    local _arguments=(\"-O\" \"ansi\")\n\n    if [[ -n \"${_path:-}\"   ]]\n    then\n      _arguments+=(\"${_path}\")\n    elif _highlight_syntax_with_extension \"${_extension}\"\n    then\n      _arguments+=(\"--syntax\" \"${_extension}\")\n    fi\n\n    highlight \"${_arguments[@]}\"\n  elif ((_COLOR_ENABLED)) && hash \"pygmentize\" 2>/dev/null\n  then # pygments is installed.\n    local _arguments=(\"-O\" \"style=default\" \"-f\" \"terminal\")\n\n    if [[ -n \"${_path:-}\"   ]]\n    then\n      _arguments+=(\"${_path}\")\n    elif _highlight_syntax_with_extension \"${_extension}\"\n    then\n      _arguments+=(\"-l\" \"${_extension}\")\n    fi\n\n    pygmentize \"${_arguments[@]}\" 2>/dev/null\n  else\n    if [[ -n \"${_path:-}\"   ]]\n    then\n      cat \"${_path}\"\n    else\n      cat\n    fi\n  fi\n}\n\n# _join()\n#\n# Usage:\n#   _join <delimiter> <list-item>...\n#\n# Description:\n#   Print a string containing all <list-item> arguments separated by\n#   <delimiter>.\n#\n# Example:\n#   _join \"${_delimeter}\" \"${_list[@]}\"\n#\n# More Information:\n#   https://stackoverflow.com/a/17841619\n_join() {\n  local _delimiter=\"${1:-}\"\n\n  shift\n\n  local _joined_string=\"${1:-}\"\n\n  shift\n\n  local __element=\n  for   __element in \"${@:-}\"\n  do\n    [[ -n \"${__element:-}\" ]] || continue\n\n    _joined_string+=\"${_delimiter:-}${__element:-}\"\n  done\n\n  printf \"%s\\\\n\" \"${_joined_string}\"\n}\n\n# _less_prompt()\n#\n# Usage:\n#   _less_prompt\n#\n# Description:\n#   The prompt to display in `less`.\n_less_prompt() {\n  # TODO: remove when less 668 or higher is widely available\n  local _less_version=\n  _less_version=\"$(less --version | head -1)\"\n  _less_version=\"${_less_version#* }\"\n  _less_version=\"${_less_version%% *}\"\n  _less_version=\"${_less_version%%.*}\"\n\n  local _prompt=\"\\\n> scroll for more, h for help, or q to quit\"\n\n  if [[ \"${_COLUMNS}\" -gt 81 ]]\n  then\n    # TODO: remove when less 668 or higher is widely available\n    if [[ \"${_less_version:-}\" -gt \"653\" ]] &&\n       [[ \"${_less_version:-}\" -lt \"668\" ]]\n    then # render prompt without multibyte characters\n      _prompt=\"\\\n> scroll for more, f / b to jump forward / back, h for help, or q to quit\"\n    else\n      _prompt=\"\\\n> scroll for more, f / b to jump ↓ / ↑, h for help, or q to quit\"\n    fi\n  fi\n\n  printf \"%s\\\\n\" \"${_prompt}\"\n}\n\n# _list_files()\n#\n# Usage:\n#   _list_files <path> [--reverse] [--sort] [--standard-input] [--type <type>]\n#\n# Description:\n#   List files in the current notebook or filenames from standard input.\n_list_files() {\n  local _path=\n  local _read_from_standard_input=0\n  local _reverse=0\n  local _sort=0\n  local _type=\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      --reverse)\n        _reverse=1\n        ;;\n      --sort)\n        _sort=1\n        ;;\n      --standard-input)\n        _read_from_standard_input=1\n        ;;\n      --type)\n        if _option_value_is_present \"${2:-}\"\n        then\n          _type=\"${2}\"\n\n          shift\n        fi\n        ;;\n      --[A-Za-z]*)\n        _type=\"${1:2}\"\n        ;;\n      [^-]*)\n        if [[ -z \"${_path:-}\" ]] && [[ \"${1:-}\" =~ ^/ ]]\n        then\n          _path=\"${1}\"\n        fi\n    esac\n\n    shift\n  done\n\n  if [[ -z \"${_path:-}\"   ]]\n  then\n    _path=\"$(_notebooks current --path)\"\n  fi\n\n  if ((_read_from_standard_input)) && _piped_input\n  then\n    cat\n  elif ((_sort))\n  then\n    cat \"${_path}/.index\"\n  else\n    ls -t -1 \"${_path}\"\n  fi | {\n    if ((_reverse))\n    then\n      # https://stackoverflow.com/a/744093\n      LC_ALL=C sed '1!G;h;$!d'\n    else\n      cat\n    fi\n  } | {\n    if [[ -n \"${_type:-}\" ]]\n    then\n      local __extension=\n      local _grep_patterns=()\n\n      case \"${_type}\" in\n        bookmark|bookmarks)\n          grep                  \\\n            -e '\\.bookmark\\.'   \\\n            -e '\\-bookmark\\.'\n          ;;\n        book|books)\n          grep -e 'epub$'\n          ;;\n        note|notes)\n          for __extension in \"${_TEXT_FILE_EXTENSIONS[@]}\"\n          do\n            _grep_patterns+=(\"-e\" \"${__extension}$\")\n          done\n\n          grep \"${_grep_patterns[@]}\" \\\n            | grep -v                 \\\n                -e '\\.bookmark\\.'     \\\n                -e '\\-bookmark\\.'\n          ;;\n        folder|folders|directory|directories)\n          local         __line=\n          while read -r __line\n          do\n            if [[ -d \"${_path}/${__line}\" ]]\n            then\n              printf \"%s\\\\n\" \"${__line}\"\n            fi\n          done\n          ;;\n        archive)\n          for __extension in \"${_ARCHIVE_FILE_EXTENSIONS[@]}\"\n          do\n            _grep_patterns+=(\"-e\" \"${__extension}$\" \"-e\" \"${__extension}.enc$\")\n          done\n\n          grep \"${_grep_patterns[@]}\"\n          ;;\n        audio|music)\n          for __extension in \"${_AUDIO_FILE_EXTENSIONS[@]}\"\n          do\n            _grep_patterns+=(\"-e\" \"${__extension}$\" \"-e\" \"${__extension}.enc$\")\n          done\n\n          grep \"${_grep_patterns[@]}\"\n          ;;\n        document|documents|doc|docs)\n          for __extension in \"${_DOCUMENT_FILE_EXTENSIONS[@]}\"\n          do\n            _grep_patterns+=(\"-e\" \"\\.${__extension}$\" \"-e\" \"\\.${__extension}\\.enc$\")\n          done\n\n          grep \"${_grep_patterns[@]}\"\n          ;;\n        encrypted)\n          for __extension in \"${_ENCRYPTED_FILE_EXTENSIONS[@]}\"\n          do\n            _grep_patterns+=(\"-e\" \"\\.${__extension}$\")\n          done\n\n          grep \"${_grep_patterns[@]}\"\n          ;;\n        image|images|picture|pictures)\n          for __extension in \"${_IMAGE_FILE_EXTENSIONS[@]}\"\n          do\n            _grep_patterns+=(\"-e\" \"\\.${__extension}$\" \"-e\" \"\\.${__extension}\\.enc$\")\n          done\n\n          grep \"${_grep_patterns[@]}\"\n          ;;\n        text|txt)\n          for __extension in \"${_TEXT_FILE_EXTENSIONS[@]}\"\n          do\n            _grep_patterns+=(\"-e\" \"\\.${__extension}$\")\n          done\n\n          grep \"${_grep_patterns[@]}\"\n          ;;\n        todo|todos)\n          for __extension in \"${_TODO_FILE_EXTENSIONS[@]}\"\n          do\n            _grep_patterns+=(\"-e\" \"\\.${__extension}$\")\n          done\n\n          grep \"${_grep_patterns[@]}\"\n          ;;\n        video|videos)\n          for __extension in \"${_VIDEO_FILE_EXTENSIONS[@]}\"\n          do\n            _grep_patterns+=(\"-e\" \"\\.${__extension}$\" \"-e\" \"\\.${__extension}\\.enc$\")\n          done\n\n          grep \"${_grep_patterns[@]}\"\n          ;;\n        *)\n          grep -e \"\\.${_type}$\"\n          ;;\n      esac\n    else\n      cat\n    fi\n  }\n}\n\n# _open_in_gui_app()\n#\n# Usage:\n#   _open_in_gui_app <url> | <path>\n#\n# Description:\n#   Open <url> or <path> in the system GUI web browser or application for the\n#   given file type.\n_open_in_gui_app() {\n  local _target=\"${1:-}\"\n\n  [[ -n \"${_target:-}\" ]] || return 1\n\n  if [[ -n \"${NB_GUI_BROWSER:-}\" ]] &&\n     _string_is_url \"${_target:-}\"\n  then\n    if [[ \"${OSTYPE}\" =~ cygwin|msys|win32    ]]\n    then\n      start \"${NB_GUI_BROWSER:-}\" \"${_target}\"\n    else\n      local _gui_browser_command=(\"${NB_GUI_BROWSER:-}\")\n\n      if _command_exists \"${_gui_browser_command[0]:-}\" ||\n         [[ -f \"${_gui_browser_command[0]:-}\" ]]\n      then\n        \"${_gui_browser_command[@]:-}\" \"${_target:-}\" 2>/dev/null &\n      fi\n    fi\n  elif _command_exists \"wslview\"\n  then\n    wslview \"${_target}\"\n  elif _command_exists \"xdg-open\"\n  then\n    xdg-open \"${_target}\"\n  elif _command_exists \"open\"\n  then\n    open \"${_target}\"\n  elif [[ \"${OSTYPE}\" =~ cygwin|msys|win32    ]]\n  then # https://stackoverflow.com/q/3739327\n    rundll32 url.dll,FileProtocolHandler \"${_target}\"\n  else\n    return 1\n  fi\n}\n\n# _pager()\n#\n# Usage:\n#   _pager\n#\n# Description:\n#   Display standard input in the preferred pager, `less`, `bat`, or `cat`.\n_pager() {\n  local _less_options=()\n  _less_options=(-R --CLEAR-SCREEN --prompt=\"$(_less_prompt)\" --mouse)\n\n  if [[ -n  \"${PAGER:-}\"          ]]\n  then\n    local _pager_command=()\n    IFS=\" \" read -r -a _pager_command <<< \"${PAGER:-}\"\n\n    if [[   \"${PAGER:-}\" =~ less  ]]\n    then\n      \"${_pager_command[@]:-less}\" \"${_less_options[@]:-}\"\n    else\n      \"${_pager_command[@]:-cat}\"\n    fi\n  elif _command_exists \"less\"\n  then\n    less \"${_less_options[@]:-}\"\n  elif _bat --command-exists\n  then\n    _bat --style numbers,grid\n  else\n    cat\n  fi\n}\n\n# _pandoc()\n#\n# Usage:\n#   _pandoc [--standard-input | <path>] [<pandoc-options>]\n#\n# Description:\n#   Interact with pandoc, using iconv when available.\n_pandoc() {\n  if ! _command_exists \"pandoc\"\n  then\n    _warn printf \"%spandoc%s not found.\\\\n\" \"${_BT}\" \"${_BT}\"\n\n    return 1\n  fi\n\n  local _pandoc_arguments=()\n  local _path=\n  local _read_from_standard_input=0\n\n  case \"${1:-}\" in\n    --standard-input)\n      _read_from_standard_input=1\n      ;;\n    -*)\n      _pandoc_arguments+=(\"${1:-}\")\n      ;;\n    *)\n      _path=\"${1:-}\"\n      ;;\n  esac\n\n  shift\n\n  [[ -n \"${1:-}\" ]] && _pandoc_arguments+=(\"${@}\")\n\n  if [[ -n \"${_path:-}\" ]]\n  then\n    cd \"${_path%/*}\"\n  fi\n\n  if _command_exists \"iconv\"          &&  {\n       ((_read_from_standard_input))  ||  _file_is_text \"${_path:-}\"\n     }\n  then\n    {\n      if ((_read_from_standard_input))\n      then\n        iconv -c -t utf-8\n      else\n        iconv -c -t utf-8 \"${_path}\"\n      fi\n    } | {\n      if [[ -n \"${_pandoc_arguments[*]:-}\"  ]]\n      then\n        pandoc \"${_pandoc_arguments[@]:-}\" --wrap=preserve\n      else\n        pandoc --wrap=preserve\n      fi\n    } | {\n      iconv -f utf-8\n    }\n  else\n    if ! ((_read_from_standard_input))\n    then\n      _pandoc_arguments=(\"${_path}\" \"${_pandoc_arguments[@]:-}\")\n    fi\n\n    if [[ -n \"${_pandoc_arguments[*]:-}\"    ]]\n    then\n      pandoc \"${_pandoc_arguments[@]:-}\"\n    else\n      pandoc\n    fi\n  fi\n}\n\n# _piped_input()\n#\n# Usage:\n#   _piped_input\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If piped input is present.\n#   1 (error,  false)  If the current input is interactive (eg, a shell).\n_piped_input() {\n  [[ ! -t 0 ]]\n}\n\n# _print_line()\n#\n# Usage:\n#   _print_line <text> [--muted] [--no-wrap] [--visible-length [<extra-length>]\n#\n# Description:\n#   Print a line of dashes the length of <text>.\n#\n# More Information:\n#   https://wiki.bash-hackers.org/commands/builtin/printf\n_print_line() {\n  local _extra_length=0\n  local _muted=0\n  local _text=\n  local _visible_length=0\n  local _wrap_line=1\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      --muted*) _muted=1              ;;\n      --no*w*)  _wrap_line=0          ;;\n      --vis*)   _visible_length=1     ;;\n      *)\n        case \"${_text:-}\" in\n          '') _text=\"${1:-}\"          ;;\n          *)  _extra_length=\"${1:-}\"  ;;\n        esac\n        ;;\n    esac\n\n    shift\n  done\n\n  local _text_length=\n\n  if ((_visible_length))\n  then\n    _text_length=\"$(\n      _get_visible_length \"${_text:-}\" \"${_extra_length:-0}\"\n    )\"\n  else\n    _text_length=\"${#_text}\"\n  fi\n\n  local _full_width_line=0\n\n  if ! ((_wrap_line)) && {\n       [[ -z \"${_text_length:-}\"                    ]] ||\n       [[    \"${_text_length:-}\" -gt \"${_COLUMNS}\"  ]]\n     }\n  then\n    _full_width_line=1\n  fi\n\n  local _line=\n\n  if ((_full_width_line))\n  then\n    printf -v _line \"%*s\" \"${_COLUMNS}\" \"\"\n  else\n    printf -v _line \"%*s\" \"${_text_length}\" \"\"\n  fi\n\n  if ((_muted))\n  then\n    _color_muted \"${_line// /-}\"\n  else\n    _color_secondary \"${_line// /-}\"\n  fi |  if ((_full_width_line))\n        then\n          tr -d '\\n'\n        else\n          cat\n        fi\n}\n\n# _print_padding()\n#\n# Usage:\n#   _print_padding <line> <columns> [<aligned>]\n#\n# Description:\n#   Print a string of spaces that can be used as left padding to\n#   center-align <line>. <aligned> is an optional boolean that can\n#   be used to print no padding, returning an empty string.\n_print_padding() {\n  local _padding_centered=\"${3:-1}\"\n  local _padding_columns=\"${2:-}\"\n  local _padding_line=\"${1:-}\"\n\n  local _padding_line_length=\"${#_padding_line}\"\n\n  local _padding_amount=$(( (_padding_columns-_padding_line_length) / 2 ))\n\n  if ((_padding_centered)) && ((_padding_amount))\n  then\n    printf \"%-${_padding_amount}s\" \" \"\n  fi\n}\n\n# _print_welcome()\n#\n# Usage:\n#   _print_welcome\n#\n# Description:\n#   Print the welcome message.\n_print_welcome() {\n  local _padding=\n  _padding=\"$(_print_padding \" / / | | | | |_) |\" \"${_COLUMNS}\")\"\n\n  _print_line \"$(printf \"%-${_COLUMNS}s\" '.')\"\n\n  cat <<HEREDOC\n${_padding}$(_color_primary \"Welcome\") to\n${_padding}__          _\n${_padding}\\ \\   _ __ | |__\n${_padding} \\ \\ | '_ \\| '_ \\\\\n${_padding} / / | | | | |_) |\n${_padding}/_/  |_| |_|_.__/\nHEREDOC\n\n  _print_line \"$(printf \"%-${_COLUMNS}s\" '.')\"\n}\n\n# _selector_get_identifier()\n#\n# Usage:\n#   _selector_get_identifier <selector>\n#\n# Description:\n#   Print the identifier (non-notebook) portion of a selector.\n_selector_get_identifier() {\n  local _selector=\"${1:-}\"\n\n  if [[   \"${_selector:-}\" =~ :     ]] &&\n     [[ ! \"${_selector:-}\" =~ /.*:  ]]\n  then\n    printf \"%s\\\\n\" \"${_selector#*:}\" # strip notebook name\n  else\n    printf \"%s\\\\n\" \"${_selector:-}\"\n  fi\n}\n\n# _selector_resolve_folders()\n#\n# Usage:\n#   _selector_resolve_folders <selector> [<notebook-path>] [--build]\n#\n# Options:\n#   --build  Build a new path that includes segments that don't exist yet.\n#\n# Description:\n#   Resolve a selector path, which can be a mix of folder names and ids.\n_selector_resolve_folders() {\n  local _build_path=0\n  local _folder_relative_path=\n  local _notebook_path=\n  local _selector=\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      --build)\n        _build_path=1\n        ;;\n      *)\n        if [[ -z \"${_selector:-}\"   ]]\n        then\n          _selector=\"${__arg}\"\n        else\n          _notebook_path=\"${__arg}\"\n        fi\n        ;;\n    esac\n  done\n\n  local _selector_path=\"${_selector#*:}\"\n\n  if [[ \"${_selector}\" =~ :         ]]\n  then\n    local _selector_notebook_path=\n    _selector_notebook_path=\"$(\n      _notebooks show \"${_selector%%:*}\" --path 2>/dev/null || :\n    )\"\n\n    if [[ -n \"${_selector_notebook_path:-}\"     ]]\n    then\n      _notebook_path=\"${_selector_notebook_path}\"\n    fi\n  fi\n\n  if [[ -z \"${_notebook_path:-}\"    ]]\n  then\n    _notebook_path=\"$(_notebooks current --path)\"\n  fi\n\n  if [[ \"${_selector_path}\" =~ ^/   ]]\n  then\n    _selector_path=\"${_selector_path#\"${_notebook_path}\"/}\"\n  fi\n\n  if [[ ! \"${_selector_path}\"  =~ / ]]\n  then\n    if ((_build_path))\n    then\n      _build_path=0\n      _selector_path=\"${_selector_path}/\"\n    else\n      return 0\n    fi\n  fi\n\n  while [[ \"${_selector_path}\" =~ / ]]\n  do\n    local _folder_name=\n    local _parent_folder_path=\n    local _selector_segment=\"${_selector_path%%\\/*}\"\n\n    if [[ -z \"${_folder_relative_path:-}\"       ]]\n    then\n      _parent_folder_path=\"${_notebook_path}\"\n    else\n      _parent_folder_path=\"${_notebook_path}/${_folder_relative_path}\"\n    fi\n\n    if [[ -n \"${_selector_segment:-}\"           ]]\n    then\n      if [[ \"${_selector_segment}\" =~ ^[0-9]+$  ]]\n      then # folder name might be an id\n        _folder_name=\"$(\n          _index get_basename \"${_selector_segment:?}\" \"${_parent_folder_path:?}\" ||\n            printf \"%s\\\\n\" \"${_selector_segment:?}\"\n        )\"\n      fi\n\n      if [[ -z \"${_folder_name:-}\"              ]]\n      then\n        _folder_name=\"${_selector_segment}\"\n      fi\n\n      if [[ -d \"${_parent_folder_path:?}/${_folder_name:?}\" ]] ||\n         ((_build_path))\n      then\n        if [[ -z \"${_folder_relative_path:-}\"   ]]\n        then\n          _folder_relative_path=\"${_folder_name}\"\n        else\n          _folder_relative_path+=\"/${_folder_name}\"\n        fi\n\n        _selector_path=\"${_selector_path#*/}\"\n\n        continue\n      fi\n    fi\n\n    return 1\n  done\n\n  printf \"%s\\\\n\" \"${_folder_relative_path:-}\"\n}\n\n# _selector_resolve_path()\n#\n# Usage:\n#   _selector_resolve_path <selector> [<notebook-path>] [--full | --relative]\n#                          [--skip-titles]\n#\n# Options:\n#   --full  Print the full path.\n#\n# Description:\n#   Determine relative path of the file that is identified by the given <id>,\n#   <filename>, <path>, or <title> and is in the current notebook or a\n#   notebook specified with a colon prefix.\n#\n#   Examples:\n#     1\n#     example.md\n#     title\n#     relative/path/to/example.md\n#     /path/to/example.md\n#     notebook:1\n#     notebook:example.md\n#     notebook:title\n#     notebook:relative/path/to/example.md\n#     notebook:/path/to/example.md\n_selector_resolve_path() {\n  local _identifier=\n  local _notebook_path=\n  local _print_full_path=0\n  local _relative_path=\n  local _selector=\n  local _skip_titles=0\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg:-}\" in\n      --full)\n        _print_full_path=1\n        ;;\n      --skip-titles)\n        _skip_titles=1\n        ;;\n      [^-]*)\n        if [[ -z \"${_selector:-}\"   ]]\n        then\n          _selector=\"${__arg%/}\" # strip trailing /\n        else\n          _notebook_path=\"${__arg:-}\"\n        fi\n        ;;\n    esac\n  done\n\n  if [[ -n \"${_selector}\"           ]]\n  then\n    if [[ -z \"${_notebook_path:-}\"  ]] &&\n       [[ \"${_selector}\" =~ (:|^/)  ]]\n    then\n      _notebook_path=\"$(\n        _notebooks show \"${_selector}\" --path 2>/dev/null || :\n      )\"\n    fi\n\n    if [[ -z \"${_notebook_path:-}\"  ]]\n    then\n      _notebook_path=\"$(\n        _notebooks current --path 2>/dev/null || :\n      )\"\n    fi\n\n    _identifier=\"$(_selector_get_identifier \"${_selector}\")\"\n    _identifier=\"${_identifier%/}\" # strip trailing /\n\n    if [[ -e \"${_identifier}\"                     ]] &&\n       [[ \"${_identifier}\" =~ ^${_notebook_path}  ]]\n    then # <selector> is a full path in the current notebook\n      _relative_path=\"${_identifier/${_notebook_path}}\"\n      _relative_path=\"${_relative_path#\\/}\"\n    elif [[ \"${_identifier}\" =~ ^/  ]] &&\n         [[ -e \"${_identifier:-}\"   ]]\n    then # <selector> is a full path in a different notebook\n      _notebook_path=\"$(\n        _notebooks show \"${_identifier}\" --path 2>/dev/null\n      )\"\n\n      _relative_path=\"${_identifier/\"${_notebook_path}\"\\//}\"\n    elif [[ -e  \"${_notebook_path}/${_identifier}\"  ]] &&\n         [[ !   \"${_identifier}\" =~ ^[0-9]+$        ]]\n    then # <selector> is a relative path with a non-numeric filename\n      _relative_path=\"${_identifier}\"\n    else\n      local _folder_path=\"${_notebook_path}\"\n      local _folder_relative_path=\n      _folder_relative_path=\"$(\n        _selector_resolve_folders \"${_selector}\" \"${_notebook_path}\"\n      )\" || return 0\n\n      if [[ -n \"${_folder_relative_path:-}\"     ]]\n      then\n        _folder_path=\"${_notebook_path}/${_folder_relative_path}\"\n      fi\n\n      _identifier=\"${_identifier##*/}\"\n\n      if [[ -e \"${_folder_path}/${_identifier}\" ]] &&\n         [[ !  \"${_identifier}\" =~ ^[0-9]+$     ]]\n      then # <selector> is relative path with a non-numeric filename\n        _relative_path=\"${_folder_relative_path}/${_identifier}\"\n      elif [[ \"${_identifier}\" =~ ^[0-9]+$      ]]\n      then # <selector> is an id\n        local _basename=\n        _basename=\"$(_index get_basename \"${_identifier}\" \"${_folder_path}\")\"\n\n        if [[ -n \"${_basename:-}\"                     ]]\n        then\n          if [[ -n \"${_folder_relative_path:-}\"       ]]\n          then\n            _relative_path=\"${_folder_relative_path}/${_basename}\"\n          else\n            _relative_path=\"${_basename}\"\n          fi\n        elif [[ -e \"${_notebook_path}/${_identifier}\" ]]\n        then # <selector> is a relative path with numeric filename\n          _relative_path=\"${_identifier}\"\n        fi\n      elif ! ((_skip_titles))\n      then # <selector> might be a title\n        local _maybe_title=\"${_identifier##*\\/}\"\n\n        _relative_path=\"$(\n          {\n            _list_files \"${_folder_path}\"\n          } | {\n            local         __filename=\n            while read -r __filename || [[ -n \"${__filename:-}\" ]]\n            do\n              local _title=\n              _title=\"$(\n                _get_content \"${_folder_path}/${__filename}\" --title\n              )\"\n\n              if [[ -n \"${_title}\"                              ]] &&\n                 {\n                   [[ \"${_title}\" == \"${_maybe_title}\"          ]] ||\n                   {\n                     [[ \"${__filename}\"   =~ todo\\.md$          ]] &&\n                     [[ \"${_maybe_title}\" == \"${_title##*] }\"   ]]\n                   }\n                 }\n              then\n                local _full_path=\"${_folder_path}/${__filename}\"\n\n                printf \"%s\\\\n\" \"${_full_path/\"${_notebook_path}\"\\//}\"\n\n                break\n              fi\n            done\n          }\n        )\"\n      fi\n    fi\n  fi\n\n  if [[ -n \"${_identifier:-}\" ]] && [[ -z \"${_relative_path:-}\" ]]\n  then\n    return 0\n  elif ((_print_full_path))\n  then\n    printf \"%s\\\\n\" \"$(_join \"/\" \"${_notebook_path}\" \"${_relative_path:-}\")\"\n  else\n    printf \"%s\\\\n\" \"${_relative_path:-}\"\n  fi\n}\n\n# _spinner()\n#\n# Usage:\n#   _spinner <pid>\n#\n# Description:\n#   Display an ascii spinner while <pid> is running.\n#\n# Example Usage:\n#   ```\n#   _spinner_example() {\n#     printf \"Working...\"\n#     (sleep 1) &\n#     _spinner $!\n#     printf \"Done!\\\\n\"\n#   }\n#   (_spinner_example)\n#   ```\n#\n# More Information:\n#   http://fitnr.com/showing-a-bash-spinner.html\n_spinner() {\n  local _delay=0.1\n  local _pid=\"${1:-}\"\n  local _spin_string=\"|/-\\\\\"\n\n  if [[ -z \"${_pid:-}\" ]]\n  then\n    _exit_1 printf \"Usage: _spinner <pid>\\\\n\"\n  fi\n\n  while ps a | awk '{print $1}' | grep -q \"${_pid}\"\n  do\n    local _temp=\"${_spin_string#?}\"\n\n    if ((_COLOR_ENABLED))\n    then\n      printf \" %s%s[%s%c%s]%s\"    \\\n        \"${_TPUT_SGR0}\"           \\\n        \"${_TPUT_SETAF_8}\"        \\\n        \"${_TPUT_COLOR_PRIMARY}\"  \\\n        \"${_spin_string}\"         \\\n        \"${_TPUT_SETAF_8}\"        \\\n        \"${_TPUT_SGR0}\"\n\n      printf \"\\b\\b\\b\\b\"\n    fi\n\n    sleep ${_delay}\n\n    _spin_string=\"${_temp}${_spin_string%\"${_temp}\"}\"\n  done\n\n  return 0\n}\n\n# _string_is_email()\n#\n# Usage:\n#   _string_is_email <string>\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If the string is recognized as an email address.\n#   1 (error,  false)  if not.\n_string_is_email() {\n  [[ \"${1:-}\" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]+$ ]]\n}\n\n# _string_is_url()\n#\n# Usage:\n#   _string_is_url <string>\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If the string is a recognized URL.\n#   1 (error,  false)  if not.\n_string_is_url() {\n  [[ -z \"${1:-}\" ]] && return 1\n\n  local _url_match_patterns=()\n\n  local __url_match_pattern=\n  for   __url_match_pattern in \"${_URL_PATTERNS[@]}\"\n  do\n    _url_match_patterns+=(-e \"^${__url_match_pattern}$\")\n  done\n\n  printf \"%s\\\\n\" \"${1:-}\" | grep -E -q \"${_url_match_patterns[@]:-}\" &>/dev/null\n}\n\n# _wrap()\n#\n# Usage:\n#   _wrap [on | off]\n#\n# Description:\n#   Turn on line wrapping / automatic margins.\n_wrap() {\n  if [[ \"${1:-}\" == \"off\"  ]]\n  then\n    # NOTE: `tput` vs escape sequence:\n    # https://unix.stackexchange.com/a/558771\n    # https://unix.stackexchange.com/a/515938\n    # https://superuser.com/a/189068\n\n    # tput rmam\n    printf '\\033[?7l'\n  elif [[ \"${1:-}\" == \"on\" ]]\n  then\n    # tput smam\n    printf '\\033[?7h'\n  fi\n}\n\n###############################################################################\n# describe\n###############################################################################\n\n# describe()\n#\n# Usage:\n#   describe <name> <description>\n#   describe --get <name>\n#\n# Options:\n#   --get  Print the description for <name> if one has been set.\n#\n# Examples:\n# ```\n#   describe \"list\" <<HEREDOC\n# Usage:\n#   ${_ME} list\n#\n# Description:\n#   List items.\n# HEREDOC\n#\n# describe --get \"list\"\n# ```\n#\n# Set or print a description for a specified command or function <name>. The\n# <description> text can be passed as the second argument or as standard input.\n#\n# To make the <description> text available to other functions, `describe()`\n# assigns the text to a variable with the format `$____DESCRIBE_<name>`.\n#\n# When the `--get` option is used, the description for <name> is printed, if\n# one has been set.\ndescribe() {\n  set +e\n  [[ -z \"${1:-}\"          ]] &&\n    _exit_1 printf \"describe(): <name> required.\\\\n\"\n\n  if [[ \"${1}\" == \"--get\" ]]\n  then # get ------------------------------------------------------------------\n    [[ -z \"${2:-}\"        ]] &&\n      _exit_1 printf \"describe(): <description> required.\\\\n\"\n\n    local _name=\"${2:-}\"\n    local _describe_var=\"____DESCRIBE_${_name//-/_}\"\n\n    if [[ !   \"${_name}\" =~ ^\\-               ]] &&\n       [[     \"${_name}\" =~ ^[A-Za-z0-9_-]+$  ]] &&\n       [[ -n  \"${!_describe_var:-}\"           ]]\n    then\n      printf \"%s\\\\n\" \"${!_describe_var}\"\n    elif _command_exists \"_describe_${_name:-}\"\n    then\n      \"_describe_${_name:-}\"\n    else\n      printf \"No additional information for \\`%s\\`\\\\n\" \"${_name}\"\n    fi\n  else # set ------------------------------------------------------------------\n    if [[ -n \"${2:-}\"     ]]\n    then # argument is present\n      read -r -d '' \"____DESCRIBE_${1//-/_}\" <<HEREDOC\n${2}\nHEREDOC\n\n      eval \"_describe_${1}() { printf \\\"%s\\\\n\\\" \\\"${2:-}\\\"; }\"\n    else # no argument is present, so assume piped input\n      local _describe_var=\"____DESCRIBE_${1//-/_}\"\n\n      read -r -d '' \"${_describe_var}\"\n\n      eval \"_describe_${1}() { printf \\\"%s\\\\n\\\" \\\"${!_describe_var:-}\\\"; }\"\n    fi\n  fi\n  set -e\n}\n\n# Support legacy `desc` name.\ndesc() { describe \"${@}\"; }\n\n###############################################################################\n# Subcommands: Group 1                                     Subcommands: Group 1\n# --------------------                                     --------------------\n#\n# `ls` and dependencies.\n###############################################################################\n# --------------------------------------------------------------------------- #\n\n# count · ############################################################# · count\n\n_describe_count() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} count [<notebook>:][<folder-path>/]\n\n$(_color_primary \"Description\"):\n  Print the number of items in the first level of the current notebook,\n  <notebook>, or the folder at <folder-path>.\nHEREDOC\n}\n_count() {\n  local _list_files_options=()\n  local _selector=\n  local _skip_unmatched_selector=0\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      --skip-unmatched-selector)\n        _skip_unmatched_selector=1\n        ;;\n      --type)\n        _list_files_options+=(\"${1}\")\n        _list_files_options+=(_option_get_value \"${1}\" \"${2:-}\")\n\n        shift\n        ;;\n      -*|/*)\n        _list_files_options+=(\"${1}\")\n        ;;\n      *)\n        _selector=\"${1}\"\n        ;;\n    esac\n\n    shift\n  done\n\n  if [[ -n \"${_selector:-}\"         ]]\n  then\n    local _selector_path=\n    _selector_path=\"$(_selector_resolve_path \"${_selector}\" --full)\"\n\n    if [[ -z \"${_selector_path:-}\"  ]]\n    then\n      if ! ((_skip_unmatched_selector))\n      then\n        _warn printf \"Not found: %s\\\\n\" \"$(_color_primary \"${_selector:-}\")\"\n\n        return 1\n      fi\n    else\n      _list_files_options+=(\"${_selector_path:-}\")\n    fi\n  fi\n\n  _list_files \"${_list_files_options[@]:-}\" | wc -l | tr -d ' '\n}\n\n# git · ################################################################# · git\n\n_describe_git() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} git [checkpoint [<message>] | dirty]\n  ${_ME} git <git-options>...\n\n$(_color_primary \"Subcommands\"):\n  checkpoint    Create a new git commit in the current notebook and sync with\n                the remote if \\`${_ME} set auto_sync\\` is enabled.\n  dirty         0 (success, true) if there are uncommitted changes in the\n                current notebook. 1 (error, false) if the notebook is clean.\n\n$(_color_primary \"Description\"):\n  Run \\`git\\` commands within the current notebook directory.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-git-sync\n  ${_README_URL}#-revision-history\n\n$(_color_primary \"See Also\"):\n  ${_ME} help history\n  ${_ME} help remote\n  ${_ME} help run\n  ${_ME} help status\n  ${_ME} help sync\n\n$(_color_primary \"Examples\"):\n  ${_ME} git status\n  ${_ME} git diff\n  ${_ME} git log\n  ${_ME} example:git status\nHEREDOC\n}\n_git() {\n  # _git_autosyncable()\n  #\n  # Usage:\n  #   _git_autosyncable [<notebook-path>]\n  #\n  # Exit / Error / Return Status:\n  #   0 (success, true)  If autosync should trigger.\n  #   1 (error,  false)  If autosync should not trigger.\n  _git_autosyncable() {\n    ((_GIT_ENABLED)) || return 1\n\n    local _last_fetch_timestamp=\n    local _notebook_path=\"${1:-}\"\n\n    if [[ -z \"${_notebook_path}\" ]]\n    then\n      _notebook_path=\"$(_notebooks current --path)\"\n    fi\n\n    if ! ((NB_AUTO_SYNC))\n    then # autosync not enabled.\n      return 1\n    fi\n\n    if ! git -C \"${_notebook_path}\" config --get remote.origin.url &>/dev/null\n    then # there is no remote configured.\n      return 1\n    fi\n\n    if [[ ! -e \"${_notebook_path}/.git/FETCH_HEAD\" ]]\n    then # no previous fetches, but has an origin and autosync is enabled.\n      return 0\n    fi\n\n    if [[ -s \"${_notebook_path}/.git/nb/last_sync_state_checked\" ]]\n    then\n      _last_fetch_timestamp=\"$(\n        cat \"${_notebook_path}/.git/nb/last_sync_state_checked\" 2>/dev/null\n      )\"\n    fi\n\n    if [[ -z \"${_last_fetch_timestamp:-}\" ]]\n    then\n      _last_fetch_timestamp=\"$(\n        _get_last_modified_timestamp \"${_notebook_path}/.git/FETCH_HEAD\"\n      )\"\n    fi\n\n    local _current_timestamp=\n    _current_timestamp=\"$(date +%s)\"\n\n    local _diff=\n    _diff=$((_current_timestamp-_last_fetch_timestamp))\n\n    [[ \"${_diff}\" -gt \"${NB_AUTO_SYNC_SECONDS:-60}\" ]]\n  }\n\n  # _git_checkpoint()\n  #\n  # Usage:\n  #   _git_checkpoint <notebook-path> <commit-message>\n  #\n  # Description:\n  #   Commit all files in <notebook-path> with the provided <commit-message>.\n  _git_checkpoint() {\n    ((_GIT_ENABLED)) || return 0\n\n    # Usage: _git_checkpoint_commit <notebook-path> <message>\n    _git_checkpoint_commit() {\n      local _message=\"${2:-}\"\n      local _notebook_path=\"${1:-}\"\n\n      if [[ -z \"${_notebook_path:-}\" ]] || [[ -z \"${_message:-}\" ]]\n      then\n        _exit_1 printf \\\n           \"Usage: _git_checkpoint_commit <message> <notebook-path>\"\n      fi\n\n      git -C \"${_notebook_path}\" add --all &&\n        git -C \"${_notebook_path}\" commit -a -m \"${_message}\"\n    }\n\n    local _message=\n    local _notebook_path=\n    local _wait=0\n\n    local __arg=\n    for   __arg in \"${@:-}\"\n    do\n      case \"${__arg}\" in\n        --spinner|--wait)\n          _wait=1\n          ;;\n        *)\n          if [[ -z \"${_notebook_path}\"  ]] &&\n             [[ \"${__arg}\" =~ ^/        ]] &&\n             [[ -d \"${__arg}\"           ]]\n          then\n            _notebook_path=\"${__arg}\"\n          elif [[ -z \"${_message}\" ]]\n          then\n            _message=\"${__arg}\"\n          fi\n          ;;\n      esac\n    done\n\n    if [[ -z \"${_notebook_path:-}\" ]]\n    then\n      _notebook_path=\"$(_notebooks current --path)\"\n    fi\n\n    if [[ -z \"${_message}\" ]]\n    then\n      _message=\"[${_ME}] Commit\"\n    fi\n\n    if ((NB_AUTO_SYNC))\n    then\n      (\n        {\n          # only commit when the index is dirty\n          if _git dirty \"${_notebook_path}\"\n          then\n            _git_checkpoint_commit \"${_notebook_path}\" \"${_message}\" &>/dev/null\n          fi && GIT_TERMINAL_PROMPT=0 _git sync \"${_notebook_path}\"  &>/dev/null\n        } || :\n      ) &\n    else\n      (\n        _git_checkpoint_commit \"${_notebook_path}\" \"${_message}\" &>/dev/null ||\n          return 0\n      ) &\n    fi\n\n    if ((_wait))\n    then\n      if ! _piped_input\n      then # interative shell\n        _spinner  ${!}\n      fi\n\n      wait      ${!}\n      return    ${?}\n    else\n      return    0\n    fi\n  }\n\n  # _git_dirty()\n  #\n  # Usage:\n  #   _git_dirty [<notebook-path>]\n  #\n  # Exit / Error / Return Status:\n  #   0 (success, true)  If there are uncommitted changes in <notebook-path>\n  #                      or the current notebook.\n  #   1 (error,  false)  If <notebook-path> or the current notebook is clean.\n  _git_dirty() {\n    ((_GIT_ENABLED)) || return 1\n\n    local _target_path=\"${1:-}\"\n\n    if [[ -z \"${_target_path:-}\" ]]\n    then\n      _target_path=\"$(_notebooks current --path)\"\n    fi\n\n    [[ -n \"$(git -C \"${_target_path}\" status --porcelain)\" ]]\n  }\n\n  # _git_out_of_sync()\n  #\n  # Usage:\n  #   _git_out_of_sync [<notebook-path>]\n  #\n  # Exit / Error / Return Status:\n  #   0 (success, true)  If <notebook-path> or the current notebook is out of\n  #                      sync with the remote.\n  #   1 (error,  false)  If <notebook-path> or the current notebook is synced\n  #                      with the remote.\n  _git_out_of_sync() {\n    ((_GIT_ENABLED)) || return 1\n\n    local _notebook_path=\"${1:-}\"\n\n    if [[ -z \"${_notebook_path:-}\" ]]\n    then\n      _notebook_path=\"$(_notebooks current --path)\"\n    fi\n\n    # get the current branch name\n    local _branch=\n    _branch=\"$(\n      git -C \"${_notebook_path}\" rev-parse --abbrev-ref HEAD\n    )\"\n\n    # get the local branch HEAD SHA\n    local _local_head=\n    _local_head=\"$(\n      git -C \"${_notebook_path}\" rev-parse \"${_branch}\"\n    )\"\n\n    # get the remote branch HEAD SHA\n    local _remote_head=\n    _remote_head=\"$(\n      git -C \"${_notebook_path}\" ls-remote origin \"refs/heads/${_branch}\" 2>/dev/null | awk '{print $1}'\n    )\"\n\n    mkdir -p \"${_notebook_path}/.git/nb\"\n    date +%s > \"${_notebook_path}/.git/nb/last_sync_state_checked\"\n\n    [[ -n \"${_remote_head:-}\" ]] && [[ \"${_local_head}\" != \"${_remote_head}\" ]]\n  }\n\n  # _git_required()\n  #\n  # Usage:\n  #   _git_required\n  #\n  # Description:\n  #   Exit with `_exit_1` if `git` isn't found.\n  _git_required() {\n    ((_GIT_ENABLED)) || return 0\n\n    if ! _command_exists \"git\"\n    then\n      _exit_1 cat <<HEREDOC\nWelcome to $(_color_primary \"${_ME}\")!\n\nGit is required, but wasn't found. Install Git, then run \\`${_ME}\\` again.\n\nAbout Git: $(_color_primary \"https://git-scm.com\")\nHEREDOC\n    fi\n\n    local _git_name=\n    _git_name=\"$(git config --global --includes user.name   || printf '')\"\n\n    local _git_email=\n    _git_email=\"$(git config --global --includes user.email || printf '')\"\n\n    if [[ -z \"${_git_name:-}\"   ]]  ||\n       [[ -z \"${_git_email:-}\"  ]]\n    then\n      cat <<HEREDOC\nWelcome to $(_color_primary \"${_ME}\")!\n\nGit requires some additional setup before using $(_color_primary \"${_ME}\").\nEnter the name and email address you'd like to use with Git.\nEdits you make are attributed to this name and email address.\nHEREDOC\n      if [[ -z \"${_git_name:-}\"   ]]\n      then\n        while true\n        do\n          local __name=\n          IFS='' read -r -e -d $'\\n' -p \"$(_color_primary \"Name\"):  \" __name\n\n          if [[ -n \"${__name:-}\"  ]]\n          then\n            git config --global --includes user.name \"${__name}\"\n\n            break\n          fi\n        done\n      fi\n\n      if [[ -z \"${_git_email:-}\"  ]]\n      then\n        while true\n        do\n          local __email=\n          IFS='' read -r -e -d $'\\n' -p \"$(_color_primary \"Email\"): \" __email\n\n          if [[ -n \"${__email:-}\" ]]\n          then\n            git config --global --includes user.email \"${__email}\"\n\n            break\n          fi\n        done\n      fi\n    fi\n  }\n\n  # _git_sync()\n  #\n  # Usage:\n  #   _git_sync [<notebook-path>]\n  #\n  # Description:\n  #   Sync <notebook-path> or the current notebook with the remote.\n  _git_sync() {\n    local _notebook_path=\"${1:-}\"\n    local _prompt=\"${GIT_TERMINAL_PROMPT:-1}\"\n\n    if _contains \"--skip-prompt\" \"${1:-}\" \"${2:-}\"\n    then\n      _prompt=0\n    fi\n\n    if [[ -z \"${_notebook_path:-}\"  ]]\n    then\n      _notebook_path=\"$(_notebooks current --path)\"\n    fi\n\n    local _remote_url=\n\n    if ! _remote_url=\"$(git -C \"${_notebook_path}\" remote get-url origin 2>/dev/null)\" ||\n       [[ -z \"${_remote_url:-}\"     ]]\n    then\n      return 0\n    fi\n\n    local _git_branch=\n    _git_branch=\"$(git -C \"${_notebook_path}\" rev-parse --abbrev-ref HEAD 2>/dev/null)\"\n\n    local _branch_query_succeeded=0\n\n    local _remote_branches=\n    _remote_branches=($(\n      git -C \"${_notebook_path}\" ls-remote --heads \"${_remote_url}\" 2>/dev/null \\\n        | LC_ALL=C sed \"s/.*\\///g\"\n    )) && _branch_query_succeeded=1\n\n    if ! GIT_TERMINAL_PROMPT=0 git -C \"${_notebook_path}\" fetch origin \"${_git_branch}\" &>/dev/null\n    then\n      if _contains \"${_git_branch}\" \"${_remote_branches[@]:-}\" ||\n         ! ((_branch_query_succeeded))\n      then\n        if ((_prompt))\n        then # fetch again, displaying git prompt and/or errors after newline\n          printf \"\\\\n\"\n\n          if ! GIT_TERMINAL_PROMPT=1 git -C \"${_notebook_path}\" fetch origin \"${_git_branch}\"\n          then\n            exit 1\n          fi\n        else\n          return 1\n        fi\n      fi\n    fi\n\n    if ((_prompt))\n    then\n      if ! _contains \"${_git_branch}\" \"${_remote_branches[@]:-}\"  ||\n         ! git -C \"${_notebook_path}\" show-branch                 \\\n           \"remotes/origin/${_git_branch}\" > /dev/null 2>&1       ||\n         {\n           local _local_branch_root_hash=\n           _local_branch_root_hash=\"$(\n             git -C \"${_notebook_path}\" rev-list --max-parents=0  \\\n               \"${_git_branch}\"\n           )\"\n\n           local _remote_branch_root_hash=\n           _remote_branch_root_hash=\"$(\n             git -C \"${_notebook_path}\" rev-list --max-parents=0  \\\n               \"remotes/origin/${_git_branch}\"\n           )\"\n\n           [[ \"${_local_branch_root_hash:-}\" != \"${_remote_branch_root_hash:-}\" ]]\n         }\n      then\n        printf \"\\\\n\"\n\n        _remote set \"${_remote_url}\" \"${_git_branch}\" --skip-preamble\n\n        _git_branch=\"$(git -C \"${_notebook_path}\" rev-parse --abbrev-ref HEAD)\"\n      fi\n    fi\n\n    if git -C \"${_notebook_path}\" show-branch \\\n         \"remotes/origin/${_git_branch}\"      \\\n         > /dev/null 2>&1                     &&\n         ! git -C \"${_notebook_path}\" rebase \"origin/${_git_branch}\" &>/dev/null\n    then\n      local _merge_error=1\n\n      local _conflicted_files=\n      _conflicted_files=($(\n        GIT_PAGER='' git -C \"${_notebook_path}\" diff --name-only --diff-filter=U\n      ))\n\n      local _conflicted_binary_files=()\n      local _conflicted_text_files=()\n\n      if [[ -n \"${_conflicted_files[*]:-}\" ]]\n      then\n        local __maybe_index_relative_path=\n        for   __maybe_index_relative_path in \"${_conflicted_files[@]}\"\n        do\n          if [[ \"${__maybe_index_relative_path}\" =~ (^.index$|/.index$) ]]\n          then\n            # Remove git conflict markers to keep both.\n            # More info: https://stackoverflow.com/a/55187779\n            _sed_i              \\\n              -e '/^<<<<<<</d'  \\\n              -e '/^>>>>>>>/d'  \\\n              -e '/=======/d'   \\\n              \"${_notebook_path}/${__maybe_index_relative_path}\"\n\n            git -C \"${_notebook_path}\" add \"${__maybe_index_relative_path}\"\n          fi\n        done\n\n        local __relative_path=\n        for   __relative_path in \"${_conflicted_files[@]}\"\n        do\n          [[ \"${__relative_path}\" =~ (^.index$|/.index$) ]] && continue\n\n          if _file_is_text \"${__relative_path}\"\n          then\n            _conflicted_text_files+=(\"${__relative_path}\")\n\n            git -C \"${_notebook_path}\" add                \\\n              \"${__relative_path}\"\n          else\n            git -C \"${_notebook_path}\" checkout           \\\n              \"origin/${_git_branch}\" -- \"${__relative_path}\"\n\n            local _conflicted_file=\n            _conflicted_file=\"$(\n              _notebooks show \"${_notebook_path}\"         \\\n                --filename  \"${__relative_path%%.*}--conflicted-copy.${__relative_path#*.}\"\n            )\"\n\n            _conflicted_binary_files+=(\"${_conflicted_file}\")\n\n            git -C \"${_notebook_path}\" mv                 \\\n              \"${__relative_path}\" \"${_conflicted_file}\"\n\n            git -C \"${_notebook_path}\" checkout           \\\n              \"${_git_branch}\" -- \"${__relative_path}\"\n\n            git -C \"${_notebook_path}\" add \"${_conflicted_file}\"\n            git -C \"${_notebook_path}\" add \"${__relative_path}\"\n          fi\n        done\n\n        GIT_EDITOR=true git -C \"${_notebook_path}\" rebase \\\n          --continue &>/dev/null                          &&\n            _merge_error=0\n      fi\n\n      if ((_merge_error))\n      then\n        git -C \"${_notebook_path}\" rebase --abort\n\n        _warn printf                                              \\\n          \"Merge conflict. Use \\`%s git\\` to merge manually.\\\\n\"  \\\n          \"${_ME}\"\n\n        return 1\n      else\n        local _notebook_name=\n        _notebook_name=\"$(_notebooks show \"${_notebook_path}\" --name)\"\n\n        if ((${#_conflicted_text_files[@]}))\n        then\n          printf \"\\\\n\"\n\n          _warn cat <<HEREDOC\nFiles containing conflicts:\n\n$(printf \"  %s\\\\n\" \"${_conflicted_text_files[@]/#/${_notebook_name}:}\")\n\nResolve conflicts with \\`${_ME} edit\\`. More info: \\`${_ME} help sync\\`\nHEREDOC\n        fi\n\n        if ((${#_conflicted_binary_files[@]}))\n        then\n          printf \"\\\\n\"\n\n          _warn cat <<HEREDOC\nConflicted copies of binary files:\n\n$(printf \"  %s\\\\n\" \"${_conflicted_binary_files[@]/#/${_notebook_name}:}\")\nHEREDOC\n        fi\n      fi\n    fi\n\n    GIT_TERMINAL_PROMPT=\"${GIT_TERMINAL_PROMPT:-1}\" \\\n      git -C \"${_notebook_path}\" push               \\\n      --set-upstream                                \\\n      origin \"${_git_branch}\"                       \\\n      &>/dev/null || {\n        _warn printf \"Unable to push to remote.\\\\n\"\n\n        return 1\n      }\n  }\n\n  case \"${1:-}\" in\n    *autosync*)\n      _git_autosyncable \"${2:-}\"\n      ;;\n    checkpoint)\n      shift\n\n      _git_checkpoint \"${@:-}\"\n      ;;\n    dirty)\n      _git_dirty \"${2:-}\"\n      ;;\n    out*of*sync|o|oos|out)\n      _git_out_of_sync \"${2:-}\"\n      ;;\n    required|setup)\n      _git_required\n      ;;\n    sync)\n      _git_sync \"${2:-}\" \"${3:-}\"\n      ;;\n    *)\n      local _notebook_path=\n      _notebook_path=\"$(_notebooks current --path)\"\n\n      if [[ -n \"${1:-}\" ]]\n      then\n        git -C \"${_notebook_path}\" \"${@}\"\n      else\n        git -C \"${_notebook_path}\"\n      fi\n      ;;\n  esac\n}\n\n# help · ############################################################### · help\n\nexport _README_URL=\"https://github.com/xwmx/nb\"\n\n_describe_help() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} help [<subcommand>] [-p | --print]\n  ${_ME} help [-c | --colors] | [-r | --readme] | [-s | --short] [-p | --print]\n\n$(_color_primary \"Options\"):\n  -c, --colors  View information about color themes and color settings.\n  -p, --print   Print to standard output / terminal.\n  -r, --readme  View the \\`${_ME}\\` README file.\n  -s, --short   Print shorter help without subcommand descriptions.\n\n$(_color_primary \"Description\"):\n  Print the program help information. When a subcommand name is passed, print\n  the help information for the subcommand.\n\n$(_color_primary \"Examples\"):\n  ${_ME} help\n  ${_ME} help add\n  ${_ME} help import\n  ${_ME} h notebooks\n  ${_ME} h e\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} h\nHEREDOC\n}\n_help() {\n  local _arguments=()\n  local _color_help=0\n  local _readme=0\n  local _shell=0\n  local _short=0\n  local _use_pager=1\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      +) _help \"add\"    && return 0 ;;\n      -) _help \"delete\" && return 0 ;;\n      --pager)\n        _use_pager=1\n        ;;\n      -p|--print|--dump|--skip*pager|--no*pager)\n        _use_pager=0\n        ;;\n      -r|*readme*|*README*)\n        _readme=1\n        ;;\n      --shell)\n        _shell=1\n        ;;\n      -s|--short)\n        _short=1\n        ;;\n      -c|*color*|*colour*|*theme*)\n        _color_help=1\n        ;;\n      *)\n        _arguments+=(\"${__arg}\")\n        ;;\n    esac\n  done\n\n  if ! ((_COLOR_ENABLED))\n  then\n    _TPUT_COLOR_PRIMARY=\"\"\n    _TPUT_SETAF_8=\"\"\n    _TPUT_SGR0=\"\"\n  fi\n\n  if ((_readme))\n  then\n    _download_from --no-chrome              \\\n      \"${_REPO_RAW_URL}/README.md\"          \\\n        | if _command_exists \"pandoc\"       &&\n             _web_browser --check\n          then\n            _pandoc                         \\\n              --standard-input              \\\n              --from  markdown              \\\n              --to    html                  \\\n              2>/dev/null                   \\\n              | _web_browser\n\n            return 0\n          else\n            _highlight_syntax_if_available  \\\n              | if ((_use_pager))\n                then\n                  _pager\n                else\n                  cat\n                fi\n          fi\n  else\n    if ((_color_help))\n    then\n      # NOTE: this screen mirrors the content from README.md#-color-themes:\n      # https://github.com/xwmx/nb#-color-themes\n      _color_primary  \" __          _                     _\"\n      _color_primary  \" \\ \\   _ __ | |__         ___ ___ | | ___  _ __ ___\"\n      _color_primary  \"  \\ \\ | '_ \\| '_ \\   _   / __/ _ \\| |/ _ \\| '__/ __|\"\n      _color_primary  \"  / / | | | | |_) | (_) | (_| (_) | | (_) | |  \\__ \\\\\"\n      _color_primary  \" /_/  |_| |_|_.__/       \\___\\___/|_|\\___/|_|  |___/\"\n      printf \"\\\\n\"\n      _color_secondary \\\n                      \" ---------------------------------------------------\"\n      printf \"\\\\n\"\n      cat <<HEREDOC\n\\`${_ME}\\` uses color to highlight various interface elements, including ids,\nthe current notebook name, the shell prompt, and divider lines.\n\n\\`${_ME}\\` includes several built-in color themes and also supports user-defined\nthemes. The current color theme can be set using \\`${_ME} set color_theme\\`:\n\n    $(_color_primary \"${_ME} set color_theme\")\n\nCustom color themes are \\`${_ME}\\` plugins with a \\`.${_ME}-theme\\` file extension.\nA theme is defined with a single \\`if\\` statement indicating the name and\nassigning the color environment variables to \\`tput\\` ANSI color numbers:\n\n    $(_color_secondary \"# turquoise.${_ME}-theme\")\n    $(_color_primary \"if [[ \\\"\\${NB_COLOR_THEME}\\\" == ${_TPUT_SGR0}\\\"turquoise\\\"${_TPUT_COLOR_PRIMARY} ]]\")\n    $(_color_primary \"then\")\n    $(_color_primary \"  export NB_COLOR_PRIMARY=${_TPUT_SGR0}43${_TPUT_COLOR_PRIMARY}\")\n    $(_color_primary \"  export NB_COLOR_SECONDARY=${_TPUT_SGR0}38${_TPUT_COLOR_PRIMARY}\")\n    $(_color_primary \"fi\")\n\nView this theme as a complete file\n\n    $(_color_primary \"https://github.com/xwmx/nb/blob/master/plugins/turquoise.${_ME}-theme\")\n\nThemes can be installed using the \\`${_ME} plugins\\` subcommand:\n\n    $(_color_muted \">\") $(_color_primary \"${_ME} plugins install https://github.com/xwmx/nb/blob/master/plugins/turquoise.${_ME}-theme\")\n    $(_color_secondary \"Plugin installed:\")\n    $(_color_secondary \"/home/example/.${_ME}/.plugins/turquoise.${_ME}-theme\")\n\nOnce a theme is installed, use it with \\`${_ME} set color_theme\\`:\n\n    $(_color_muted \">\") $(_color_primary \"${_ME} set color_theme turquoise\")\n    $(_color_secondary \"NB_COLOR_THEME set to turquoise\")\n\nThe primary and secondary colors can also be overridden individually,\nmaking color themes easily customizable:\n\n    $(_color_secondary \"# open the settings prompt for the primary color\")\n    $(_color_primary \"${_ME} set color_primary\")\n\n    $(_color_secondary \"# open the settings prompt for the secondary color\")\n    $(_color_primary \"${_ME} set color_secondary\")\n\nTo view a table of available colors and numbers, run:\n\n    $(_color_primary \"${_ME} settings colors\")\n\nTo set the syntax highlighting color theme, use:\n\n    $(_color_primary \"${_ME} set syntax_theme\")\n\nHEREDOC\n    elif [[ -z \"${_arguments[*]:-}\" ]] || ((_short))\n    then\n      _color_primary        \" __          _\"\n      _color_primary        \" \\ \\   _ __ | |__\"\n      _color_primary        \"  \\ \\ | '_ \\| '_ \\\\\"\n      _color_primary        \"  / / | | | | |_) |\"\n      _color_primary        \" /_/  |_| |_|_.__/\"\n\n      printf        \\\n        \"\\\\n %s\\\\n\" \\\n        \"$(_color_secondary  \"------------------\")\"\n\n      cat <<HEREDOC\n\n$(_color_brackets \"${_ME}\") Command line and local web note-taking, bookmarking, and archiving with\nplain text data storage, encryption, filtering and search, pinning, #tagging,\nGit-backed versioning and syncing, Pandoc-backed conversion, global and local\nnotebooks, customizable color themes, [[wiki-style linking]], plugins, and more\nin a single portable, user-friendly script.\n\n$(_color_primary \"Help\"):\n  ${_ME} help               Display this help information.\n  ${_ME} help <subcommand>  View help information for <subcommand>.\n  ${_ME} help --colors      View information about color settings.\n  ${_ME} help --readme      View the \\`${_ME}\\` README file.\n\n$(_color_primary \"Usage\"):\n  ${_ME}\n  ${_ME} [<ls-options>...] [<id> | <filename> | <path> | <title> | <notebook>]\n  ${_ME} [<url>] [<bookmark options>...]\n  ${_ME} add [<notebook>:][<folder-path>/][<filename>] [<content>]\n         [-b | --browse] [-c <content> | --content <content>] [--edit]\n         [-e | --encrypt] [-f <filename> | --filename <filename>]\n         [--folder <folder-path>] [--no-template] [--tags <tag1>,<tag2>...]\n         [--template <template>] [-t <title> | --title <title>] [--type <type>]\n  ${_ME} add bookmark [<bookmark-options>...]\n  ${_ME} add folder [<name>]\n  ${_ME} add todo [<todo-options>...]\n  ${_ME} archive [<notebook>]\n  ${_ME} bookmark [<ls-options>...]\n  ${_ME} bookmark [<notebook>:][<folder-path>/] <url>...\n              [-c <comment> | --comment <comment>] [--edit] [-e | --encrypt]\n              [-f <filename> | --filename <filename>] [--no-request]\n              [-q <quote> | --quote <quote>] [--save-source]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]...\n              [-t <tag1>,<tag2>... | --tags <tag1>,<tag2>...] [--title <title>]\n  ${_ME} bookmark [list [<list-options>...]]\n  ${_ME} bookmark (edit | delete | open | peek | url)\n              ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} bookmark search <query>\n  ${_ME} browse [<notebook>:][<folder-path>/][<id> | <filename> | <title>] [--daemon]\n            [-g | --gui] [-n | --notebooks] [-p | --print] [-q | --query <query>]\n            [-s | --serve] [-t <tag> | --tag <tag> | --tags <tag1>,<tag2>...]\n  ${_ME} browse add [<notebook>:][<folder-path>/][<filename>]\n            [-c <content> | --content <content>] [--tags <tag1>,<tag2>...]\n            [-t <title> | --title <title>]\n  ${_ME} browse delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} browse edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} completions (check | install [-d | --download] | uninstall)\n  ${_ME} copy ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[<notebook>:][<folder-path>/]<filename>]\n  ${_ME} count [<notebook>:][<folder-path>/]\n  ${_ME} delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])...\n            [-f | --force]\n  ${_ME} do ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n        [<task-number>]\n  ${_ME} edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [-c <content> | --content <content>] [--edit]\n          [-e <editor> | --editor <editor>] [-l | --last] [--overwrite]\n          [--prepend]\n  ${_ME} env [-l | --long]\n  ${_ME} env [install | update] [--ace | --mathjax]\n  ${_ME} export ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <path> [-f | --force] [<pandoc options>...]\n  ${_ME} export notebook <name> [<path>]\n  ${_ME} export pandoc ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            [<pandoc options>...]\n  ${_ME} folders (add | delete) [<notebook>:][<folder-path>/]<folder-name>\n  ${_ME} folders <list-options>...\n  ${_ME} git [checkpoint [<message>] | dirty]\n  ${_ME} git <git-options>...\n  ${_ME} help [<subcommand>] [-p | --print]\n  ${_ME} help [-c | --colors] | [-r | --readme] | [-s | --short] [-p | --print]\n  ${_ME} history [<notebook>:][<folder-path>/][<id> | <filename> | <title>]\n  ${_ME} import [bookmarks | copy | download | move] (<path>... | <url>)\n            [--convert] [<notebook>:][<folder-path>/][<filename>]\n  ${_ME} import notebook <path> [<name>]\n  ${_ME} init [<remote-url> [<branch>]] [--author] [--email <email>]\n          [--name <name>]\n  ${_ME} list [-e [<length>] | --excerpt [<length>]] [--filenames]\n          [-f | --folders-first] [-n <limit> | --limit <limit> | --<limit>]\n          [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n          [--paths] [-s | --sort] [-r | --reverse] [--tags]\n          [-t <type> | --type <type> | --<type>]\n          [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n  ${_ME} ls [-a | --all] [-b | --browse] [-e [<length>] | --excerpt [<length>]]\n        [--filenames] [-f | --folders-first] [-g | --gui]\n        [-n <limit> | --limit <limit> | --<limit>] [--no-footer] [--no-header]\n        [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n        [--paths] [-s | --sort] [-r | --reverse] [--tags]\n        [-t <type> | --type <type> | --<type>]\n        [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n  ${_ME} move ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          ([<notebook>:][<path>] | --reset | --to-bookmark | --to-note |\n          --to-title | --to-todo) [-f | --force]\n  ${_ME} notebooks [<name> | <query>] [--ar | --archived] [--global] [--local]\n               [--names] [--paths] [--unar | --unarchived]\n  ${_ME} notebooks add ([<name>] [<remote-url> [<branch>... | --all]]) [--author]\n                   [--email <email>] [--name <name>]\n  ${_ME} notebooks (archive | open | peek | status | unarchive) [<name>]\n  ${_ME} notebooks author [<name> | <path>] [--email <email>] [--name <name>]\n  ${_ME} notebooks current [--path | --selected | --filename [<filename>]]\n                       [--global | --local]\n  ${_ME} notebooks delete <name> [-f | --force]\n  ${_ME} notebooks (export <name> [<path>] | import <path>)\n  ${_ME} notebooks init [<path> [<remote-url> [<branch>]]] [--author]\n                    [--email <email>] [--name <name>]\n  ${_ME} notebooks rename <old-name> <new-name>\n  ${_ME} notebooks select <selector>\n  ${_ME} notebooks show (<name> | <path> | <selector>) [--ar | --archived]\n                    [--escaped | --name | --path | --filename [<filename>]]\n  ${_ME} notebooks use <name>\n  ${_ME} open ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} peek ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} pin  ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} plugins [<name>] [--paths]\n  ${_ME} plugins install [<path> | <url>] [--force]\n  ${_ME} plugins uninstall <name> [--force]\n  ${_ME} remote [branches [<url>] | remove | rename [<branch-name>] <name>]\n  ${_ME} remote [delete <branch-name> | reset <branch-name>]\n  ${_ME} remote set <url> [<branch-name>]\n  ${_ME} run <command> [<arguments>...]\n  ${_ME} search ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <query>... [-a | --all] [--and <query>] [--not <query>] [--or <query>]\n            [-l | --list] [--path] [-t <tag1>,<tag2>... | --tag <tag1>,<tag2>...]\n            [-t | --tags] [--type <type> | --<type>] [--utility <name>]\n  ${_ME} set [<name> [<value>] | <number> [<value>]]\n  ${_ME} settings [colors [<number> | themes] | edit | list [--long]]\n  ${_ME} settings (get | show | unset) (<name> | <number>)\n  ${_ME} settings set (<name> | <number>) <value>\n  ${_ME} shell [<subcommand> [<options>...] | --clear-history]\n  ${_ME} show ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[-a | --added] | [--authors] | [-b | --browse] | --filename | --id |\n          --info-line | --path | [-p | --print] | --relative-path | [-r |\n          --render] | --title | --type [<type>] | [-u | --updated]] [--no-color]\n  ${_ME} show <notebook>\n  ${_ME} status [<notebook>]\n  ${_ME} subcommands [add <name>...] [alias <name> <alias>]\n                 [describe <name> <usage>]\n  ${_ME} sync [-a | --all]\n  ${_ME} tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n           [open | closed]\n  ${_ME} todo add [<notebook>:][<folder-path>/][<filename>] <title>\n              [--description <description>] [--due <date>]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]\n              [--tags <tag1>,<tag2>...] [--task <title>...]\n  ${_ME} todo do   ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  ${_ME} todo undo ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  ${_ME} todos [<notebook>:][<folder-path>/] [open | closed] [--pager]\n               [--tags <tag1>,<tag2>...]\n  ${_ME} todos tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n                 [open | closed] [--pager]\n  ${_ME} unarchive [<notebook>]\n  ${_ME} undo ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [<task-number>]\n  ${_ME} unpin ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} unset (<name> | <number>)\n  ${_ME} update\n  ${_ME} use <notebook>\n  ${_ME} -h | --help | help [<subcommand> | --readme]\n  ${_ME} -i | --interactive [<subcommand> [<options>...]]\n  ${_ME} --no-color\n  ${_ME} --version | version\nHEREDOC\n\n      if ! ((_short))\n      then\n        cat <<HEREDOC\n\n$(_color_primary \"Subcommands\"):\n  (default)    List notes and notebooks. This is an alias for \\`${_ME} ls\\`.\n               When a <url> is provided, create a new bookmark.\n  add          Add a note, folder, or file.\n  archive      Archive the current or specified notebook.\n  bookmark     Add, open, list, and search bookmarks.\n  browse       Browse and manage linked items in terminal and GUI browsers.\n  completions  Install and uninstall completion scripts.\n  copy         Copy or duplicate an item.\n  count        Print the number of items in a notebook or folder.\n  delete       Delete a note.\n  do           Mark a todo or task as done.\n  edit         Edit a note.\n  env          Print environment information and install dependencies.\n  export       Export a note to a variety of different formats.\n  folders      Add, delete, and list folders.\n  git          Run \\`git\\` commands within the current notebook.\n  help         View help information for the program or a subcommand.\n  history      View git history for the current notebook or a note.\n  import       Import a file into the current notebook.\n  init         Initialize the first notebook.\n  list         List notes in the current notebook.\n  ls           List notebooks and notes in the current notebook.\n  move         Move or rename a note.\n  notebooks    Manage notebooks.\n  open         Open a bookmarked web page or notebook folder, or edit a note.\n  peek         View a note, bookmarked web page, or notebook in the terminal.\n  pin          Pin an item so it appears first in lists.\n  plugins      Install and uninstall plugins and themes.\n  remote       Configure the remote URL and branch for the notebook.\n  run          Run shell commands within the current notebook.\n  search       Search notes.\n  settings     Edit configuration settings.\n  shell        Start the \\`${_ME}\\` interactive shell.\n  show         Show a note or notebook.\n  status       Print notebook status information.\n  subcommands  List, add, alias, and describe subcommands.\n  sync         Sync local notebook with the remote repository.\n  tasks        List tasks in todos, notebooks, folders, and other items.\n  todo         Manage todos and tasks.\n  unarchive    Unarchive the current or specified notebook.\n  undo         Mark a todo or task as not done.\n  unset        Return a setting to its default value.\n  unpin        Unpin a pinned item.\n  update       Update \\`${_ME}\\` to the latest version.\n  use          Switch to a notebook.\n  version      Display version information.\n\n$(_color_primary \"Notebook Usage\"):\n  ${_ME} <notebook>:[<subcommand>] [<identifier>] [<options>...]\n  ${_ME} <subcommand> <notebook>:<identifier> [<options>...]\n\n$(_color_primary \"Program Options\"):\n  -h, --help          Display this help information.\n  -i, --interactive   Start the \\`${_ME}\\` interactive shell.\n  --no-color          Print without color highlighting.\n  --version           Display version information.\n\n$(_color_primary \"More Information\"):\n  https://github.com/${_REPO}\n\n$(_color_primary \"Sponsor & Donate\"):\n  https://github.com/sponsors/xwmx\n  https://paypal.me/WilliamMelody\n\n$(_color_primary \"Created By\"):\n  William Melody\n  https://github.com/xwmx\n  https://www.williammelody.com\n\n$(_color_primary \"Contributors\"):\n  https://github.com/xwmx/nb/graphs/contributors\n\nHEREDOC\n      fi\n    else\n      printf \"%s\\\\n\" \"$(describe --get \"${_arguments[@]}\")\"\n    fi | {\n      if ((_shell))\n      then\n        LC_ALL=C sed -e \"s/^  ${_ME} /  /\" -e \"/^  ${_ME}$/d\"\n      else\n        cat\n      fi\n    } | {\n      if ((_color_help))\n      then\n        cat\n      else\n        local _replacement_pattern=\"${_TPUT_SGR0}${_TPUT_SETAF_8}\\1${_TPUT_SGR0}\"\n\n        LC_ALL=C sed -E                                                               \\\n-e \"/^\\ \\ |\\[\\[wiki\\-style\\ linking\\]\\]/s/(\\[|\\]|\\(|\\)|\\|)/${_replacement_pattern}/g\" \\\n-e \"s/#tag/${_TPUT_SGR0}${_TPUT_SETAF_8}#${_TPUT_SGR0}tag/g\"                          \\\n-e \"s/(currently\\ set\\ to: )(.*)/\\1${_TPUT_SGR0}${_TPUT_COLOR_PRIMARY}\\2${_TPUT_SGR0}/g\"\n      fi\n    } | {\n      LC_ALL=C sed -e \"s/\\`/${_TPUT_SGR0}${_TPUT_SETAF_8}\\`${_TPUT_SGR0}/g\"\n    } | {\n      if ((_use_pager))\n      then\n        _pager\n      else\n        cat\n      fi\n    }\n  fi\n}\n_alias_subcommand \"help\" \"h\"\n\n# index · ############################################################# · index\n\n_describe_index() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} index add <filename>\n  ${_ME} index delete <filename>\n  ${_ME} index edit\n  ${_ME} index get_basename <id>\n  ${_ME} index get_id <filename>\n  ${_ME} index get_max_id\n  ${_ME} index rebuild [--ancestors]\n  ${_ME} index reconcile [--ancestors] [--commit]\n  ${_ME} index show\n  ${_ME} index update <existing-filename> <new-filename>\n  ${_ME} index verify\n  ${_ME} index <subcommand> <options>... [<folder-path>]\n\n$(_color_primary \"Options\"):\n  --ancestors   Perform the action on all folders within the notebook that\n                are ancestors of the current folder.\n  --commit      Commit changes to git.\n\n$(_color_primary \"Subcommands\"):\n  add           Add <filename> to the index.\n  delete        Delete <filename> from the index.\n  edit          Open the index file in \\`\\$EDITOR\\`.\n  get_basename  Print the filename / basename at the specified <id>.\n  get_id        Get the id for <filename>.\n  get_max_id    Get the maximum id for the folder.\n  rebuild       Rebuild the index, listing files by last modified, reversed.\n                Some ids will change. Prefer \\`${_ME} index reconcile\\`.\n  reconcile     Remove duplicates and update index for added and deleted files.\n  show          Print the index.\n  update        Overwrite the <existing-filename> entry with <new-filename>.\n  verify        Verify that the index matches the folder contents.\n\n$(_color_primary \"Description\"):\n  Manage the index for the current folder or the folder at <folder-path>,\n  which can be passed as the final argument to any \\`index\\` subcommand.\n\n  \\`index\\` is used internally by \\`${_ME}\\` and using it manually will\n  probably corrupt the index. If something goes wrong with an index,\n  fix it with \\`${_ME} index reconcile\\`.\n\n  An index is a text file named '.index' in any folder within a notebook.\n  .index contains a list of filenames and the line number of each filename\n  represents the id. .index files are included in the git repository so\n  ids are preserved across systems.\nHEREDOC\n}\n_index() {\n  local _ancestors=0\n  local _commit_changes=0\n  local _folder_path=\n  local _subcommand=\"${1:-}\"\n\n  case \"${_subcommand:-}\" in\n    edit|get_max_id|show|verify)\n      _folder_path=\"${2:-}\"\n      ;;\n    rebuild|reconcile)\n      shift\n\n      local __arg=\n      for   __arg in \"${@:-}\"\n      do\n        case \"${__arg:-}\" in\n          --ancestors)\n            _ancestors=1\n            ;;\n          --commit|--checkpoint)\n            _commit_changes=1\n            ;;\n          *)\n            _folder_path=\"${__arg:-}\"\n            ;;\n        esac\n      done\n      ;;\n    add|delete|get_basename|get_id)\n      _folder_path=\"${3:-}\"\n      ;;\n    update)\n      _folder_path=\"${4:-}\"\n      ;;\n    *)\n      [[ -d \"${1:-}\" ]] && _folder_path=\"${1:-}\"\n      ;;\n  esac\n\n  _folder_path=\"${_folder_path:-\"${NB_NOTEBOOK_PATH}\"}\"\n\n  local _index_path=\"${_folder_path}/.index\"\n  local _notebook_path=\"${NB_NOTEBOOK_PATH}\"\n\n  if [[ ! \"${_folder_path:-}\" =~ ^${NB_NOTEBOOK_PATH} ]]\n  then\n    local _notebook_and_relative_path=\"${_folder_path#\"${NB_DIR}\"/}\"\n    _notebook_path=\"${NB_DIR}/${_notebook_and_relative_path%%/*}\"\n  fi\n\n  if [[ ! -e \"${_index_path}\" ]]\n  then\n    case \"${_subcommand}\" in\n      add)\n        _index reconcile \"${_folder_path}\" --ancestors\n        ;;\n      edit|rebuild|reconcile)\n        :\n        ;;\n      *)\n        _index reconcile \"${_folder_path}\" --ancestors --commit\n        ;;\n    esac\n  fi\n\n  case \"${_subcommand}\" in\n    add)\n      local _basename=\"${2:-}\"\n\n      if [[ -z \"${_basename}\" ]]\n      then\n        _exit_1 _help index\n      fi\n\n      if [[ ! -e \"${_folder_path}/${_basename}\" ]]\n      then\n        _exit_1 printf \"File not found: %s\\\\n\" \"${_folder_path}/${_basename}\"\n      fi\n\n      if ! grep -q \"^${_basename}$\" \"${_index_path}\"\n      then\n        {\n          printf \"%s\\\\n\" \"${_basename}\" | LC_ALL=C sed -E \"${_IGNORE_PATTERNS[@]:-}\"\n        } >> \"${_index_path}\"\n      fi\n      ;;\n    delete)\n      local _basename=\"${2:-}\"\n\n      if [[ -z \"${_basename}\" ]]\n      then\n        _exit_1 _help index\n      fi\n\n      _basename=\"${_basename//'['/\\\\[}\"\n      _basename=\"${_basename//']'/\\\\]}\"\n\n      if grep -q \"^${_basename}$\" \"${_index_path}\"\n      then\n        _sed_i -e \"s/^${_basename}$//g\" \"${_index_path}\"\n      else\n        return 1\n      fi\n      ;;\n    edit)\n      _edit_file \"${_index_path}\" --no-wait\n\n      return 0\n      ;;\n    get_basename)\n      # Usage: _index_get_basename <id> <index-path>\n      _index_get_basename() {\n        if [[ -z \"${1:-}\" ]] || [[ \"${1:-}\" == \"0\" ]]\n        then\n          return 1\n        fi\n\n        LC_ALL=C sed \"${1:-}q;d\" \"${2:-}\"\n      }\n\n      local _id_number=\"${2:-}\"\n      if [[ -z \"${_id_number}\"  ]]\n      then\n        _exit_1 _help index\n      fi\n\n      local _basename=\n      _basename=\"$(_index_get_basename \"${_id_number}\" \"${_index_path}\")\"\n\n      if [[ -z \"${_basename}\"   ]]\n      then\n        _index reconcile &&\n          _basename=\"$(_index_get_basename \"${_id_number}\" \"${_index_path}\")\"\n      fi\n\n      if [[ -z \"${_basename}\"   ]]\n      then\n        return 1\n      else\n        printf \"%s\\\\n\" \"${_basename}\"\n      fi\n      ;;\n    get_id)\n      # Usage: _index_get_id <basename> <index-path>\n      _index_get_id() {\n        # Alternatives:\n        # awk 'match($0,v){print NR; exit}' v=\"^${1:-}$\" \"${2:-}\"\n        # git -C \"${3:?}\" grep  \\\n        #   --line-number       \\\n        #   --no-color          \\\n        #   -e \"^${1:?}$\"       \\\n        #   \"${2:?}\"            \\\n        #   | cut -d: -f2\n        # grep -n \"^${1:-}$\" \"${2:-}\"                         | cut -d: -f1\n        # rg --color=never --line-number \"^${1:-}$\" \"${2:-}\"  | cut -d: -f1\n\n        local _basename=\"${1:-}\"\n        _basename=\"${_basename//\\[/\\\\\\[}\"\n        _basename=\"${_basename//\\]/\\\\\\]}\"\n\n        LC_ALL=C sed -n \"/^${_basename:-}$/=\" \"${2:-}\"\n      }\n\n      local _basename=\"${2:-}\"\n\n      if [[ -z \"${_basename}\" ]]\n      then\n        _help index\n\n        return 1\n      fi\n\n      local _id=\n      _id=\"$(_index_get_id \"${_basename}\" \"${_index_path}\")\"\n\n      if [[ -z \"${_id}\" ]]\n      then\n        _index reconcile &&\n          _id=\"$(_index_get_id \"${_basename}\" \"${_index_path}\")\"\n      fi\n\n      if [[ -z \"${_id}\" ]]\n      then\n        return 1\n      else\n        printf \"%s\\\\n\" \"${_id}\"\n      fi\n\n      # Alternative\n      # -----------\n\n      # local _basename=\"${2:-}\"\n      # local _id=\n\n      # if [[ -z \"${_basename}\" ]]\n      # then\n      #   _help index\n      #\n      #   return 1\n      # fi\n\n      # _index_get_id \"${_basename:-}\" \"${_index_path:-}\" | {\n      #   read -r _id\n\n      #   if [[ -n \"${_id:-}\"   ]]\n      #   then\n      #     printf \"%s\\\\n\" \"${_id:-}\"\n      #   else\n      #     _index reconcile &&\n      #       _index_get_id \"${_basename:-}\" \"${_index_path:-}\" | {\n      #           read -r _id\n\n      #           if [[ -n \"${_id:-}\" ]]\n      #           then\n      #             printf \"%s\\\\n\" \"${_id:-}\"\n      #           else\n      #             return 1\n      #           fi\n      #         }\n      #   fi\n      # }\n      ;;\n    get_max_id)\n      wc -l < \"${_index_path}\" | tr -d '[:space:]'\n\n      printf \"\\\\n\"\n      ;;\n    rebuild)\n      local _top_path=\"${_folder_path:?}\"\n\n      if ((_ancestors))\n      then\n        _top_path=\"${_notebook_path:?}\"\n      fi\n\n      local _rebuild_type=\"Rebuild\"\n\n      if [[ ! -e \"${_folder_path:?}/.index\" ]]\n      then\n        _rebuild_type=\"Initialize\"\n      fi\n\n      local _current_folder_path=\"${_folder_path:?}\"\n\n      while [[ \"${_current_folder_path:?}\" =~ ${_top_path:?} ]]\n      do\n        {\n          ls -t -r \"${_current_folder_path:?}\"\n        } | {\n          LC_ALL=C sed -E \"${_IGNORE_PATTERNS[@]:-}\"\n        } > \"${_current_folder_path:?}/.index\"\n\n        _current_folder_path=\"${_current_folder_path%/*}\"\n      done  &&\n        _git checkpoint \"${_notebook_path}\" \"[${_ME}] ${_rebuild_type:-Rebuild} Index\"\n\n      return 0\n      ;;\n    reconcile)\n      # Usage: _index_reconcile_remove_duplicates <index-path>\n      _index_reconcile_remove_duplicates() {\n        local _reconcile_index_path=\"${1:-}\"\n        [[ -z \"${_reconcile_index_path:-}\" ]] && return 1\n\n        local _temp_file=\n        _temp_file=\"$(_temp file)\"\n\n        exec 3> \"${_temp_file}\"\n        exec 4< \"${_temp_file}\"\n\n        rm \"${_temp_file:?}\"\n\n        # Remove duplicates and preserve newlines.\n        awk '!NF || !seen[$0]++' \"${_reconcile_index_path}\" >&3\n        cat <&4 > \"${_reconcile_index_path}\"\n\n        exec 3>&-\n        exec 4<&-\n      }\n\n      local _top_path=\"${_folder_path:?}\"\n\n      [[ -d \"${_top_path}\" ]] || return 0\n\n      if ((_ancestors))\n      then\n        _top_path=\"${_notebook_path:?}\"\n      fi\n\n      local _current_folder_path=\"${_folder_path:?}\"\n\n      while [[ \"${_current_folder_path:?}\" =~ ^${_top_path} ]]\n      do\n        if [[ ! -e \"${_current_folder_path:?}/.index\"       ]]\n        then\n          {\n            ls -t -r \"${_current_folder_path:?}\"\n          } | {\n            LC_ALL=C sed -E \"${_IGNORE_PATTERNS[@]:-}\"\n          } > \"${_current_folder_path:?}/.index\"\n        fi\n\n        local -a _index_list=()\n        _index_list=($(<\"${_current_folder_path:?}/.index\"))\n\n        local -a _file_list=()\n        _file_list=($(\n          {\n            ls -t -r \"${_current_folder_path:?}\"\n          } | {\n            LC_ALL=C sed -E \"${_IGNORE_PATTERNS[@]:-}\"\n          }\n        ))\n\n        _index_reconcile_remove_duplicates \"${_current_folder_path:?}/.index\"\n\n        local -a _index_file_list_diff=()\n        _index_file_list_diff=($(\n          printf \"%s\\\\n\"          \\\n            \"${_index_list[@]:-}\" \\\n            \"${_file_list[@]:-}\"  \\\n            | sort                \\\n            | uniq -u\n        ))\n\n        local -a _diff_in_index=()\n        _diff_in_index=($(\n          printf \"%s\\\\n\"                    \\\n            \"${_index_list[@]:-}\"           \\\n            \"${_index_file_list_diff[@]:-}\" \\\n            | sort                          \\\n            | uniq -d                       \\\n            | uniq\n        ))\n\n        local __item=\n        for   __item in \"${_diff_in_index[@]:-}\"\n        do\n          if [[ -n \"${__item}\" ]]\n          then\n            _contains \"${__item}\" \"${_file_list[@]:-}\" ||\n              _index delete \"${__item}\" \"${_current_folder_path:?}\"\n          fi\n        done\n\n        local -a _diff_in_file_list=()\n        _diff_in_file_list=($(\n          printf \"%s\\\\n\"                    \\\n            \"${_file_list[@]:-}\"            \\\n            \"${_index_file_list_diff[@]:-}\" \\\n            | sort                          \\\n            | uniq -d                       \\\n            | uniq\n        ))\n\n        local __item=\n        for   __item in \"${_diff_in_file_list[@]:-}\"\n        do\n          if [[ -n \"${__item}\" ]]\n          then\n            _contains \"${__item}\" \"${_index_list[@]:-}\" ||\n              _index add \"${__item}\" \"${_current_folder_path:?}\"\n          fi\n        done\n\n        _current_folder_path=\"${_current_folder_path%/*}\"\n      done\n\n      if ((_commit_changes))\n      then\n        _git checkpoint \"${_notebook_path}\" \"[${_ME}] Reconcile Index\"\n      fi\n      ;;\n    show)\n      cat \"${_index_path}\"\n      ;;\n    update)\n      local _new_basename=\"${3:-}\"\n      local _old_basename=\"${2:-}\"\n\n      if [[ -z \"${_old_basename}\" ]] || [[ -z \"${_new_basename}\" ]]\n      then\n        _exit_1 _help index\n      fi\n\n      _old_basename=\"${_old_basename//'['/\\\\[}\"\n      _old_basename=\"${_old_basename//']'/\\\\]}\"\n\n      if grep -q \"^${_old_basename}$\" \"${_index_path}\"\n      then\n        _sed_i -e \"s/^${_old_basename}$/${_new_basename}/g\" \"${_index_path}\"\n      else\n        return 1\n      fi\n      ;;\n    verify)\n      local _valid=1\n\n      local -a _index_list=()\n      _index_list=($(<\"${_index_path}\"))\n\n      local -a _file_list=()\n      _file_list=($(\n        {\n          ls -t -r \"${_folder_path}\"\n        } | {\n          LC_ALL=C sed -E \"${_IGNORE_PATTERNS[@]:-}\"\n        }\n      ))\n\n      local -a _index_file_list_diff=()\n      _index_file_list_diff=($(\n        printf \"%s\\\\n\"          \\\n          \"${_index_list[@]:-}\" \\\n          \"${_file_list[@]:-}\"  \\\n          | sort                \\\n          | uniq -u\n      ))\n\n      if [[ -n \"${_index_file_list_diff[*]:-}\" ]]\n      then\n        _valid=0\n      fi\n\n      local __item=\n      for   __item in $(printf \"%s\\\\n\" \"${_index_list[@]:-}\" | uniq -c)\n      do\n        local _count=\n        _count=\"$(printf \"%s\\\\n\" \"${__item}\" | awk '{print $1}')\"\n\n        if [[ \"${_count}\" -gt 1 ]]\n        then\n          _valid=0\n\n          break\n        fi\n      done\n\n      if ! ((_valid))\n      then\n        _warn                                                               \\\n          printf \"Index corrupted. To fix, run:\\\\n  %s index reconcile\\\\n\"  \\\n          \"${_ME}\"\n\n        return 1\n      else\n        return 0\n      fi\n      ;;\n    *)\n      :\n      ;;\n  esac\n}\n\n# init · ############################################################### · init\n\n_describe_init() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} init [<remote-url> [<branch>]] [--author] [--email <email>]\n          [--name <name>]\n\n$(_color_primary \"Options\"):\n  --author         Display the local email and name config prompt.\n  --email <email>  Set the local commit author email address to <email>.\n  --name  <name>   Set the local commit author name to <name>.\n\n$(_color_primary \"Description\"):\n  Initialize the initial \"home\" notebook and generate a configuration file at:\n\n      ${NBRC_PATH}\n\n  Pass optional <remote-url> and <branch> arguments to create the initial\n  \"home\" notebook using a clone of an existing notebook.\n\n$(_color_primary \"See Also\"):\n  ${_ME} help notebooks\n\n$(_color_primary \"Examples\"):\n  ${_ME} init\n  ${_ME} init https://github.com/example/example.git\n  ${_ME} init https://github.com/example/example.git example-branch\nHEREDOC\n}\n_init() {\n  # Usage: _init_create_home_notebook [<url> [<branch>]] [--author]\n  #                                   [--email <email>] [--name <name>]\n  _init_create_home_notebook() {\n    local _author=0\n    local _author_arguments=()\n    local _remote_branch=\n    local _remote_url=\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --author) _author=1 ;;\n        --email|--name)\n          _author=1\n          _author_arguments+=(\"${1:-}\")\n\n          if _option_value_is_present \"${2:-}\"\n          then\n            _author_arguments+=(\"${2:-}\")\n\n            shift\n          fi\n          ;;\n        *)\n          if   [[ -z \"${_remote_url:-}\"     ]] &&\n               _string_is_url \"${1:-}\"\n          then\n            _remote_url=\"${1:-}\"\n          elif [[ -z \"${_remote_branch:-}\"  ]]\n          then\n            _remote_branch=\"${1:-}\"\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    ((_author)) && _author_arguments+=(\"${NB_DIR}/home\")\n\n    if   [[ -n \"${_remote_url:-}\"     ]]\n    then\n      if [[ -n \"${_remote_branch:-}\"  ]]\n      then\n        git clone --no-local --single-branch --branch \"${_remote_branch:-}\" \\\n          \"${_remote_url}\"                                                  \\\n          \"${NB_DIR}/home\"\n      else\n        git clone --no-local --single-branch \"${_remote_url}\" \"${NB_DIR}/home\"\n      fi && if ((_author))\n            then\n              _notebooks author \"${_author_arguments[@]:-}\"\n            fi\n    else\n      {\n        mkdir -p  \"${NB_DIR}/home\"\n      } && {\n        if ((_GIT_ENABLED))\n        then\n          git -C  \"${NB_DIR}/home\" init   &>/dev/null\n        fi\n      } && {\n        if ((_author))\n        then\n          _notebooks author \"${_author_arguments[@]:-}\"\n        fi\n      } && {\n        touch  \"${NB_DIR}/home/.index\"\n      } && {\n        _git checkpoint \"${NB_DIR}/home\" \"[${_ME}] Initialize\"\n      }\n    fi\n\n    _notebooks use \"home\" 1>/dev/null\n\n    # printf \"Created notebook:           %s\\\\n\" \"$(_color_primary \"home\")\"\n  }\n\n  # Usage: _init_create_nb_dir\n  _init_create_nb_dir() {\n    if    [[ -d \"${NB_DIR}\" ]]\n    then\n      printf \"Data directory exists:      %s\\\\n\" \"$(_color_primary \"${NB_DIR}\")\"\n    elif  [[ -e \"${NB_DIR}\" ]]\n    then\n      _exit_1 cat <<HEREDOC\nUnable to set up the $(_color_primary \"${_ME}\") data directory. File exists at:\n${NB_DIR}\nHEREDOC\n    else\n      mkdir -p \"${NB_DIR}\"\n      printf \"Created data directory:     %s\\\\n\" \"$(_color_primary \"${NB_DIR}\")\"\n    fi\n  }\n\n  # Usage: _init_create_rc_file\n  _init_create_rc_file() {\n    if [[ -e \"${NBRC_PATH}\" ]]\n    then\n      printf \"Configuration file exists:  %s\\\\n\" \\\n        \"$(_color_primary \"${NBRC_PATH}\")\"\n    else\n      cat <<HEREDOC > \"${NBRC_PATH}\"\n#!/usr/bin/env bash\n###############################################################################\n# .${_ME}rc\n#\n# Configuration file for \\`${_ME}\\`, a command line note-taking, bookmarking,\n# and knowledge base application with encryption, search, Git-backed syncing,\n# and more in a single portable script.\n#\n# Edit this file manually or manage settings using the \\`${_ME} settings\\`\n# subcommand. Configuration options are set as environment variables, eg:\n#   export NB_ENCRYPTION_TOOL=gpg\n#\n# https://github.com/${_REPO}\n###############################################################################\nHEREDOC\n      printf \"Created configuration file: %s\\\\n\" \"$(_color_primary \"${NBRC_PATH}\")\"\n    fi\n  }\n\n  # Usage: _init_print_header\n  _init_print_header() {\n    printf \"%s%s\\\\n\" \"$(_color_primary \"Initializing\")\" \"$(_color_muted \"...\")\"\n  }\n\n  if [[ -e \"${NB_DIR}\" ]] && [[ ! -d \"${NB_DIR}\" ]]\n  then\n    _exit_1 printf \"NB_DIR exists and is not a directory: %s\\\\n\" \\\n      \"$(_color_primary \"${NB_DIR}\")\"\n  fi\n\n  if [[ -d \"${_GLOBAL_NOTEBOOK_PATH}\" ]]\n  then\n    _exit_1 cat <<HEREDOC\n$(_color_primary \"${_ME}\") already initialized. To initialize a local notebook, use:\n  $(_color_primary \"${_ME} notebooks init\")\nMore Information:\n  $(_color_primary \"${_ME} help notebooks\")\nHEREDOC\n  fi\n\n  _print_welcome                            &&\n    _init_print_header          1>/dev/null &&\n    _init_create_nb_dir         1>/dev/null &&\n    _init_create_rc_file        1>/dev/null &&\n    _validate_configuration     \"${@:-}\"    &&\n    _init_create_home_notebook  \"${@:-}\"\n}\n\n# list · ############################################################### · list\n\n_describe_list() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} list [-e [<length>] | --excerpt [<length>]] [--filenames]\n          [-f | --folders-first] [-n <limit> | --limit <limit> | --<limit>]\n          [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n          [--paths] [-s | --sort] [-r | --reverse] [--tags]\n          [-t <type> | --type <type> | --<type>]\n          [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n\n$(_color_primary \"Options\"):\n  -e, --excerpt [<length>]        Print an excerpt <length> lines long under\n                                  each note's filename [default: 3].\n  --filenames                     Print the filename for each note.\n  -f, --folders-first             Print folders before other items.\n  -n, --limit <limit>, --<limit>  The maximum number of notes to list.\n  --no-id                         Don't include the id in list items.\n  --no-indicator                  Don't include the indicator in list items.\n  -p, --page <number>             The page to view in the list paginated by\n                                  a <limit> option or \\`${_ME} set limit\\`.\n  --pager                         Display output in the pager.\n  --paths                         Print the full path to each item.\n  -s, --sort                      Order notes by id.\n  -r, --reverse                   List items in reverse order.\n  --tags                          List tags in the notebook or folder.\n  -t, --type <type>, --<type>     List items of <type>. <type> can be a file\n                                  extension or one of the following types:\n                                  archive, audio, book, bookmark, document,\n                                  folder, image, note, text, video\n\n$(_color_primary \"Description\"):\n  List notes in the current notebook.\n\n  When <id>, <filename>, <path>, or <title> are present, the listing for the\n  matching note is displayed. When no match is found, titles and filenames\n  are searched for any that match <query> as a case-insensitive regular\n  expression.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#listing--filtering\n\n$(_color_primary \"Indicators\"):\n  ${_NB_INDICATOR_AUDIO:-} Audio\n  ${_NB_INDICATOR_EBOOK:-} Book\n  ${_NB_INDICATOR_BOOKMARK:-} Bookmark\n  ${_NB_INDICATOR_ENCRYPTED:-} Encrypted\n  ${_NB_INDICATOR_FOLDER:-} Folder\n  ${_NB_INDICATOR_IMAGE:-} Image\n  ${_NB_INDICATOR_DOCUMENT:-} PDF, Word, or Open Office document\n  ${_NB_INDICATOR_VIDEO:-} Video\n\n$(_color_primary \"See Also\"):\n  ${_ME} help browse\n  ${_ME} help ls\n  ${_ME} help pin\n  ${_ME} help search\n  ${_ME} help unpin\n\n$(_color_primary \"Examples\"):\n  ${_ME} list\n  ${_ME} list example.md -e 10\n  ${_ME} list --excerpt --no-id\n  ${_ME} list --filenames --reverse\n  ${_ME} list \"^Example.*\"\n  ${_ME} list --10\n  ${_ME} list --type document\n  ${_ME} example:list\nHEREDOC\n}\n_list() {\n  local _error_on_empty=0\n  local _excerpt_length=3\n  local _folders_first=0\n  local _force_line_wrap=0\n  local _limit=\n  local _line_wrap=1\n  local _list_filenames=0\n  local _list_paths=0\n  local _no_id=0\n  local _only_pinned=0\n  local _page=1\n  local _paginate=0\n  local _print_excerpt=0\n  local _print_indicators=1\n  local _print_notebook_selectors=0\n  local _recursive=0\n  local _recursive_arguments=()\n  local _reverse=0\n  local _selector_arguments=()\n  local _sort=0\n  local _type=\n  local _use_pager=0\n  local _with_pinned=0\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      -a|--all)\n        _limit=\n        ;;\n      -e|--excerpt)\n        _print_excerpt=1\n        _recursive_arguments+=(\"--excerpt\")\n\n        if _option_value_is_present \"${2:-}\"\n        then\n          _excerpt_length=\"${2:-}\"\n          _recursive_arguments+=(\"${2:-}\")\n\n          shift\n        fi\n        ;;\n      --*empty)\n        _error_on_empty=1\n        _recursive_arguments+=(\"--error-on-empty\")\n        ;;\n      --filename*)\n        _list_filenames=1\n        _recursive_arguments+=(\"--filenames\")\n        ;;\n      --folders*first|--ff|-ff|--f|-f)\n        _folders_first=1\n        ;;\n      --limit|-n|--num|--number|--per*)\n        if _option_value_is_present \"${2:-}\"\n        then\n          _limit=\"${2:-}\"\n\n          shift\n        fi\n        ;;\n      --no*color)\n        _COLOR_ENABLED=0\n        ;;\n      --no*folders*first|--no*ff|-no*ff|--no*f|-no*f)\n        _folders_first=0\n        ;;\n      --no-id*|--noid*|--no*index)\n        _no_id=1\n        _recursive_arguments+=(\"--no-id\")\n        ;;\n      --no*indicator*|--no*icon*|--no*emoji*|--no*unicode*)\n        _print_indicators=0\n        _recursive_arguments+=(\"--no-indicators\")\n        ;;\n      --no*wrap|--truncate)\n        _line_wrap=0\n        _recursive_arguments+=(\"--no-wrap\")\n        ;;\n      --notebook-selectors)\n        _print_notebook_selectors=1\n        ;;\n      -p|--page)\n        _page=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n        ((_page))               || _page=1\n        [[ -z \"${_limit:-}\" ]]  && _limit=\"${NB_LIMIT}\"\n        _paginate=1\n\n        shift\n        ;;\n      --pager|--less)\n        _use_pager=1\n        ;;\n      --path*)\n        _list_paths=1\n        _recursive_arguments+=(\"--paths\")\n        ;;\n      --pinned)\n        _only_pinned=1\n        _with_pinned=1\n        _recursive_arguments+=(\"--pinned\")\n        ;;\n      --recursive|--tree)\n        _recursive=1\n        ;;\n      -r|--reverse)\n        _reverse=1\n        ;;\n      -s|--sort)\n        _sort=1\n        ;;\n      --tags|--hashtags)\n        _search \"${_selector_arguments[@]:-}\" \"${@:-}\"\n\n        return 0\n        ;;\n      --titles)\n        : # Do nothing. This is the default behavior.\n        ;;\n      -t|--type)\n        _type=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --with*pinned)\n        _with_pinned=1\n        ;;\n      --wrap)\n        _force_line_wrap=1\n        _recursive_arguments+=(\"--wrap\")\n        ;;\n      *)\n        if   [[   \"${1:-}\" =~ ^-+[0-9]+$  ]]\n        then\n          _limit=\"${1##*-}\"\n        elif [[   \"${1:-}\" =~ ^--         ]]\n        then\n          if ! _contains \"${1:-}\" \"--ar\" \"--archived\" \"--unar\" \"--unarchived\"\n          then\n            _type=\"${1:2}\"\n          fi\n        else\n          _selector_arguments+=(\"${1:-}\")\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  local _filter_patterns=()\n  local _folder_relative_path=\n  local _selector=\n  local _selector_basename=\n\n  local __argument=\n  for   __argument in \"${_selector_arguments[@]:-}\"\n  do\n    if [[   -z \"${__argument:-}\"  ]]\n    then\n      continue\n    elif [[ -n \"${_selector:-}\"   ]]\n    then # selector has already been set\n      _filter_patterns+=(\"${__argument}\")\n    elif [[ \"${__argument}\" =~ :$ ]]\n    then # argument appears to be a <notebook>: selector\n      local _selector_notebook_path=\n      _selector_notebook_path=\"$(_notebooks show \"${__argument}\" --path)\"\n\n      if [[ -n \"${_selector_notebook_path:-}\" ]]\n      then\n        _notebooks select \"${_selector_notebook_path}\"\n        _notebook_path=\"${_selector_notebook_path}\"\n\n        _selector=\"${__argument}\"\n      else\n        _filter_patterns+=(\"${__argument}\")\n      fi\n    else\n      local _selector_relative_path=\n      _selector_relative_path=\"$(\n        # resolve selector relative path without a trailing /\n        _selector_resolve_path \"${__argument%\\/}\" --relative\n      )\"\n\n      if [[ \"${__argument:-}\" =~ ^/ ]]\n      then # selector is a full path\n        _selector=\"${__argument}\"\n\n        local _selector_notebook_path=\n        _selector_notebook_path=\"$(\n          _notebooks show \"${__argument}\" --path 2>/dev/null || :\n        )\"\n\n        if [[ -n  \"${_selector_notebook_path:-}\"                        ]] &&\n           [[ -d  \"${_selector_notebook_path:-}\"                        ]] &&\n           [[     \"${_selector_notebook_path:-}\" != \"${_notebook_path}\" ]]\n        then\n          _notebooks select \"${_selector_notebook_path}\"\n          _notebook_path=\"${_selector_notebook_path}\"\n        fi\n\n        if [[ \"${__argument}\" =~ /$ ]] && [[ -d \"${__argument}\"   ]]\n        then\n          _selector_relative_path=\"${_selector_relative_path}/\"\n          _folder_relative_path=\"${_selector_relative_path%\\/*}\"\n          _selector_basename=\"${_selector_relative_path##*\\/}\"\n        elif [[     \"${_selector_relative_path}\" =~ /             ]]\n        then\n          _folder_relative_path=\"${_selector_relative_path%\\/*}\"\n          _selector_basename=\"${_selector_relative_path##*\\/}\"\n        elif [[ -n  \"${_selector_relative_path:-}\"                ]]\n        then\n          _folder_relative_path=\n          _selector_basename=\"${_selector_relative_path}\"\n        elif [[ \"${__argument:-}\" != \"${_notebook_path:-}\"        ]]\n        then\n          _filter_patterns+=(\"${__argument}\")\n        fi\n      elif [[ \"${__argument:-}\" =~ /$                             ]]\n      then\n        if [[ -n \"${_selector_relative_path:-}\"                   ]]\n        then\n          if [[ -d \"${_notebook_path}/${_selector_relative_path}\" ]]\n          then # argument is a folder selector with trailing /\n            _folder_relative_path=\"${_selector_relative_path}\"\n            _selector=\"${__argument}\"\n            _selector_basename=\n          else # argument is a file selector\n            if [[ \"${_selector_relative_path:-}\" =~ /             ]]\n            then # argument is a nested file selector\n              _folder_relative_path=\"${_selector_relative_path%\\/*}\"\n            else # argument does not include a folder\n              _folder_relative_path=\n            fi\n\n            _selector=\"${__argument%\\/}\"\n            _selector_basename=\"${_selector_relative_path##*\\/}\"\n          fi\n        else # argument has a trailing slash and does not match an existing path\n          _filter_patterns+=(\"${__argument}\")\n        fi\n      elif [[ \"${__argument:-}\" =~ /            ]]\n      then\n        if [[ -n \"${_selector_relative_path:-}\" ]]\n        then # argument is a nested file or folder path\n          _folder_relative_path=\"${_selector_relative_path%\\/*}\"\n          _selector=\"${__argument}\"\n          _selector_basename=\"${_selector_relative_path##*\\/}\"\n        else\n          # resolve selector relative path without final path segment\n          _selector_relative_path=\"$(\n            _selector_resolve_path \"${__argument%\\/*}\" --relative\n          )\"\n\n          if [[ -n \"${_selector_relative_path:-}\"                   ]] &&\n             [[ -d \"${_notebook_path}/${_selector_relative_path:-}\" ]]\n          then # folder path is selector, final path segment is filter pattern\n            _folder_relative_path=\"${_selector_relative_path}\"\n            _selector=\"${__argument%\\/*}\"\n            _selector_basename=\n            _selector_relative_path=\"${_folder_relative_path:-}\"\n\n            _filter_patterns+=(\"${__argument##*\\/}\")\n          else # argument does not resolve, treat as filter pattern\n            _filter_patterns+=(\"${__argument}\")\n          fi\n        fi\n      else\n        if [[ -n \"${_selector_relative_path:-}\" ]]\n        then # argument is a root-level file or folder identifier\n          _folder_relative_path=\n          _selector=\"${__argument}\"\n          _selector_basename=\"${_selector_relative_path##*\\/}\"\n        else\n          if [[ \"${__argument:-}\" =~ :          ]]\n          then # argument appears to include notebook selector\n            local _selector_notebook_path=\n            _selector_notebook_path=\"$(\n              _notebooks show \"${__argument%%:*}\" --path || :\n            )\"\n\n            if [[ -n \"${_selector_notebook_path:-}\"                   ]] &&\n               [[ \"${_selector_notebook_path}\" == \"${_notebook_path}\" ]]\n            then # argument notebook selector matches the current notebook\n              _selector=\"${__argument%%:*}\"\n              _filter_patterns+=(\"${__argument#*:}\")\n            else\n              _filter_patterns+=(\"${__argument}\")\n            fi\n          else\n            _filter_patterns+=(\"${__argument}\")\n          fi\n        fi\n      fi\n    fi\n  done\n\n  local _filter_pattern=\n  _filter_pattern=\"$(_join \"|\" \"${_filter_patterns[@]:-}\")\"\n\n  if [[ \"${_selector:-}\" =~ ^[^\\/]+/ ]] && [[ -z \"${_folder_relative_path:-}\" ]]\n  then\n    _warn printf \"Not found: %s\\\\n\" \"$(_color_primary \"${_selector}\")\"\n\n    return 1\n  fi\n\n  local _list_files_options=()\n\n  [[ -n \"${_type:-}\" ]] && _list_files_options+=(\"--type\" \"${_type}\")\n  ((_reverse))          && _list_files_options+=(\"--reverse\")\n  ((_sort))             && _list_files_options+=(\"--sort\")\n\n  local _list_path=\"${_notebook_path}\"\n\n  # context variables\n\n  local _maybe_id_path_context=\n  local _maybe_selector_context=\n\n  if [[ -n \"${_folder_relative_path:-}\"                 ]] &&\n     [[ -e \"${_notebook_path}/${_folder_relative_path}\" ]]\n  then\n    _list_path=\"${_notebook_path}/${_folder_relative_path}\"\n\n    _maybe_id_path_context=\"$(\n      _get_id_selector \"${_folder_relative_path:-}/\"\n    )\"\n\n    _maybe_selector_context=\"${_folder_relative_path:-}/\"\n  fi\n\n  if [[ ! -e \"${_list_path}\" ]]\n  then\n    _exit_1 printf \"Not found: %s\\\\n\" \"$(\n      _color_primary \"${_folder_relative_path:-\"${_selector:-}\"}\"\n    )\"\n  fi\n\n  if _notebooks current --selected || ((_print_notebook_selectors))\n  then\n    local _selected_notebook_name=\n    _selected_notebook_name=\"$(\n      _notebooks show \"${_notebook_path}\" --name --no-color\n    )\"\n\n    _maybe_id_path_context=\"${_selected_notebook_name}:${_maybe_id_path_context:-}\"\n\n    _maybe_selector_context=\"${_selected_notebook_name}:${_maybe_selector_context}\"\n  fi\n\n  # recursive\n\n  # TODO: support --limit and any other loop-dependent features\n\n  _recursive_arguments+=(\"${_list_files_options[@]:-}\")\n\n  if ((_recursive))\n  then\n    {\n      find \"${_list_path}\" -mindepth 1 \\( -name '.*' -prune \\) -o \\( -type d -print \\) | sort\n    } | {\n      local         __folder_path=\n      while read -r __folder_path\n      do\n        [[ -z \"${__folder_path:-}\"                    ]] && continue\n        [[    \"${__folder_path:-}\" == \"${_list_path}\" ]] && continue\n\n        _list \"${__folder_path}/\"         \\\n          \"${_recursive_arguments[@]:-}\"  \\\n          --error-on-empty 2>/dev/null    || :\n      done\n    }\n  fi\n\n  # pinning\n\n  local _pinned_basenames=()\n\n  if ((_with_pinned))\n  then\n    if [[ -f \"${_list_path}/.pindex\"  ]]\n    then\n      _pinned_basenames=($(cat \"${_list_path}/.pindex\"))\n    fi\n\n    # Search-Based Pinning\n    #\n    # Display pinned items first in the list by matching against a pattern\n    # like \"#pinned\". To enable, assign a tag or other pattern to the\n    # $NB_PINNED_PATTERN environment variable.\n    #\n    # Example:\n    #   # file: ~/.nbrc\n    #   export NB_PINNED_PATTERN=\"#pinned\"\n    if [[ -n \"${NB_PINNED_PATTERN:-}\" ]]\n    then\n      _pinned_basenames=($(\n        {\n          printf \"%s\\\\n\" \"${_pinned_basenames[@]:-}\"\n          GIT_PAGER='' git -C \"${_list_path}\"     \\\n            grep                                  \\\n            --color=never                         \\\n            --extended-regexp                     \\\n            --files-with-matches                  \\\n            --ignore-case                         \\\n            --max-depth 0                         \\\n            --text                                \\\n            -e \"${NB_PINNED_PATTERN:-\"#pinned\"}\"  \\\n            \"${_list_path}\" 2>/dev/null || :\n        } | awk '!NF || !seen[$0]++'\n      ))\n    fi\n  fi\n\n  # TODO: External local variables used in pipeline.\n  #\n  # Not affected by list path:\n  #\n  # ${_excerpt_length}\n  # ${_limit}\n  # ${_list_files_options[@]}\n  # ${_with_pinned}\n  #\n  # Affected by list path / selector (Display):\n  #\n  # ${_maybe_selector_context}\n  #\n  # Affected by list path / selector (Logic):\n  #\n  # ${_filter_pattern}\n  # ${_folder_relative_path}\n  # ${_list_path}\n  # ${_maybe_selector_context}\n  # ${_pinned_basenames[@]}\n  # ${_selector_arguments[@]}\n  # ${_selector_basename}\n\n  # Use code blocks to capture all output for piping to pager.\n  {\n    if [[ -n \"${_selector_basename:-}\"        ]] &&\n       [[ \"${#_selector_arguments[@]}\" -le 1  ]]\n    then\n      printf \"%s\\\\n\" \"${_selector_basename}\"\n    else\n      if ((_with_pinned)) && ((${#_pinned_basenames[@]}))\n      then\n        {\n          printf \"%s\\\\n\" \"${_pinned_basenames[@]:-}\"\n        } | {\n          local         __pinned_basename=\n          while read -r __pinned_basename\n          do\n            if [[ -e \"${_list_path:-}/${__pinned_basename:-}\" ]]\n            then\n              printf \"%s\\\\n\" \"${__pinned_basename:-}\"\n            else\n              _sed_i -e \"s/^${__pinned_basename}$//g\" \"${_list_path}/.pindex\"\n              _sed_i -e '/^[[:space:]]*$/d'           \"${_list_path}/.pindex\"\n\n              if [[ ! -s \"${_list_path}/.pindex\"              ]]\n              then\n                rm -f \"${_list_path}/.pindex\"\n              fi\n\n              local _deleted_pin_relative_path=\"${__pinned_basename:-}\"\n\n              if [[ -n \"${_folder_relative_path:-}\"           ]]\n              then\n                _deleted_pin_relative_path=\"${_folder_relative_path}/${__pinned_basename}\"\n              fi\n\n              _git checkpoint \"${_notebook_path}\"                   \\\n                \"[${_ME}] Unpinned: ${_deleted_pin_relative_path}\"\n            fi\n          done\n        } | {\n          _list_files \"${_list_path}\" \"${_list_files_options[@]:-}\" \\\n            --standard-input  || :\n        }\n      fi\n\n      if ! ((_only_pinned))\n      then\n        if ((_folders_first))\n        then\n          _list_files \"${_list_path}\" \"${_list_files_options[@]:-}\" --type folder || :\n\n          {\n            _list_files \"${_list_path}\" \"${_list_files_options[@]:-}\" || :\n          } | {\n            local         __line=\n            while read -r __line\n            do\n              if [[ ! -d \"${_list_path}/${__line}\" ]]\n              then\n                printf \"%s\\\\n\" \"${__line}\"\n              fi\n            done\n          }\n        else\n          _list_files \"${_list_path}\" \"${_list_files_options[@]:-}\" || :\n        fi\n      fi\n    fi\n  } | {\n    LC_ALL=C sed -E \"${_IGNORE_PATTERNS[@]:-}\"\n  } | {\n    local _filenames_count=0\n    local _matches=0\n    local _paginated_count=0\n    local _pagination_max=\"$((_page * _limit))\"\n    local _pagination_min=\"$(((_page * _limit) - _limit))\"\n    local _pinned_basenames_seen=()\n    local _printed_count=0\n\n    local _max_id=\n    _max_id=\"$(_index get_max_id \"${_list_path}\")\"\n\n    if ((_line_wrap))         &&\n       ((_COLOR_ENABLED))     &&\n       ! ((_list_filenames))  &&\n       ! ((_list_paths))      &&\n       ! ((_no_id))           &&\n       ! ((_force_line_wrap))\n    then\n      _line_wrap=0\n    fi\n\n    # begin main loop\n\n    local         __basename=\n    while read -r __basename\n    do\n      [[ -z \"${__basename:-}\" ]] && continue\n\n      _filenames_count=$((_filenames_count+1))\n\n      local _first_line=\n      local _maybe_title=\n      local _title_basename_or_path=\"${__basename}\"\n      local _title_basename_or_path_color=\"${__basename}\"\n\n      if [[ -z \"${_filter_pattern:-}\"                       ]] &&\n         [[ -n \"${_selector_basename:-}\"                    ]] &&\n         [[ \"${__basename}\" != \"${_selector_basename}\"      ]]\n      then\n        continue # exclude from list\n      elif ((_with_pinned)) &&\n           _contains \"${__basename}\" \"${_pinned_basenames_seen[@]:-}\"\n      then\n        continue # exclude from list\n      elif [[ -n \"${_selector_basename}\"                    ]] &&\n           [[ \"${__basename:-}\" == \"${_selector_basename}\"  ]]\n      then\n        # include in list\n        _matches=$((_matches+1))\n      elif [[ -n \"${_filter_pattern:-}\" ]]\n      then\n        # turn on case-insensitive matching\n        shopt -s nocasematch\n\n        if [[ -n \"${_selector_basename}\"                    ]] &&\n           [[ \"${__basename:-}\" == \"${_selector_basename}\"  ]]\n        then\n          # include in list\n          _matches=$((_matches+1))\n        elif [[ ! \"${_filter_pattern}\" =~ ^[0-9][0-9]$      ]] &&\n             [[ \"${__basename:-}\" =~ ${_filter_pattern}     ]]\n        then\n          # include in list\n          _matches=$((_matches+1))\n        else\n          _maybe_title=\"$(_get_content \"${_list_path}/${__basename}\")\"\n\n          if [[ \"${_maybe_title:-}\" =~ ^__first_line:       ]]\n          then\n            _first_line=\"${_maybe_title#__first_line:}\"\n            _maybe_title=\n          fi\n\n          if [[ \"${_maybe_title:-}\" =~ ${_filter_pattern}   ]]\n          then\n            # include in list\n            _matches=$((_matches+1))\n          else\n            continue # exclude from list\n          fi\n        fi\n\n        # turn off case-insensitive matching\n        shopt -u nocasematch\n      fi\n\n      local _pinned=0\n\n      if ((_with_pinned))\n      then\n        if _contains \"${__basename}\" \"${_pinned_basenames[@]:-}\"\n        then\n          _pinned=1\n          _pinned_basenames_seen+=(\"${__basename}\")\n        elif ((_only_pinned))\n        then\n          continue\n        fi\n      fi\n\n      if ((_paginate))\n      then\n        _paginated_count=$((_paginated_count+1))\n\n        if   [[ \"${_paginated_count}\" -le \"${_pagination_min}\"  ]]\n        then\n          continue\n        elif [[ \"${_paginated_count}\" -gt \"${_pagination_max}\"  ]]\n        then\n          break\n        fi\n      fi\n\n      if [[   -n \"${_limit:-}\"                        ]] &&\n         [[      \"${_printed_count}\" -ge \"${_limit}\"  ]]\n      then # the limit has been reached\n        if [[ -n \"${_filter_pattern:-}\"               ]]\n        then\n          # keep looking for matches to count total\n          continue\n        else\n          if ((_only_pinned))\n          then\n            _filenames_count=\"${#_pinned_basenames[@]}\"\n          else\n            _filenames_count=\"$(\n              _count \"${_list_path}\" \"${_list_files_options[@]:-}\"\n            )\"\n          fi\n\n          break\n        fi\n      fi\n\n      if ((_list_paths))\n      then\n        _title_basename_or_path=\"${_list_path}/${__basename}\"\n        _title_basename_or_path_color=\"${_list_path}/${__basename}\"\n      elif ! ((_list_filenames))\n      then\n        if [[ -z \"${_maybe_title}\" ]]\n        then\n          _maybe_title=\"$(_get_content \"${_list_path}/${__basename}\")\"\n        fi\n\n        if [[ -n \"${_maybe_title}\" ]]\n        then\n          if [[ \"${_maybe_title}\" =~ ^__first_line: ]]\n          then\n            _first_line=\"${_maybe_title#__first_line:}\"\n            _maybe_title=\n          else\n            _title_basename_or_path=\"${_maybe_title}\"\n            _title_basename_or_path_color=\"${_maybe_title}\"\n          fi\n        fi\n      fi\n\n      local _extra_length=0\n      local _indicators=\n\n      if ((_print_indicators))\n      then\n        if ((_with_pinned)) && ((_pinned))\n        then\n          _indicators+=\"${_NB_INDICATOR_PINNED:-}\"\n        fi\n\n        # TODO: `show --indicators` duplicated for performance\n        if [[ -d \"${_list_path}/${__basename}\" ]]\n        then\n          _indicators+=\"${_NB_INDICATOR_FOLDER:-}\"\n        elif _file_is_bookmark \"${_list_path}/${__basename}\"\n        then\n          _indicators+=\"${_NB_INDICATOR_BOOKMARK:-}\"\n        elif ! LC_ALL=C _contains \"${__basename##*.}\" \"${_TEXT_FILE_EXTENSIONS[@]}\"\n        then\n          if _file_is_image \"${_list_path}/${__basename}\"\n          then\n            _indicators+=\"${_NB_INDICATOR_IMAGE:-}\"\n          elif _file_is_document \"${_list_path}/${__basename}\"\n          then\n            _indicators+=\"${_NB_INDICATOR_DOCUMENT:-}\"\n          elif _file_is_video \"${_list_path}/${__basename}\"\n          then\n            _indicators+=\"${_NB_INDICATOR_VIDEO:-}\"\n          elif _file_is_audio \"${_list_path}/${__basename}\"\n          then\n            _indicators+=\"${_NB_INDICATOR_AUDIO:-}\"\n          elif [[ \"${__basename}\" =~ \\.epub$ ]]\n          then\n            _indicators+=\"${_NB_INDICATOR_EBOOK:-}\"\n          fi\n        fi\n\n        if _file_is_encrypted \"${_list_path}/${__basename}\"\n        then\n          _indicators+=\"${_NB_INDICATOR_ENCRYPTED:-}\"\n        fi\n\n        if _file_is_todo \"${_list_path}/${__basename}\"\n        then\n          # TODO: review\n          if [[ \"${_title_basename_or_path}\" =~ \\[x\\]\\  ]]\n          then\n            _indicators+=\"${_NB_INDICATOR_TODO_DONE% } \"\n            _extra_length=\"1\"\n          else\n            _indicators+=\"${_NB_INDICATOR_TODO% } \"\n            _extra_length=\"-2\"\n          fi\n\n          if ((_COLOR_ENABLED))\n          then\n            _title_basename_or_path_color=\"\\\n${_title_basename_or_path_color/\\[x\\]/${_TPUT_SETAF_8}[${_TPUT_COLOR_PRIMARY}x${_TPUT_SETAF_8}]${_TPUT_SGR0}}\"\n            _title_basename_or_path_color=\"\\\n${_title_basename_or_path_color/\\[$' '\\]/${_TPUT_SETAF_8}[ ]${_TPUT_SGR0}}\"\n          fi\n        fi\n      fi\n\n      local _item_info=\"${_indicators}${_title_basename_or_path}\"\n      local _item_info_color=\"${_indicators}${_title_basename_or_path_color}\"\n\n      if ! ((_list_filenames))  &&\n         ! ((_list_paths))      &&\n         ! ((_print_excerpt))   &&\n         [[ \"${_title_basename_or_path}\" == \"${__basename}\" ]]\n      then\n        if [[ -n \"${_first_line:-}\" ]]\n        then\n          _item_info=\"${_item_info} ${_MD} \\\"${_first_line}\\\"\"\n          _item_info_color=\"${_item_info_color} ${_MD} \\\"${_first_line}\\\"\"\n        fi\n      fi\n\n      local _info_line=\n      local _info_line_color=\n\n      if ((_no_id))\n      then\n        _info_line=\"${_item_info}\"\n        _info_line_color=\"${_item_info_color}\"\n      else\n        local _escaped_basename=\"${__basename}\"\n        _escaped_basename=\"${_escaped_basename//\\[/\\\\\\[}\"\n        _escaped_basename=\"${_escaped_basename//\\]/\\\\\\]}\"\n\n        local _item_id=\n        # use `sed` directly instead of `_index get_id` for performance\n        _item_id=\"$(LC_ALL=C sed -n \"/^${_escaped_basename:-}$/=\" \"${_list_path:-}/.index\")\"\n\n        if [[ -z \"${_item_id:-}\" ]]\n        then\n          _index reconcile \"${_list_path:-}\" --ancestors --commit\n\n          _item_id=\"$(LC_ALL=C sed -n \"/^${_escaped_basename:-}$/=\" \"${_list_path:-}/.index\")\"\n        fi\n\n        local _item_identifier=\"${_maybe_selector_context:-}${_item_id:-}\"\n        local _max_identifier=\"${_maybe_selector_context:-}${_max_id:-}\"\n\n        local _brackets_identifier=\"[${_item_identifier:-}]\"\n        # avoid calling `_color_brackets` for performance\n        local _brackets_identifier_color=\"\\\n${_TPUT_SGR0}\\\n${_TPUT_SETAF_8}\\\n[\\\n${_TPUT_COLOR_PRIMARY}\\\n${_item_identifier:-}\\\n${_TPUT_SETAF_8}\\\n]\\\n${_TPUT_SGR0}\"\n\n        # use calculated number of spaces for nicer formatting\n        local _spaces_length=\n        _spaces_length=$(( ${#_max_identifier} - ${#_item_identifier} + 1 ))\n\n        local _spaces=\n        printf -v _spaces '%*s' \"${_spaces_length}\" \"\"\n\n        _info_line=\"${_brackets_identifier}${_spaces}${_item_info}\"\n        _info_line_color=\"${_brackets_identifier_color}${_spaces}${_item_info_color}\"\n      fi\n\n      if ! ((_line_wrap))\n      then\n        _wrap off\n      fi\n\n      if ((_COLOR_ENABLED))\n      then\n        printf \"%s\" \"${_info_line_color}\"\n      else\n        printf \"%s\" \"${_info_line}\"\n      fi\n\n      if ! ((_line_wrap))\n      then\n        _wrap on\n      fi\n\n      # end of line\n      printf \"\\\\n\"\n\n      if ((_print_excerpt))                   &&\n         [[ \"${_excerpt_length}\" =~ ^[0-9] ]] &&\n         _file_is_text \"${_list_path}/${__basename}\"\n      then # excerpt is specified with a non-zero digit, required by `head`\n        _print_line \"${_info_line:-}\"         \\\n          --no-wrap                           \\\n          --visible-length \"${_extra_length:-0}\"\n\n        if ((${_excerpt_length:-0}))\n        then\n          head -n \"${_excerpt_length}\" \"${_list_path}/${__basename}\" \\\n            | _highlight_syntax_if_available \"${__basename##*.}\"\n\n          printf \"\\\\n\"\n        fi\n      fi\n\n      _printed_count=$((_printed_count+1))\n    done\n\n    # end main loop\n\n    if [[   -n \"${_limit:-}\"          ]] && ! ((_paginate))\n    then\n      if [[ -n \"${_filter_pattern:-}\" ]]\n      then\n        if [[ \"${_matches:-0}\"    -gt \"${_limit}\" ]] &&\n           [[ \"${_printed_count}\" -ge \"${_limit}\" ]]\n        then\n          local _label=\"matches\"\n          local _omitted_count=\n          _omitted_count=$((_matches-_printed_count))\n\n          [[ \"${_omitted_count}\" -eq 1 ]] && _label=\"match\"\n\n          printf \"%s %s omitted. %s total.\\\\n\"    \\\n            \"${_omitted_count}\"                   \\\n            \"${_label}\"                           \\\n            \"${_matches}\"\n\n          return 0\n        fi\n      elif [[ \"${_filenames_count}\" -gt \"${_limit}\" ]] &&\n           [[ \"${_printed_count}\"   -ge \"${_limit}\" ]]\n      then\n        printf \"%s omitted. %s total.\\\\n\"         \\\n          \"$((_filenames_count-_printed_count))\"  \\\n          \"${_filenames_count}\"\n\n        return 0\n      fi\n    fi\n\n    if ! ((_printed_count)) && [[ -n \"${_filter_pattern:-}\"   ]]\n    then\n      local _filter_message=\n\n      if _notebooks current --selected\n      then\n        _filter_message=\"$(_color_primary \"$(_notebooks current):\")\"\n      fi\n\n      if [[ -n \"${_folder_relative_path:-}\"     ]]\n      then\n        _filter_message=\"${_filter_message}$(_color_primary \"${_folder_relative_path}/\")\"\n      fi\n\n      if [[ -n \"${_filter_message:-}\"           ]]\n      then\n        _filter_message=\"${_filter_message} \"\n      fi\n\n      _filter_message=\"${_filter_message}$(_color_primary \"${_filter_pattern:-}\")\"\n\n      if [[ -n \"${_type:-}\"                     ]]\n      then\n         _filter_message=\"${_filter_message} Type: $(_color_primary \"${_type}\")\"\n      fi\n\n      _warn printf \"Not found: %s\\\\n\" \"${_filter_message}\"\n\n      return 1\n    fi\n\n    if ! ((_filenames_count)) && [[ -z \"${_filter_pattern:-}\" ]]\n    then\n      {\n        local _maybe_id_path_context_padded_left=\n        local _maybe_id_path_context_padded_right=\n\n        if [[ -n \"${_maybe_id_path_context:-}\"  ]]\n        then\n          _maybe_id_path_context=\"${_maybe_id_path_context//' '/\\\\ }\"\n          _maybe_id_path_context_padded_left=\" ${_maybe_id_path_context:-}\"\n          _maybe_id_path_context_padded_right=\"${_maybe_id_path_context:-} \"\n        fi\n\n        if [[ \"${_type}\" =~ (^bookmark$|^bookmarks$)    ]]\n        then\n          cat <<HEREDOC\n0 bookmarks.\n\nAdd a bookmark:\n  $(_color_primary \"${_ME} ${_maybe_id_path_context_padded_right:-}<url>\")\nHelp information:\n  $(_color_primary \"${_ME} help bookmark\")\nHEREDOC\n        elif [[ \"${_type}\" =~ (^todo$|^todos$)          ]]\n        then\n          cat <<HEREDOC\n0 todos.\n\nAdd a todo:\n  $(_color_primary \"${_ME} todo add${_maybe_id_path_context_padded_left:-} <title>\")\nHelp information:\n  $(_color_primary \"${_ME} help todo\")\nHEREDOC\n        elif [[ -n \"${_type:-}\" ]] || ((_only_pinned))\n        then\n          if _contains \"${_type}\" \"bookmarks\" \"documents\" \"images\" \"videos\" \"folders\"\n          then\n            _type=\"$(printf \"%s\\\\n\" \"${_type}\" | sed -e 's/s$//')\"\n          fi\n\n          if ((_only_pinned))\n          then\n            cat <<HEREDOC\n0 pinned ${_type:+\"${_type} \"}items.\n\nPin an item:\n  $(_color_primary \"${_ME} pin ${_maybe_id_path_context:-}<id>\")\nHelp information:\n  $(_color_primary \"${_ME} help\")\nHEREDOC\n          else\n            if [[ \"${_type:-}\" =~ (^folder$|^folders$)  ]]\n            then\n              local _empty_type_label=\"folders\"\n            else\n              local _empty_type_label=\"${_type} items\"\n            fi\n\n            cat <<HEREDOC\n0 ${_empty_type_label}.\n\nImport a file:\n  $(_color_primary \"${_ME} import (<path> | <url>)${_maybe_id_path_context_padded_left:-}\")\nHelp information:\n  $(_color_primary \"${_ME} help import\")\nHEREDOC\n          fi\n        else\n          cat <<HEREDOC\n0 items.\n\nAdd a note:\n  $(_color_primary \"${_ME} add${_maybe_id_path_context_padded_left:-}\")\nAdd a bookmark:\n  $(_color_primary \"${_ME} ${_maybe_id_path_context_padded_right:-}<url>\")\nAdd a todo:\n  $(_color_primary \"${_ME} todo add${_maybe_id_path_context_padded_left:-} <title>\")\nImport a file:\n  $(_color_primary \"${_ME} import (<path> | <url>)${_maybe_id_path_context_padded_left:-}\")\nHelp information:\n  $(_color_primary \"${_ME} help\")\nHEREDOC\n        fi\n      } | {\n        if ((_error_on_empty))\n        then\n          cat 1>&2\n\n          return 1\n        else\n          cat\n\n          return 0\n        fi\n      }\n    fi\n  } | if ((_use_pager))\n      then\n        _pager\n      else\n        cat\n      fi\n}\n\n# ls · ################################################################### · ls\n\n_describe_ls() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} ls [-a | --all] [-b | --browse] [-e [<length>] | --excerpt [<length>]]\n        [--filenames] [-f | --folders-first] [-g | --gui]\n        [-n <limit> | --limit <limit> | --<limit>] [--no-footer] [--no-header]\n        [--no-id] [--no-indicator] [-p <number> | --page <number>] [--pager]\n        [--paths] [-s | --sort] [-r | --reverse] [--tags]\n        [-t <type> | --type <type> | --<type>]\n        [<notebook>:][<folder-path>/][<id> | <filename> | <path> | <query>]\n\n$(_color_primary \"Options\"):\n  -a, --all                       Print all items in the notebook. Equivalent\n                                  to no limit.\n  -b, --browse                    Open the specified item or current notebook\n                                  with \\`browse\\` in a terminal web browser.\n  -e, --excerpt [<length>]        Print an excerpt <length> lines long under\n                                  each note's filename [default: 3].\n  --filenames                     Print the filename for each note.\n  -f, --folders-first             Print folders before other items.\n  -g, --gui                       Open the specified item or current notebook\n                                  with \\`browse\\` in a GUI web browser.\n  -n, --limit <limit>, --<limit>  The maximum number of listed items.\n                                  [default: 15]\n  --no-footer                     Print without footer.\n  --no-header                     Print without header.\n  --no-id                         Don't include the id in list items.\n  --no-indicator                  Don't include the indicator in list items.\n  -p, --page <number>             The page to view in the list paginated by\n                                  a <limit> option or \\`${_ME} set limit\\`.\n  --pager                         Display output in the pager.\n  --paths                         Print the full path to each item.\n  -s, --sort                      Order notes by id.\n  -r, --reverse                   List items in reverse order.\n  --tags                          List tags in the notebook or folder.\n  -t, --type <type>, --<type>     List items of <type>. <type> can be a file\n                                  extension or one of the following types:\n                                  note, book, bookmark, document, archive,\n                                  image, video, audio, folder, text\n\n$(_color_primary \"Description\"):\n  List notebooks and notes in the current notebook, displaying note titles\n  when available. \\`${_ME} ls\\` is a combination of \\`${_ME} notebooks\\` and\n  \\`${_ME} list\\` in one view.\n\n  When <id>, <filename>, <path>, or <title> are present, the listing for the\n  matching note is displayed. When no match is found, titles and filenames\n  are searched for any that match <query> as a case-insensitive regular\n  expression.\n\n  Options are passed through to \\`list\\`. For more information, see\n  \\`${_ME} help list\\`.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#listing--filtering\n\n$(_color_primary \"Indicators\"):\n  ${_NB_INDICATOR_AUDIO:-} Audio\n  ${_NB_INDICATOR_EBOOK:-} Book\n  ${_NB_INDICATOR_BOOKMARK:-} Bookmark\n  ${_NB_INDICATOR_ENCRYPTED:-} Encrypted\n  ${_NB_INDICATOR_FOLDER:-} Folder\n  ${_NB_INDICATOR_IMAGE:-} Image\n  ${_NB_INDICATOR_DOCUMENT:-} PDF, Word, or Open Office document\n  ${_NB_INDICATOR_VIDEO:-} Video\n\n$(_color_primary \"See Also\"):\n  ${_ME} help browse\n  ${_ME} help list\n  ${_ME} help pin\n  ${_ME} help search\n  ${_ME} help unpin\n\n$(_color_primary \"Examples\"):\n  ${_ME}\n  ${_ME} --all\n  ${_ME} ls\n  ${_ME} ls example.md -e 10\n  ${_ME} ls --excerpt --no-id\n  ${_ME} ls --reverse\n  ${_ME} ls \"^Example.*\"\n  ${_ME} ls --10\n  ${_ME} ls --type document\n  ${_ME} example:\n  ${_ME} example: -ae\n  ${_ME} example:ls\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME}\nHEREDOC\n}\n_ls() {\n  # _ls_print_footer()\n  #\n  # Usage:\n  #   _ls_print_footer [<selector>]\n  _ls_print_footer() {\n    local _footer_line_hi=\n    local _footer_line_raw=\n    local _footer_separator_raw=\" ${_MD}\"\n    local _footer_test_line=\n    local _maybe_notebook=\n    local _maybe_selector_scope=\n    local _maybe_selector_scope_padded_left=\n    local _maybe_selector_scope_padded_right=\n    local _selector_path=\"${1:-}\"\n\n    local _footer_separator_hi=\n    _footer_separator_hi=\"$(_color_primary \"${_footer_separator_raw}\")\"\n\n    if _notebooks current --selected\n    then\n      _maybe_notebook=\"$(\n        _notebooks show \"$(_notebooks current)\" --escaped --no-color\n      ):\"\n    fi\n\n    local _folder_id_path=\n    _folder_id_path=\"$(_get_id_selector \"${_selector_path:-}\")\"\n\n    if [[ -n \"${_maybe_notebook:-}\" ]] ||\n       [[ -n \"${_folder_id_path:-}\" ]]\n    then\n      _maybe_selector_scope=\"${_maybe_notebook}${_folder_id_path}\"\n      _maybe_selector_scope_padded_left=\" ${_maybe_selector_scope}\"\n      _maybe_selector_scope_padded_right=\"${_maybe_selector_scope} \"\n    fi\n\n    local _notebook_command=\"${_ME} notebooks add <name>\"\n\n    local _unarchived_notebook_count=0\n\n    set +f\n    local __path=\n    for   __path in \"${NB_DIR}\"/*\n    do\n      if [[ ! -f \"${__path:?}/.archived\"          ]]\n      then\n        _unarchived_notebook_count=$((_unarchived_notebook_count + 1))\n      fi\n\n      if [[ \"${_unarchived_notebook_count}\" -gt 1 ]]\n      then\n        if [[ -n \"${_maybe_notebook:-}\"           ]]\n        then\n          _notebook_command=\"${_ME} use ${_maybe_notebook%%:*}\"\n        else\n          _notebook_command=\"${_ME} use <notebook>\"\n        fi\n\n        break\n      fi\n    done\n    set -f\n\n    local _commands_raw=(\n      \"${_CHEVRON_RIGHT} ${_ME}${_maybe_selector_scope_padded_left}\"\n      \"${_ME} add${_maybe_selector_scope_padded_left}\"\n      \"${_ME} ${_maybe_selector_scope_padded_right}<url>\"\n      \"${_ME} edit ${_maybe_selector_scope}<id>\"\n      \"${_ME} show ${_maybe_selector_scope}<id>\"\n      \"${_ME} open ${_maybe_selector_scope}<id>\"\n      \"${_ME} browse${_maybe_selector_scope_padded_left}\"\n      \"${_ME} todos${_maybe_selector_scope_padded_left}\"\n      \"${_ME} tasks${_maybe_selector_scope_padded_left}\"\n      \"${_ME} search ${_maybe_selector_scope_padded_right}<query>\"\n      \"${_notebook_command}\"\n      \"${_ME} settings\"\n      \"${_ME} help\"\n    )\n\n    local _commands_hi=(\n      \"$(_color_muted \"${_CHEVRON_RIGHT}\") $(_color_secondary \"${_ME}${_maybe_selector_scope_padded_left}\")\"\n      \"$(_color_secondary \"${_commands_raw[1]}\")\"\n      \"$(_color_secondary \"${_commands_raw[2]}\")\"\n      \"$(_color_secondary \"${_commands_raw[3]}\")\"\n      \"$(_color_secondary \"${_commands_raw[4]}\")\"\n      \"$(_color_secondary \"${_commands_raw[5]}\")\"\n      \"$(_color_secondary \"${_commands_raw[6]}\")\"\n      \"$(_color_secondary \"${_commands_raw[7]}\")\"\n      \"$(_color_secondary \"${_commands_raw[8]}\")\"\n      \"$(_color_secondary \"${_commands_raw[9]}\")\"\n      \"$(_color_secondary \"${_commands_raw[10]}\")\"\n      \"$(_color_secondary \"${_commands_raw[11]}\")\"\n      \"$(_color_secondary \"${_commands_raw[12]}\")\"\n    )\n\n    _wrap off\n\n    _print_line \"$(printf \"%-${_COLUMNS}s\" '.')\" | tr -d '\\n'\n\n    printf \"%s\" \"${_TPUT_SGR0}\"\n\n    _wrap on\n\n    printf \"\\\\n\"\n\n    local i=\n    for ((i=0; i < ${#_commands_raw[@]}; i++))\n    do\n      if [[ -z \"${_footer_test_line}\"                 ]]\n      then # first item in line\n        _footer_test_line=\"${_commands_raw[i]}\"\n      else\n        _footer_test_line=\"${_footer_test_line}${_footer_separator_raw} ${_commands_raw[i]}\"\n      fi\n\n      if [[ \"${#_footer_test_line}\" -gt \"${_COLUMNS}\" ]]\n      then # wrap to next line\n        printf \"%s\\\\n\" \"${_footer_line_hi}\"\n\n        # Start the line for the next iteration using the current name.\n        _footer_test_line=\"${_commands_raw[i]}\"\n        _footer_line_hi=\"${_commands_hi[i]:-}\"\n        _footer_line_raw=\"${_commands_raw[i]}\"\n      else # add to line\n        if [[ -z \"${_footer_line_hi}\" ]]\n        then # first item in highlighted line\n          _footer_line_hi=\"${_commands_hi[i]:-}\"\n          _footer_line_raw=\"${_commands_raw[i]}\"\n        else\n          _footer_line_hi=\"${_footer_line_hi}${_footer_separator_hi} ${_commands_hi[i]:-}\"\n          _footer_line_raw=\"${_footer_line_raw}${_footer_separator_raw} ${_commands_raw[i]}\"\n        fi\n      fi\n\n      if [[ \"${#_commands_raw[@]}\" == $((i+1))        ]]\n      then # end of list\n        printf \"%s\\\\n\" \"${_footer_line_hi}\"\n      fi\n    done\n  }\n\n  # _ls_print_folder_header()\n  #\n  # Usage: _ls_print_folder_header <folder-path>\n  _ls_print_folder_header() {\n    [[ -z \"${1:-}\" ]] && return 0\n\n    # printf \"${_NB_INDICATOR_FOLDER:-}\" # TODO: Review\n\n    local _folder_separator=\n    _folder_separator=\"$(_color_muted \"/\")\"\n\n    printf \"%s\\\\n\" \"${1//\\// ${_folder_separator} }\"\n\n    _print_line \"$(printf \"%-${_COLUMNS}s\" '.')\" --muted\n\n    printf \"\\\\n\"\n  }\n\n  # _ls_print_header()\n  #\n  # Usage:\n  #   _ls_print_header <alignment>\n  #\n  # Description:\n  #   Build word-wrapping notebook line. `fold` doesn't account for\n  #   highlighting.\n  #\n  #   Simple version:\n  #     _notebooks --names            \\\n  #       | tr '\\n' ' '               \\\n  #       | fold -s \"-w$(tput cols)\"  \\\n  #       && printf \"\\\\n\"\n  _ls_print_header() {\n    local _alignment=\"${1:-}\"\n    local _auto_align=1 # auto-align by default.\n    local _centered=0\n    local _justified=0\n    local _plain=0\n\n    [[ \"${NB_HEADER}\" == 2 ]] && _centered=1\n    [[ \"${NB_HEADER}\" == 3 ]] && _justified=1\n\n    case \"${_alignment}\" in\n      --auto*align)\n        _auto_align=1\n        _centered=0\n        _justified=0\n        ;;\n      --centered)\n        _auto_align=0\n        _centered=1\n        _justified=0\n        ;;\n      --justified)\n        _auto_align=0\n        _centered=0\n        _justified=1\n        ;;\n      --plain)\n        _plain=1\n        ;;\n    esac\n\n    local _separator=\n    local _separator_hi=\n\n    if ! ((_plain))\n    then\n      _separator=\" ${_MD}\"\n      _separator_hi=\"$(_color_muted \"${_separator}\")\"\n    fi\n\n    local _current_notebook_name=\n    _current_notebook_name=\"$(_notebooks current)\"\n\n    local _highlight_archived=0\n\n    if [[ -e \"${NB_NOTEBOOK_PATH:-}/.archived\" ]]\n    then\n      _highlight_archived=1\n    fi\n\n    {\n      local _archived_count=0\n      local _unarchived_notebook_names=()\n\n      set +f\n      local __path=\n      for   __path in \"${NB_DIR}\"/*\n      do\n        if [[ -f \"${__path:?}/.archived\" ]]\n        then\n          _archived_count=$((_archived_count+1))\n        else\n          _unarchived_notebook_names+=(\"${__path##*\\/}\")\n        fi\n      done\n      set -f\n\n      if _notebooks current --local\n      then\n        printf \"local\\\\n\"\n      fi\n\n      printf \"%s\\\\n\" \"${_unarchived_notebook_names[@]:-}\"\n\n      if ((_archived_count))\n      then\n        printf \"[%s archived]\\\\n\" \"${_archived_count}\"\n      fi\n    } | {\n      local _line_hi=\n      local _line_number=0\n      local _line_raw=\n      local _output_line_raw=\n      local _padding=\n      local _test_line=\n\n      local         __header_name=\n      while read -r __header_name\n      do\n        local _maybe_highlighted_notebook_name=\n\n        if [[ \"${_current_notebook_name}\" == \"${__header_name}\" ]] ||\n           {\n             ((_highlight_archived))                               &&\n             [[ \"${__header_name:-}\"      =~ ^\\[.*\\]            ]]\n           }\n        then\n          _maybe_highlighted_notebook_name=\"$(\n            _color_primary \"${__header_name:-}\" --underline\n          )\"\n        else\n          _maybe_highlighted_notebook_name=\"${__header_name:-}\"\n        fi\n\n        if [[ -z \"${_test_line}\"                  ]]\n        then # first item in line\n          _test_line=\"${__header_name}\"\n        else\n          _test_line=\"${_test_line}${_separator} ${__header_name}\"\n        fi\n\n        if [[ \"${#_test_line}\" -gt \"${_COLUMNS}\"  ]]\n        then # wrap to next line\n          # Use the existing value of $_line_[highlighted|raw] without the\n          # current name.\n          if ((_auto_align)) || ((_centered)) && ! ((_justified))\n          then\n            _centered=1\n            _padding=\"$(\n              _print_padding \"${_line_raw}\" \"${_COLUMNS}\" \"${_centered}\"\n            )\"\n          fi\n\n          printf \"%s%s%s\\\\n\" \"${_TPUT_SGR0}\" \"${_padding:-}\" \"${_line_hi:-}\"\n          _output_line_raw=\"${_padding}${_line_raw}\\\\n\"\n          _line_number=$((_line_number + 1))\n\n          # Start the line for the next iteration using the current name.\n          _test_line=\"${__header_name}\"\n          _line_hi=\"${_maybe_highlighted_notebook_name:-}\"\n          _line_raw=\"${__header_name}\"\n        else # add to line\n          if [[ -z \"${_line_hi}\"                  ]]\n          then # first item in highlighted line\n            _line_hi=\"${_maybe_highlighted_notebook_name:-}\"\n            _line_raw=\"${__header_name}\"\n          else\n            _line_hi=\"${_line_hi}${_separator_hi} ${_maybe_highlighted_notebook_name:-}\"\n            _line_raw=\"${_line_raw}${_separator} ${__header_name}\"\n          fi\n        fi\n      done\n\n      if ((_line_number))  && ! ((_justified)) &&\n         ((_auto_align))   ||   ((_centered))\n      then\n        _centered=1\n      fi\n\n      _padding=\"$(\n        _print_padding \"${_line_raw}\" \"${_COLUMNS}\" \"${_centered}\"\n      )\"\n\n      printf \"%s%s%s\\\\n\" \"${_TPUT_SGR0}\" \"${_padding:-}\" \"${_line_hi:-}\"\n      _output_line_raw=\"${_padding}${_line_raw}\\\\n\"\n\n      _wrap off\n\n      if ((_centered))\n      then # print full-width line.\n        _print_line \"$(printf \"%-${_COLUMNS}s\" '.')\" | tr -d '\\n'\n      else # print line the length of the first line.\n        _print_line \"$(\n          # $_output_line_raw content is 2 characters too long. TODO: Review\n          printf \"%s\" \"${_output_line_raw}\" | LC_ALL=C sed 's/..$//'\n        )\" | tr -d '\\n'\n      fi\n\n      printf \"%s\" \"${_TPUT_SGR0}\"\n\n      _wrap on\n\n      printf \"\\\\n\"\n    }\n  }\n\n  local _all=0\n  local _arguments=()\n  local _delegate_to_browse=0\n  local _delegate_arguments=()\n  local _fast_exit=0\n  local _filter_patterns=()\n  local _folders_first=\"${NB_FOLDERS_FIRST:-0}\"\n  local _header_flags=()\n  local _limit=\n  local _maybe_type=\n  local _selector=\n  local _selector_folder_path=\n  local _use_pager=0\n  local _with_pinned=1\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      --added*|--created*|--updated*|--ar|--archived|--unar|--unarchived)\n        _delegate_arguments+=(\"${1}\")\n        ;;\n      -a|--all)\n        _all=1\n        ;;\n      --auto*align|--centered|--justified|--plain)\n        _header_flags+=(\"${1}\")\n        ;;\n      -b|--browse)\n        _delegate_to_browse=1\n        ;;\n      --content|--title)\n        if _option_value_is_present \"${2:-}\"\n        then\n          _delegate_arguments+=(\"${1}\" \"${2:-}\")\n\n          shift\n        fi\n        ;;\n      --*exit*)\n        _fast_exit=1\n        ;;\n      --folders-first|--ff|-ff|--f|-f)\n        _folders_first=1\n        ;;\n      -g|--gui)\n        _delegate_to_browse=1\n        _delegate_arguments+=(\"${1}\")\n        ;;\n      --limit|-n|--num|--number|--per*)\n        _limit=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --pager|--less)\n        _use_pager=1\n        ;;\n      -l)\n        : # Ignore accidental ls -l  due to muscle memory.\n        ;;\n      --no*folders*first|--no*ff|-no*ff|--no*f|-no*f)\n        _folders_first=0\n        ;;\n      --no*footer)\n        NB_FOOTER=0\n        ;;\n      --no*header)\n        NB_HEADER=0\n        ;;\n      -s|--sort|-r|--reverse)\n        _arguments+=(\"${1}\")\n        _with_pinned=0\n        ;;\n      --tag*)\n        _delegate_arguments+=(\"${1}\")\n\n        if _option_value_is_present \"${2:-}\"\n        then\n          _delegate_arguments+=(\"${2:-}\")\n\n          shift\n        fi\n        ;;\n      -t|--type)\n        _maybe_type=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n        _arguments+=(\"${1}\" \"${2:-}\")\n\n        shift\n        ;;\n      --[A-Za-z]*)\n        _maybe_type=\"${1:2}\"\n\n        _arguments+=(\"${1}\")\n        ;;\n      -*)\n        if [[ \"${1:-}\" =~ ^-+[0-9]+$  ]]\n        then\n          _limit=\"${1##*-}\"\n        else\n          _arguments+=(\"${1}\")\n\n          if _option_value_is_present \"${2:-}\"\n          then\n            _arguments+=(\"${2:-}\")\n\n            shift\n          fi\n        fi\n        ;;\n      \\#*)\n        _delegate_arguments+=(--tag \"${1}\")\n        ;;\n      *:*)\n        local _selector_id=\n        _selector_id=\"$(_selector_get_identifier \"${1}\")\"\n\n        if [[ -n \"${_selector_id:-}\"  ]]\n        then\n          _arguments+=(\"${_selector_id}\")\n        fi\n\n        _selector=\"${1:-}\"\n        _filter_patterns+=(\"${1}\")\n        ;;\n      *)\n        if [[ -z \"${_selector:-}\"     ]]\n        then\n          _selector=\"${1}\"\n        fi\n\n        _arguments+=(\"${1}\")\n        _filter_patterns+=(\"${1}\")\n        ;;\n    esac\n\n    shift\n  done\n\n  # Delegate to `add`, `show`, and other subcommands.\n\n  if ((${#_delegate_arguments[@]})) || ((_delegate_to_browse))\n  then\n    if ((_delegate_to_browse))\n    then\n      _defer \"_browse\" \"${_arguments[@]:-}\" \"${_delegate_arguments[@]:-}\"\n\n      return 0\n    else\n      local i=\n      for ((i=0; i < ${#_delegate_arguments[@]}; i++))\n      do\n        case \"${_delegate_arguments[i]:-}\" in\n          --ar*|--unar*)\n            _defer \"_notebooks\" list \"${_delegate_arguments[@]:-}\"\n\n            return 0\n            ;;\n          --added*|--created*|--updated*)\n            if [[ -n \"${_selector:-}\"     ]]\n            then\n              _defer \"_show\" \"${_arguments[@]:-}\" \"${_delegate_arguments[@]:-}\"\n\n              return 0\n            fi\n            ;;\n          --content|--title)\n            if _option_value_is_present \"${_delegate_arguments[$((i+1))]:-}\"\n            then\n              _defer \"_add\" \"${_arguments[@]:-}\" \"${_delegate_arguments[@]:-}\"\n\n              return 0\n            fi\n            ;;\n          --tag*)\n            ((_all)) && _delegate_arguments+=(\"--all\")\n            _defer \"_search\"                \\\n              \"${_arguments[@]:-}\"          \\\n              \"${_delegate_arguments[@]:-}\" \\\n              --list\n\n            return 0\n            ;;\n          *)\n            if [[ -n \"${_arguments[i]:-}\" ]]\n            then\n              _arguments+=(\"${_arguments[i]:-}\")\n            fi\n            ;;\n        esac\n      done\n    fi\n  fi\n\n  # Build list options.\n\n  local _list_options=(${_arguments[@]:-})\n\n  if ((_with_pinned))\n  then\n    _list_options+=(\"--with-pinned\")\n  fi\n\n  if ((_folders_first))\n  then\n    _list_options+=(\"--folders-first\")\n  fi\n\n  local _selector_relative_path=\"${_selector#*:}\"\n\n  if [[ -n \"${_limit:-}\"                            ]]\n  then\n    _list_options+=(\"--limit\" \"${_limit}\")\n  elif ! ((_all))                                       &&\n       [[ -z \"${_AUTO_LIMIT:-}\"                     ]]  &&\n       {\n         [[ -z \"${_selector_relative_path:-}\"       ]]  ||\n         {\n           [[ \"${_selector_relative_path:-}\" =~ /   ]]  &&\n           [[ -z \"${_selector_relative_path##*\\/}\"  ]]  &&\n           [[ \"${#_filter_patterns[@]}\" -le 1       ]]\n         }\n       }\n  then\n    _list_options+=(\"--limit\" \"${NB_LIMIT}\")\n  fi\n\n  # Resolve selector folders before printing header to minimize pause\n  # before printing list.\n\n  if [[ \"${_selector:-}\" =~ /             ]]\n  then\n    _selector_folder_path=\"$(_selector_resolve_folders \"${_selector}\" || :)\"\n\n    if [[ -n \"${_selector_folder_path:-}\" ]]\n    then\n      _selector_folder_path=\"${_selector_folder_path}/\"\n    fi\n  fi\n\n  # Determine whether to display header and footer.\n\n  local _display_header_and_footer=0\n\n  if [[ -z \"${_arguments[*]:-}\"           ]]  ||\n     {\n       [[ \"${_selector:-}\" =~ (/$|:$)     ]]  &&\n       [[ -n \"${_selector_folder_path:-}\" ]]  &&\n       [[ \"${#_arguments[@]}\" -le 1       ]]\n     }\n  then\n    _display_header_and_footer=1\n  fi\n\n  # Pre-load auto --limit header and footer.\n\n  local _footer=\n  local _header=\n\n  if [[ -n \"${_AUTO_LIMIT:-}\"             ]]  &&\n     ! ((_all))                               &&\n     ! _contains \"--limit\" \"${_list_options[@]:-}\"\n  then\n    local _available_lines=0\n    _available_lines=\"$(_tput lines)\"\n\n    local _header_and_footer_line_count=0\n\n    if ((NB_HEADER)) && ((_display_header_and_footer))\n    then\n      _header=\"$(_ls_print_header \"${_header_flags[@]:-}\")\"\n    fi\n\n    if ((NB_FOOTER)) && ((_display_header_and_footer))\n    then\n      _footer=\"$(_ls_print_footer \"${_selector_folder_path:-}\")\"\n    fi\n\n    local _header_and_footer_line_count=0\n    _header_and_footer_line_count=\"$(\n      {\n        [[ -n \"${_header:-}\" ]] && printf \"%s\\\\n\" \"${_header:-}\"\n        [[ -n \"${_footer:-}\" ]] && printf \"%s\\\\n\" \"${_footer:-}\"\n\n        printf \"\"\n      } | wc -l | xargs\n    )\"\n\n    local _auto_limit_adjustment=\"$((_AUTO_LIMIT - 2))\"\n    local _auto_limit_amount=1\n\n    _auto_limit_amount=\"$((\n      ${_available_lines:-1}                -\n        ${_header_and_footer_line_count:-0} +\n        ${_auto_limit_adjustment:-0}\n    ))\"\n\n    [[ \"${_auto_limit_amount}\" -gt 0 ]] || _auto_limit_amount=1\n\n    if [[ -n \"${_AUTO_LIMIT_MAX:-}\"  ]] &&\n       [[    \"${_AUTO_LIMIT_MAX:-}\" -lt \"${_auto_limit_amount:-1}\" ]]\n    then\n      _auto_limit_amount=\"${_AUTO_LIMIT_MAX}\"\n    fi\n\n    _list_options+=(\"--limit\" \"${_auto_limit_amount:-1}\")\n  fi\n\n  local _list_error=\n\n  # NOTE: Pipeline structured to start List, Header, and Footer concurrently.\n  {\n    # List\n    # ----\n    {\n      # Capture error to variable while preserving standard output. More info:\n      # https://unix.stackexchange.com/a/474195\n      _list_error=\"$(\n        _list --error-on-empty \"${_list_options[@]:-}\" 2>&1 >&3 3>&-\n      )\"\n    } 3>&1 || {\n      if [[ -n  \"${_arguments[0]:-}\"        ]]  &&\n         [[ !   \"${_arguments[0]:-}\" =~ ^-- ]]\n      then\n        local _maybe_notebook_name=\"${_arguments[0]:-}\"\n\n        _maybe_notebook_name=\"$(\n          printf \"%s\\\\n\" \"${_maybe_notebook_name}\" | LC_ALL=C sed 's/\\:$//'\n        )\"\n\n        local _notebook_name=\n        _notebook_name=\"$(\n          _notebooks \\\n            show \"${_maybe_notebook_name:-}\" --name --no-color 2>/dev/null || :\n        )\"\n      fi\n\n      if [[ -n \"${_notebook_name:-}\"          ]]  &&\n         ! _notebooks current --selected          &&\n         [[ -d \"${NB_DIR}/${_notebook_name}\"  ]]\n      then\n        NB_NOTEBOOK_PATH=\"${NB_DIR}/${_notebook_name}\"  \\\n          _ls \"${_arguments[@]:1}\"\n\n        return 0\n      else\n        local _count_arguments=()\n\n        if [[ -n \"${_selector:-}\"   ]]\n        then\n          _count_arguments+=(\"${_selector}\")\n        fi\n\n        if [[ -n \"${_maybe_type:-}\" ]]\n        then\n          _count_arguments+=(\"--${_maybe_type}\")\n        fi\n\n        local _local_count=\n        _local_count=\"$(\n          _count \"${_count_arguments[@]:-}\" --skip-unmatched-selector || :\n        )\"\n\n        if ! ((_local_count))                           &&\n           {\n             [[ -n  \"${_selector_folder_path:-}\"    ]]  ||\n             [[ !   \"${_filter_patterns[*]:-}\" =~ / ]]\n           }\n        then\n          {\n            _list \"${_list_options[@]:-}\"\n          } | {\n            if [[ -z \"${_selector:-}\"               ]]  ||\n               {\n                 [[ \"${_selector:-}\" =~ (/$|:$)     ]]  &&\n                 [[ \"${#_filter_patterns[@]}\" -eq 1 ]]\n               }\n            then # only container arguments\n              if ((NB_HEADER)) && [[ -n \"${_maybe_type:-}\"  ]]\n              then\n                _ls_print_header \"${_header_flags[@]:-}\"\n              fi\n\n              if ! ((${NB_FOLDER_HEADER:-0}))\n              then\n                _ls_print_folder_header \"${_selector_folder_path:-}\"\n              fi\n\n              cat\n\n              if ((NB_FOOTER)) && [[ -n \"${_maybe_type:-}\"  ]]\n              then\n                _ls_print_footer \"${_selector_folder_path:-}\"\n              fi\n            else\n              cat\n            fi\n          }\n        else\n          if [[ -n \"${_list_error:-}\" ]]\n          then\n            printf \"%s\\\\n\" \"${_list_error}\"\n\n            return 1\n          fi\n        fi\n      fi\n    }\n  } | {\n    # Header\n    # ------\n\n    if ((NB_HEADER)) && ((_display_header_and_footer))\n    then\n      if [[ -n \"${_header:-}\"             ]]\n      then\n        printf \"%s\\\\n\" \"${_header:-}\"\n      else\n        _ls_print_header \"${_header_flags[@]:-}\"\n      fi\n    fi\n\n    if [[ -n \"${_selector_folder_path:-}\" ]] &&\n       ((${NB_FOLDER_HEADER:-0}))            &&\n       ((_display_header_and_footer))\n    then\n      _ls_print_folder_header \"${_selector_folder_path:-}\"\n    fi\n\n    cat\n\n  } | {\n    # Footer\n    # ------\n\n    if ((NB_FOOTER))                  &&\n       ((_display_header_and_footer)) &&\n       [[ -z \"${_footer:-}\" ]]\n    then\n      _footer=\"$(_ls_print_footer \"${_selector_folder_path:-}\")\"\n    fi\n\n    cat\n\n    if [[ -n \"${_footer:-}\" ]]\n    then # print preloaded footer\n      printf \"%s\\\\n\" \"${_footer}\"\n    fi\n  } | {\n    if ((_use_pager))\n    then\n      _pager\n    else\n      cat\n    fi\n  }\n\n  if ((_fast_exit))\n  then\n    exit 0\n  else\n    return 0\n  fi\n}\n\n# notebooks · ##################################################### · notebooks\n\n_describe_notebooks() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} notebooks [<name> | <query>] [--ar | --archived] [--global] [--local]\n               [--names] [--paths] [--unar | --unarchived]\n  ${_ME} notebooks add ([<name>] [<remote-url> [<branch>... | --all]]) [--author]\n                   [--email <email>] [--name <name>]\n  ${_ME} notebooks (archive | open | peek | status | unarchive) [<name>]\n  ${_ME} notebooks author [<name> | <path>] [--email <email>] [--name <name>]\n  ${_ME} notebooks current [--path | --selected | --filename [<filename>]]\n                       [--global | --local]\n  ${_ME} notebooks delete <name> [-f | --force]\n  ${_ME} notebooks (export <name> [<path>] | import <path>)\n  ${_ME} notebooks init [<path> [<remote-url> [<branch>]]] [--author]\n                    [--email <email>] [--name <name>]\n  ${_ME} notebooks rename <old-name> <new-name>\n  ${_ME} notebooks select <selector>\n  ${_ME} notebooks show (<name> | <path> | <selector>) [--ar | --archived]\n                    [--escaped | --name | --path | --filename [<filename>]]\n  ${_ME} notebooks use <name>\n\n$(_color_primary \"Options\"):\n  --all                    Add notebooks from all remote branches.\n  --ar, --archived         List archived notebooks, or return archival status\n                           with \\`show\\`.\n  --author                 Set the notebook's commit author email and name.\n  --email <email>          Set the notebook's commit author email to <email>.\n  --escaped                Print the notebook name with spaces escaped.\n  --filename [<filename>]  Print an available filename for the notebooks. When\n                           <filename> is provided, check for an existing file\n                           and provide a filename with an appended sequence\n                           number for uniqueness.\n  -f, --force              Skip the confirmation prompt.\n  --global                 List global notebooks or the notebook set globally\n                           with \\`use\\`.\n  --local                  Exit with 0 if current within a local notebook,\n                           otherwise exit with 1.\n  --name, --names          Print the notebook name.\n  --name <name>            Set the notebook's commit author name to <name>.\n  --path, --paths          Print the notebook path.\n  --selected               Exit with 0 if the current notebook differs from\n                           the current global notebook, otherwise exit with 1.\n  --unar, --unarchived     Only list unarchived notebooks.\n\n$(_color_primary \"Subcommands\"):\n  (default)  List notebooks.\n  add        Create a new global notebook. When <remote-url> is specified,\n             create one or more new global notebook by cloning selected\n             or specified <branch>es from <remote-url>.\n             Aliases: \\`${_ME} notebooks create\\`, \\`${_ME} notebooks new\\`\n  archive    Set the current notebook or notebook <name> to \"archived\" status.\n  author     Configure the commit author email and name for the notebook.\n  current    Print the current notebook name or path.\n  delete     Delete a notebook.\n  export     Export the notebook <name> to the current directory or <path>,\n             making it usable as a local notebook.\n  import     Import the local notebook at <path> to make it global.\n  init       Create a new local notebook. Specify a <path> or omit to\n             initialize the current working directory as a local notebook.\n             Specify <remote-url> to clone an existing notebook.\n  open       Open the current notebook directory or notebook <name> in the\n             file browser, explorer, or finder.\n             Shortcut Alias: \\`o\\`\n  peek       Open the current notebook directory or notebook <name> in the\n             first tool found in the following list:\n             \\`ranger\\` [1], \\`mc\\` [2], \\`vifm\\` [3], \\`joshuto\\` [4], \\`eza\\` [5], or \\`ls\\`.\n             Shortcut Alias: \\`p\\`\n  rename     Rename a notebook. Aliases: \\`move\\`, \\`mv\\`\n  select     Set the current notebook from a colon-prefixed selector.\n             Not persisted. Selection format: <notebook>:<identifier>\n  status     Print the archival status of the current notebook or\n             notebook <name>.\n  show       Show and return information about a specified notebook.\n  unarchive  Remove \"archived\" status from the current notebook or notebook <name>.\n  use        Switch to a notebook.\n\n    1. https://ranger.github.io/\n    2. https://en.wikipedia.org/wiki/Midnight_Commander\n    3. https://vifm.info/\n    4. https://github.com/kamiyaa/joshuto\n    5. https://github.com/eza-community/eza\n\n$(_color_primary \"Description\"):\n  Manage notebooks.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-notebooks\n\n$(_color_primary \"See Also\"):\n  ${_ME} help archive\n  ${_ME} help history\n  ${_ME} help move\n  ${_ME} help remote\n  ${_ME} help status\n  ${_ME} help sync\n  ${_ME} help unarchive\n  ${_ME} help use\n\n$(_color_primary \"Examples\"):\n  ${_ME} notebooks --names\n  ${_ME} notebooks add sample\n  ${_ME} notebooks add example https://github.com/example/example.git\n  ${_ME} nb current --path\n  ${_ME} nb archive example\n\n$(_color_primary \"Shortcut Aliases\"):\n  ${_ME} n\n  ${_ME} nb\nHEREDOC\n}\n_RESERVED_NOTEBOOK_NAMES=(\n  \".cache\"\n  \".current\"\n  \".plugins\"\n  \".readme\"\n  \"readme\"\n  \"readme.md\"\n)\n_notebooks() {\n  # _notebooks_add()\n  #\n  # Usage:\n  #   _notebooks_add ([<name>] [<remote_url> [<branch>... | --all]]) [--author]\n  #                  [--email <email>] [--name <name>]\n  _notebooks_add() {\n    local _author=0\n    local _author_arguments=()\n    local _clone_all_branches=0\n    local _name=\n    local _print_default_feedback=1\n    local _option_selected_remote_branches=()\n    local _remote_url=\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --all)    _clone_all_branches=1 ;;\n        --author) _author=1             ;;\n        --email|--name)\n          _author=1\n          _author_arguments+=(\"${1:-}\")\n\n          if _option_value_is_present \"${2:-}\"\n          then\n            _author_arguments+=(\"${2:-}\")\n\n            shift\n          fi\n          ;;\n        *)\n          if _string_is_url \"${1:-}\"\n          then\n            _remote_url=\"${1:-}\"\n          elif [[ -z \"${_name:-}\"         ]] &&\n               [[ -z \"${_remote_url:-}\"   ]]\n          then\n            _name=\"${1:-}\"\n          else\n            _option_selected_remote_branches+=(\"${1:-}\")\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    if [[ -z \"${_name:-}\"                 ]] &&\n       [[ -z \"${_remote_url:-}\"           ]]\n    then\n      _exit_1 _help notebooks\n    fi\n\n    if   [[ -n \"${_remote_url:-}\"         ]]\n    then\n      local _git_options=(\n        --no-local\n        --single-branch\n      )\n    fi\n\n    if [[ -n \"${_name:-}\"                 ]]\n    then\n      _notebooks_validate_name \"${_name}\"\n\n      if [[ -e \"${NB_DIR}/${_name}\"       ]]\n      then\n        _exit_1 printf \"Already exists: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n      fi\n    fi\n\n    if [[ -n \"${_remote_url:-}\"           ]]\n    then\n      if [[ -n \"${_name:-}\"               ]] &&\n         ! ((${#_option_selected_remote_branches[@]}))\n      then\n        git clone \"${_git_options[@]:-}\"  \\\n          \"${_remote_url}\"                \\\n          \"${NB_DIR}/${_name}\"\n      elif [[ -n \"${_name:-}\"                                 ]] &&\n           [[ \"${#_option_selected_remote_branches[@]}\" -eq 1 ]]\n      then\n        git clone \"${_git_options[@]:-}\"                      \\\n          --branch \"${_option_selected_remote_branches[0]:-}\" \\\n          \"${_remote_url}\"                                    \\\n          \"${NB_DIR}/${_name}\"\n      else\n        local _current_notebook_path=\n        _current_notebook_path=\"$(_notebooks current --path)\"\n\n        local _remote_branches=()\n\n        if [[ -n \"${_option_selected_remote_branches[*]:-}\" ]]\n        then\n          _remote_branches=(\"${_option_selected_remote_branches[@]}\")\n        else\n          _remote_branches=($(\n            git -C \"${_current_notebook_path}\" ls-remote  \\\n              --heads \"${_remote_url:-}\"                  \\\n              2>/dev/null                                 \\\n              | LC_ALL=C sed \"s/.*\\///g\"\n          ))\n        fi\n\n        if ! ((${#_remote_branches[@]}))\n        then\n          _warn printf \"No remote branches found.\\\\n\"\n\n          return 1\n        else\n          local _selected_branches=()\n\n          _print_default_feedback=0\n\n          if ((${#_option_selected_remote_branches[@]}))\n          then\n            _selected_branches=(\"${_option_selected_remote_branches[@]:-}\")\n          elif [[ \"${#_remote_branches[@]}\" -eq 1 ]]\n          then\n            _selected_branches=(\"${_remote_branches[0]:-}\")\n          elif ((_clone_all_branches))\n          then\n            _selected_branches=(\"${_remote_branches[@]:-}\")\n          fi\n\n          if ! ((${#_selected_branches[@]}))\n          then\n            printf      \"Choose a remote branch:\\\\n\"\n\n            _print_line \"-----------------------\"\n\n            local i=\n            for ((i=0; i < ${#_remote_branches[@]}; i++))\n            do\n              printf \"%s %s\\\\n\"                 \\\n                \"$(_color_brackets \"$((i+1))\")\" \\\n                \"${_remote_branches[${i}]:-}\"\n            done\n\n            printf \"%s All Branches\\\\n\"         \\\n              \"$(_color_brackets \"$((i+1))\")\"\n\n            local _branch_prompt_response=\n\n            while true\n            do\n              IFS='' read -r -e -d $'\\n' -p                                               \\\n                \"$(_color_primary \"Choose a branch\") or $(_color_primary \"q\") to quit: \"  \\\n                _branch_prompt_response\n\n              case \"${_branch_prompt_response:-}\" in\n                q*|exit)\n                  printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n                  exit 0\n                  ;;\n                [0-9]*)\n                  if [[ -n \"${_remote_branches[$((_branch_prompt_response - 1))]:-}\" ]]\n                  then\n                    _branch_prompt_response=\"${_remote_branches[$((_branch_prompt_response - 1))]:-}\"\n\n                    break\n                  elif [[ \"${_branch_prompt_response}\" -eq \"$((${#_remote_branches[@]} + 1))\" ]]\n                  then\n                    _clone_all_branches=1\n\n                    break\n                  fi\n                  ;;\n                *)\n                  if _contains \"${_branch_prompt_response}\" \"${_remote_branches[@]}\"\n                  then\n                    break\n                  fi\n              esac\n            done\n\n            if ((_clone_all_branches))\n            then\n              _selected_branches=(\"${_remote_branches[@]:-}\")\n            else\n              _selected_branches=(\"${_branch_prompt_response:-}\")\n            fi\n\n            _print_line \"------------------------------------\"\n          fi\n\n          if ! ((${#_selected_branches[@]}))\n          then\n            _selected_branches=(\"${_remote_branches[@]:-}\")\n          fi\n\n          local _first=1\n\n          local __selected_branch=\n          for   __selected_branch in \"${_selected_branches[@]:-}\"\n          do\n            local _target_notebook_name=\n\n            if _contains \"${__selected_branch:-}\" \"main\" \"master\"\n            then\n              _target_notebook_name=\"${_remote_url##*/}\"\n            else\n              _target_notebook_name=\"${__selected_branch:-}\"\n            fi\n\n            local _target_notebook_path=\n            _target_notebook_path=\"$(\n              _get_unique_path \"${NB_DIR}/${_target_notebook_name}\"\n            )\"\n\n            _target_notebook_name=\"${_target_notebook_path##*/}\"\n\n            if ((_first))\n            then\n              _first=0\n            else\n              _print_line \"------------------------------------\"\n            fi\n\n            local _bk_name=  && _bk_name=\"$(_color_brackets \"${_target_notebook_name}\")\"\n            local _hi_enter= && _hi_enter=\"$(_color_primary 'enter')\"\n            local _hi_q=     && _hi_q=\"$(_color_primary 'q')\"\n            local _hi_type=  && _hi_type=\"$(_color_primary 'type')\"\n\n            cat <<HEREDOC\nPress ${_hi_enter} to use the selected name, ${_hi_type} a new name, or press ${_hi_q} to quit.\n\nHEREDOC\n\n            while true\n            do\n              local _target_notebook_prompt_response=\n\n              IFS='' read -r -e -d $'\\n' -p \\\n                \"Name ${_bk_name}: \"        \\\n                _target_notebook_prompt_response\n\n              case \"${_target_notebook_prompt_response:-}\" in\n                '')\n                  break\n                  ;;\n                q*|exit)\n                  printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n                  exit 0\n                  ;;\n                *)\n                  _target_notebook_name=\"${_target_notebook_prompt_response}\"\n\n                  break\n                  ;;\n              esac\n            done\n\n            local _unique_notebook_path=\n            _unique_notebook_path=\"$(\n              _get_unique_path \"${NB_DIR}/${_target_notebook_name:-}\"\n            )\"\n\n            _name=\"${_unique_notebook_path##*/}\"\n\n            _notebooks_validate_name \"${_name}\" || return 1\n\n            git clone \"${_git_options[@]:-}\"    \\\n              \"${_remote_url}\"                  \\\n              --branch \"${__selected_branch:-}\" \\\n              \"${NB_DIR}/${_name}\"              &&\n              printf \"Added notebook: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n          done && return 0\n        fi\n      fi\n    else\n      mkdir -p \"${NB_DIR}/${_name}\"                   &&\n        git -C \"${NB_DIR}/${_name}\" init &>/dev/null  &&\n        {\n          if ((_author))\n          then\n            _author_arguments+=(\"${NB_DIR}/${_name}\")\n            _notebooks author \"${_author_arguments[@]:-}\"\n          fi\n        }                                             &&\n        touch \"${NB_DIR}/${_name}/.index\"             &&\n        _temp cache clear                             &&\n        _git checkpoint \"${NB_DIR}/${_name}\" \"[${_ME}] Initialize\"\n      fi                            &&\n        ((_print_default_feedback)) &&\n        printf \"Added notebook: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n  }\n\n  # Usage: _notebooks_add_new [<notebook>...]\n  _notebooks_add_new() {\n    local _notebook_list=(\"${@:-}\")\n\n    [[ ! -d \"${NB_DIR}\" ]] && return 0\n\n    if [[ -z \"${1:-}\"   ]]\n    then\n      _notebook_list=($(ls -1 \"${NB_DIR}\"))\n    fi\n\n    local __notebook_name=\n    for   __notebook_name in \"${_notebook_list[@]:-}\"\n    do\n      if [[   -d \"${NB_DIR}/${__notebook_name}\"         ]]  &&\n         [[ ! -e \"${NB_DIR}/${__notebook_name}/.index\"  ]]\n      then\n        {\n          if ((_GIT_ENABLED))\n          then\n            git -C \"${NB_DIR}/${__notebook_name}\" init &>/dev/null\n          fi\n        } && touch \"${NB_DIR}/${__notebook_name}/.index\"    &&\n        _temp cache clear                                   &&\n        _git checkpoint \"${NB_DIR}/${__notebook_name}\" \"[${_ME}] Initialize\"\n      fi\n    done\n  }\n\n  # _notebooks_author()\n  #\n  # Usage:\n  #   _notebooks_author [--name [<name>]] [--email [<email>]] [--unset]\n  #                     [<notebook-path>]\n  #\n  # Description:\n  #   Print, set, and delete the <email> and <name> for git commit attribution\n  #   within the notebook.\n  _notebooks_author() {\n    local _email=0\n    local _name=0\n    local _new_local_email=\n    local _new_local_name=\n    local _print_current=0\n    local _selector=\n    local _skip_prompt=0\n    local _unset=0\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --email)\n          _email=1\n\n          if _option_value_is_present \"${2:-}\"\n          then\n            _new_local_email=\"${2:-}\"\n\n            shift\n          fi\n          ;;\n        -f|--force|--skip*|-y|--yes)\n          _skip_prompt=1\n          ;;\n        --name)\n          _name=1\n\n          if _option_value_is_present \"${2:-}\"\n          then\n            _new_local_name=\"${2:-}\"\n\n            shift\n          fi\n          ;;\n        --print|--current)\n          _print_current=1\n          ;;\n        --unset)\n          _unset=1\n          ;;\n        *)\n          if [[ -z \"${_selector:-}\"     ]]\n          then\n            _selector=\"${1:-}\"\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    local _notebook_path=\n\n    if   [[ \"${_selector:-}\" =~ ^/      ]]\n    then\n      _notebook_path=\"${_selector:-}\"\n    elif [[ \"${_selector:-}\" == \"local\" ]]\n    then\n      _notebook_path=\"$(_notebooks_current --local --path || :)\"\n    elif [[ -n \"${_selector:-}\"         ]]\n    then\n      _notebook_path=\"${NB_DIR}/${_selector%%:*}\"\n    fi\n\n    if [[ -z \"${_notebook_path:-}\"            ]]\n    then\n      _notebook_path=\"$(_notebooks_current --path)\"\n    fi\n\n    if [[ \"${_notebook_path:-}\" =~ ^${NB_DIR} ]]\n    then\n      local _notebook_name=\"${_notebook_path##*/}\"\n    else\n      local _notebook_name=\"local\"\n    fi\n\n    local _global_email=\n    _global_email=\"$(\n      git -C \"${_notebook_path:-}\" config --global --includes user.email || :\n    )\"\n\n    local _global_name=\n    _global_name=\"$(\n      git -C \"${_notebook_path:-}\" config --global --includes user.name  || :\n    )\"\n\n    local _local_email=\n    _local_email=\"$(\n      git -C \"${_notebook_path:-}\" config --local user.email  || :\n    )\"\n\n    local _local_name=\n    _local_name=\"$(\n      git -C \"${_notebook_path:-}\" config --local user.name   || :\n    )\"\n\n    if ((_unset))\n    then\n      local _unset_output_present=0\n\n      if [[ -n \"${_local_email:-}\"  ]] && {\n           ((_email)) || ! ((_name))\n         }\n      then\n        _warn printf \"Unsetting local email.\\\\n\"\n        git -C \"${_notebook_path:-}\" config --unset user.email  || :\n        _unset_output_present=1\n      fi\n\n      if [[ -n \"${_local_name:-}\"   ]] && {\n           ((_name))  || ! ((_email))\n         }\n      then\n        _warn printf \"Unsetting local name.\\\\n\"\n        git -C \"${_notebook_path:-}\" config --unset user.name   || :\n        _unset_output_present=1\n      fi\n\n      ((_unset_output_present)) && printf \"\\\\n\"\n\n      printf \"Updated author for: %s\\\\n\" \"$(\n        _color_primary \"${_notebook_name}\"\n      )\"\n\n      _print_line \"-------------------\"\n\n      _notebooks_author \"${_notebook_path}\" --current\n\n      return 0\n    elif ((_print_current))\n    then\n      printf \"%s\" \"$(_color_primary \"email\")\"\n\n      if [[ -n \"${_local_email:-}\"        ]]\n      then\n        printf \" (%s):  %s\\\\n\" \"$(_color_primary \"local\")\" \"${_local_email:-}\"\n      else\n        printf \" (%s): %s\\\\n\" \"$(_color_primary \"global\")\" \"${_global_email:-}\"\n      fi\n\n      printf \"%s\" \"$(_color_primary \"name\")\"\n\n      if [[ -n \"${_local_name:-}\"         ]]\n      then\n        printf \"  (%s):  %s\\\\n\" \"$(_color_primary \"local\")\" \"${_local_name:-}\"\n      else\n        printf \"  (%s): %s\\\\n\" \"$(_color_primary \"global\")\" \"${_global_name:-}\"\n      fi\n\n      return 0\n    else\n      printf \"Current author for: %s\\\\n\" \"$(\n        _color_primary \"${_notebook_name}\"\n      )\"\n\n      _print_line \"-------------------\"\n\n      _notebooks_author \"${_notebook_path}\" --current\n\n      if [[ -n \"${_new_local_email:-}\"    ]] || [[ -n \"${_new_local_name:-}\" ]]\n      then\n        printf    \"\\\\nUpdate:\\\\n\"\n        _print_line  \"-------\"\n\n        if [[ -n \"${_new_local_email:-}\"  ]]\n        then\n          printf \"local %s: %s\\\\n\" \"$(_color_primary \"email\")\" \"${_new_local_email:-}\"\n        fi\n\n        if [[ -n \"${_new_local_name:-}\"   ]]\n        then\n          printf \"local %s:  %s\\\\n\" \"$(_color_primary \"name\")\" \"${_new_local_name:-}\"\n        fi\n      fi\n\n      if ! ((_skip_prompt))\n      then\n        while true\n        do\n          local __yn=\n          IFS='' read -r -e -d $'\\n' -p   \\\n\"${_NEWLINE}$(_color_primary \"Update?\")  $(_color_brackets \"y/N\") \" __yn\n\n          case \"${__yn}\" in\n            [Yy]*)\n              break\n              ;;\n            *)\n              printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n              exit 0\n              ;;\n          esac\n        done\n\n        if [[ -z \"${_new_local_email:-\"${_new_local_name:-}\"}\" ]]\n        then\n          local _unset=\n          _unset=$(_color_primary \"unset\")\n\n          cat <<HEREDOC\n\nEnter a new value, ${_unset} to use the global value,\nor leave blank to keep the current value.\n\nHEREDOC\n\n          IFS='' read -r -e -d $'\\n' -p             \\\n\"local $(_color_primary \"email:\") \" _new_local_email\n\n          IFS='' read -r -e -d $'\\n' -p             \\\n\"local $(_color_primary \"name:\")  \" _new_local_name\n        fi\n      fi\n\n      if [[ -n \"${_new_local_email:-}\"    ]]\n      then\n        if _contains \"${_new_local_email:-}\" \"global\" \"--unset\" \"unset\"\n        then\n          git -C \"${_notebook_path:-}\" config --unset user.email  || :\n        else\n          git -C \"${_notebook_path}\" config --local \\\n            user.email \"${_new_local_email:-}\"\n        fi\n      fi\n\n      if [[ -n \"${_new_local_name:-}\"     ]]\n      then\n        if _contains \"${_new_local_name:-}\" \"global\" \"--unset\" \"unset\"\n        then\n          git -C \"${_notebook_path:-}\" config --unset user.name   || :\n        else\n          git -C \"${_notebook_path}\" config --local \\\n            user.name \"${_new_local_name:-}\"\n        fi\n      fi\n\n      if [[ -n \"${_new_local_email:-\"${_new_local_name:-}\"}\" ]]   || ! ((_skip_prompt))\n      then\n        printf \"\\\\nUpdated author for: %s\\\\n\" \"$(\n          _color_primary \"${_notebook_name}\"\n        )\"\n\n        _print_line \"-------------------\"\n\n        _notebooks_author \"${_notebook_path}\" --current\n      fi\n    fi\n  }\n\n  # _notebooks_current()\n  #\n  # Usage:\n  #   _notebooks_current (<name> | <path> | <selector>) [--global | --local]\n  #                      [--path | --scoped] [--filename]\n  _notebooks_current() {\n    local _file_path=\n    local _print_global=0\n    local _print_local=0\n    local _print_path=0\n    local _print_unique_file_path=0\n    local _return_selected=0\n    local _selector=\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --global)\n          _print_global=1\n          ;;\n        --local)\n          _print_local=1\n          ;;\n        --path*)\n          _print_path=1\n          ;;\n        --scoped|--selected)\n          _return_selected=1\n          ;;\n        --filename|--basename|--file*path)\n          _print_unique_file_path=1\n\n          if _option_value_is_present \"${2:-}\"\n          then\n            _file_path=\"${2}\"\n\n            shift\n          fi\n          ;;\n        [^-]*)\n          _selector=\"${1}\"\n          ;;\n      esac\n\n      shift\n    done\n\n    if [[ -n \"${_selector:-}\" ]]\n    then\n      _notebooks_select \"${_selector}\" || :\n    fi\n\n    if ((_print_local))\n    then\n      if [[ -n \"${_LOCAL_NOTEBOOK_PATH:-}\" ]]\n      then\n        if ((_print_path))\n        then\n          printf \"%s\\\\n\" \"${_LOCAL_NOTEBOOK_PATH}\"\n        else\n          return 0\n        fi\n      else\n        return 1\n      fi\n    elif ((_print_global))\n    then\n      if ((_print_path))\n      then\n        printf \"%s\\\\n\" \"${_GLOBAL_NOTEBOOK_PATH}\"\n      else\n        basename \"${_GLOBAL_NOTEBOOK_PATH}\"\n      fi\n    elif ((_print_path))\n    then\n      printf \"%s\\\\n\" \"${NB_NOTEBOOK_PATH}\"\n    elif ((_return_selected))\n    then\n      [[ \"${NB_NOTEBOOK_PATH}\" != \"${_GLOBAL_NOTEBOOK_PATH}\" ]] &&\n      [[ \"${NB_NOTEBOOK_PATH}\" != \"${_LOCAL_NOTEBOOK_PATH}\"  ]]\n    elif ((_print_unique_file_path))\n    then\n      _notebooks_show \"${NB_NOTEBOOK_PATH}\" --filename \"${_file_path:-}\"\n    else\n      if [[ -n \"${_LOCAL_NOTEBOOK_PATH:-}\"                      ]] &&\n         [[ \"${NB_NOTEBOOK_PATH}\" == \"${_LOCAL_NOTEBOOK_PATH}\"  ]]\n      then\n        printf \"local\\\\n\"\n      else\n        basename \"${NB_NOTEBOOK_PATH}\"\n      fi\n    fi\n  }\n\n  # _notebooks_delete()\n  #\n  # Usage:\n  #   _notebooks_delete <name>\n  _notebooks_delete() {\n    local _force=0\n    local _name=\n\n    local __arg=\n    for   __arg in \"${@:-}\"\n    do\n      case \"${__arg}\" in\n        -f|--force|--skip*|-y|--yes)\n          _force=1\n          ;;\n        *)\n          [[ -z \"${_name:-}\"  ]] && _name=\"${__arg%%:*}\"\n          ;;\n      esac\n    done\n\n    if [[   -z  \"${_name}\"    ]]\n    then\n      _exit_1 _help notebooks\n    elif [[     \"${_name}\"    == \"local\"    ]] &&\n         [[ -n  \"${_LOCAL_NOTEBOOK_PATH:-}\" ]]\n    then\n      _exit_1 cat <<HEREDOC\nUse your system's shell or file explorer to delete local notebook directories.\nHEREDOC\n    fi\n\n    _notebooks_validate_name \"${_name}\"\n\n    if [[ ! -d \"${NB_DIR}/${_name}\"         ]] ||\n       [[ ! -e \"${NB_DIR}/${_name}/.git\"    ]] ||\n       [[ ! -e \"${NB_DIR}/${_name}/.index\"  ]]\n    then\n      _exit_1 printf \"Notebook not found: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n    fi\n\n    local _notebook_names=()\n    _notebook_names=($(_notebooks --names --no-color))\n\n    local _notebook_count=\n    _notebook_count=\"${#_notebook_names[@]}\"\n\n    if ! ((_force))\n    then\n      if _command_exists \"trash\" && [[ \"${OSTYPE}\" =~ ^darwin ]]\n      then\n        printf \"Moving to Trash: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n      else\n        cat <<HEREDOC\nDeleting $(_color_primary \"${_name}\").\n\nThis action cannot be undone. This will permanently delete the\n$(_color_primary \"${_name}\") notebook, all notes and files it contains,\nand the entire revision history.\n\nHEREDOC\n      fi\n\n      while true\n      do\n        local __response=\n        IFS='' read -r -e -d $'\\n' -p \\\n\"Please type $(_color_primary \"${_name}\") to confirm: \" __response\n\n        if [[ \"${__response}\"     == \"${_name}\"   ]]\n        then\n          break\n        else\n          printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n          exit 0\n        fi\n      done\n    fi\n\n    if [[ \"$(_notebooks current)\" ==  \"${_name}\"  ]] &&\n       [[ \"${_notebook_count}\"    -gt 1           ]]\n    then\n      if [[ \"${_name}\" != \"home\"  ]]\n      then\n        _notebooks use \"home\"\n      else\n        local __notebook=\n        for   __notebook in \"${_notebook_names[@]:-}\"\n        do\n          if [[ \"${__notebook}\"   !=    \"$(_notebooks current)\"   ]]\n          then\n            _notebooks use \"${__notebook}\"\n\n            break\n          fi\n        done\n      fi\n    fi\n\n    if _command_exists \"trash\"    &&    [[ \"${OSTYPE}\" =~ ^darwin ]]\n    then\n      trash \"${NB_DIR:?}/${_name:?}\"\n    else\n      if [[ -e \"${NB_DIR:?}/${_name:?}\" ]]\n      then\n        rm -r -f \"${NB_DIR:?}/${_name:?}\"\n      fi\n    fi &&\n      _temp cache clear &&\n      printf \"Notebook deleted: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n  }\n\n  # _notebooks_export()\n  #\n  # Usage:\n  #   _notebooks_export <name> [<path>]\n  _notebooks_export() {\n    local _name=\"${1:-}\"\n\n    if [[ -z \"${_name:-}\"           ]]\n    then\n      _exit_1 _help \"notebooks\"\n    fi\n\n    _notebooks_validate_name \"${_name}\"\n\n    if [[ ! -d \"${NB_DIR}/${_name}\" ]]\n    then\n      _exit_1 printf \"Notebook not found: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n    fi\n\n    local _target_path=\"${2:-}\"\n\n    if [[ -n \"${_target_path:-}\"    ]] && [[ ! \"${_target_path}\" =~ ^/ ]]\n    then\n      _target_path=\"${_CURRENT_WORKING_DIR}/${_target_path}\"\n    fi\n\n    if [[ -n \"${_target_path:-}\"              ]] &&\n       [[ -d \"${_target_path}\"                ]] &&\n       [[ ! \"${_target_path}\" =~ \\/${_name}$  ]]\n    then\n      _target_path=\"${_target_path}/${_name}\"\n    fi\n\n    if [[ -z \"${_target_path}\"      ]]\n    then\n      _target_path=\"${_CURRENT_WORKING_DIR}/${_name}\"\n    fi\n\n    _target_path=\"$(_get_unique_path \"${_target_path}\")\"\n\n    cp -R \"${NB_DIR}/${_name}\" \"${_target_path}\"  &&\n      _temp cache clear                           &&\n      printf \"Exported notebook %s to %s\\\\n\"  \\\n        \"$(_color_primary \"${_name}\")\"        \\\n        \"$(_color_primary \"${_target_path}\")\"\n  }\n\n  # _notebooks_import()\n  #\n  # Usage:\n  #   _notebooks_import <path> [<name>]\n  _notebooks_import() {\n    local _path=\"${1:-}\"\n\n    if [[ -z \"${_path:-}\"     ]]\n    then\n      _exit_1 _help \"notebooks\"\n    fi\n\n    local _basename=\n    _basename=\"$(basename \"${_path}\")\"\n\n    if [[ ! \"${_path}\" =~ ^/  ]]\n    then\n      _path=\"${_CURRENT_WORKING_DIR}/${_path}\"\n    fi\n\n    if [[ ! -d \"${_path}\"     ]]\n    then\n      _exit_1 printf \"Not a directory: %s\" \"$(_color_primary \"${_path}\")\"\n    fi\n\n    local _target_basename=\"${2:-}\"\n\n    if [[   -z \"${_target_basename:-}\"  ]]\n    then\n      _target_basename=\"${_basename}\"\n    fi\n\n    _notebooks_validate_name \"${_target_basename}\"\n\n    local _target_path=\n    _target_path=\"$(_get_unique_path \"${NB_DIR}/${_target_basename}\")\"\n\n    cp -R \"${_path}\" \"${_target_path}\"  &&\n      _temp cache clear                 &&\n      _notebooks_add_new                &&\n      printf \"Imported notebook: %s\\\\n\" \\\n        \"$(_color_primary \"$(basename \"${_target_path}\")\")\"\n  }\n\n  # _notebooks_init()\n  #\n  # Usage:\n  #   _notebooks_init [<path> [<remote_url> [<branch>]]\n  _notebooks_init() {\n    local _author=0\n    local _author_arguments=()\n    local _path=\n    local _remote_branch=\n    local _remote_url=\n    local _skip_prompt=0\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --author) _author=1 ;;\n        --email|--name)\n          _author=1\n          _author_arguments+=(\"${1:-}\")\n\n          if _option_value_is_present \"${2:-}\"\n          then\n            _author_arguments+=(\"${2:-}\")\n\n            shift\n          fi\n          ;;\n        -f|--force|--skip*|-y|--yes)\n          _skip_prompt=1\n          ;;\n        *)\n          if _string_is_url \"${1:-}\"    && [[ -z \"${_remote_url:-}\" ]]\n          then\n            _remote_url=\"${1:-}\"\n          elif [[ -z \"${_path:-}\"   ]]  && [[ -z \"${_remote_url:-}\" ]]\n          then\n            _path=\"${1:-}\"\n          else\n            _remote_branch=\"${1:-}\"\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    if [[ -n \"${_remote_url:-}\"     ]]  && [[ -z \"${_path}\"         ]]\n    then\n      _exit_1 printf                                                    \\\n        \"Must specify a <path> when cloning from <remote-url>.\\\\n%s\\\\n\" \\\n        \"$(_help \"notebooks\")\"\n    fi\n\n    if [[   -n \"${_path:-}\"         ]]\n    then\n      if [[ !   \"${_path}\" =~ ^/    ]]\n      then\n        _path=\"${_CURRENT_WORKING_DIR}/${_path}\"\n      fi\n    else\n      _path=\"${_CURRENT_WORKING_DIR}\"\n    fi\n\n    if [[ -d \"${_path}\"             ]]  &&\n       [[ -e \"${_path}/.git\"        ]]\n    then\n      local _error_message=\n\n      if [[ -f \"${_path}/.index\"    ]]\n      then\n        _error_message=\"Notebook exists: $(_color_primary \"${_path}\")\"\n      else\n        _error_message=\"Git repository exists: $(_color_primary \"${_path}\")\"\n      fi\n\n      _exit_1 printf \"%s\\\\n\" \"${_error_message}\"\n    fi\n\n    if [[ ! -e \"${_path}\"           ]]\n    then\n      mkdir -p \"${_path}\"\n    elif [[ \"${HOME}\" =~ ^${_path}  ]]\n    then\n      _exit_1 printf                                                    \\\n        \"Unable to turn top-level directory into local notebook: %s\\\\n\" \\\n        \"$(_color_primary \"${_path}\")\"\n    elif [[ -f \"${_path}\"           ]]\n    then\n      _exit_1 printf \"File exists: %s\\\\n\" \"$(_color_primary \"${_path}\")\"\n    elif [[ -d \"${_path:-}\"         ]]\n    then\n      printf \"Directory exists: %s\\\\n\" \"$(_color_primary \"${_path}\")\"\n\n      if [[ -n \"${_remote_url:-}\"   ]]\n      then\n        _exit_1 printf \"Unable to clone to existing directory.\\\\n\"\n      else\n        local _git_repository_count=0\n        _git_repository_count=\"$(\n          find \"${_path}\" -name .git -prune | wc -l | awk '$1=$1'\n        )\"\n\n        if ((_git_repository_count))\n        then\n          _warn printf \"This directory contains %s git repositories.\\\\n\" \\\n            \"$(_color_primary \"${_git_repository_count}\")\"\n        fi\n\n        if ! ((_skip_prompt))\n        then\n          while true\n          do\n            local __yn=\n            IFS='' read -r -e -d $'\\n' -p \\\n              \"Initialize directory as a local notebook? $(_color_brackets \"y/N\") \" __yn\n\n            case \"${__yn}\" in\n              [Yy]*)\n                break\n                ;;\n              *)\n                printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n                exit 0\n                ;;\n            esac\n          done\n        fi\n      fi\n    fi\n\n    if [[ \"${_path}\" != \"${_CURRENT_WORKING_DIR}\" ]] &&\n       [[ -n \"${_remote_url:-}\"                   ]]\n    then\n      if [[ -n \"${_remote_branch:-}\"      ]]\n      then\n        git clone --no-local --single-branch --branch \"${_remote_branch:-}\" \\\n          \"${_remote_url}\"                                                  \\\n          \"${_path}\"\n      else\n        git clone --no-local --single-branch \"${_remote_url}\" \"${_path}\"\n      fi\n    else\n      git -C \"${_path}\" init &>/dev/null  &&\n        {\n          if ((_author))\n          then\n            _author_arguments+=(\"${_path}\")\n            _notebooks author \"${_author_arguments[@]:-}\"\n          fi\n        } &&\n        touch \"${_path}/.index\"           &&\n        _git checkpoint \"${_path}\" \"[${_ME}] Initialize\"\n    fi\n\n    printf \"Initialized local notebook: %s\\\\n\" \"$(_color_primary \"${_path}\")\"\n  }\n\n  # _notebooks_list()\n  #\n  # Usage:\n  #   _notebooks_list [<name> | <query>] [--ar | --archived] [--local]\n  #                   [--global] [--names] [--paths] [--unar | --unarchived]\n  _notebooks_list() {\n    local _counter=0\n    local _notebook_color_enabled=\"${_COLOR_ENABLED}\"\n    local _notebook_names=()\n    local _notebook_paths=()\n    local _only_archived=0\n    local _only_global=0\n    local _only_local=0\n    local _only_names=0\n    local _only_paths=0\n    local _only_unarchived=0\n    local _options=()\n    local _query_names=()\n\n    local __arg=\n    for   __arg in \"${@:-}\"\n    do\n      case \"${__arg}\" in\n        --archived|--global|--local|--name*|--no*color|--path*|--unarchived)\n          _options+=(\"${__arg}\")\n          ;;\n      esac\n\n      case \"${__arg}\" in\n        --ar|--archived)\n          _only_archived=1\n          ;;\n        --global)\n          _only_global=1\n          ;;\n        --local)\n          _only_local=1\n          ;;\n        --name*)\n          _only_names=1\n          ;;\n        --no*color)\n          _notebook_color_enabled=0\n          ;;\n        --path*)\n          _only_paths=1\n          ;;\n        --unar|--unarchived)\n          _only_unarchived=1\n          ;;\n        *)\n          _query_names+=(\"${__arg}\")\n          ;;\n      esac\n    done\n\n    if [[ -z \"${NB_DIR}\" ]] || [[ ! -e \"${NB_DIR}\"  ]]\n    then\n      exit 1\n    fi\n\n    _current_notebook_name=\"$(_notebooks current --name)\"\n\n    if [[ -z \"${_query_names[*]:-}\"         ]]\n    then\n      _notebook_names=($(ls -1 \"${NB_DIR}\"))\n\n      _notebooks_add_new \"${_notebook_names[@]:-}\"\n\n      set +f\n      _notebook_paths=($(ls -1 -d \"${NB_DIR}\"/*))\n      set -f\n\n      if [[ -n \"${_LOCAL_NOTEBOOK_PATH:-}\"  ]]\n      then\n        _notebook_names=(\"local\" \"${_notebook_names[@]:-}\")\n        _notebook_paths=(\"${_LOCAL_NOTEBOOK_PATH}\" \"${_notebook_paths[@]:-}\")\n      fi\n    else\n      _notebooks_add_new\n\n      local __name=\n      for   __name in \"${_query_names[@]}\"\n      do\n        __name=\"${__name%:}\"\n\n        _notebook_names+=(\"${__name}\")\n\n        if [[ \"${__name}\" == \"local\"        ]]\n        then\n          _notebook_paths+=(\"${_LOCAL_NOTEBOOK_PATH}\")\n        else\n          _notebook_paths+=(\"${NB_DIR}/${__name}\")\n        fi\n      done\n    fi\n\n    local i=\n    for ((i=0; i < ${#_notebook_names[@]}; i++))\n    do\n      if [[ -e \"${_notebook_paths[i]}/.git\"                 ]]\n      then # it's a git repository.\n        local _notebook_line=\n        local _origin_url=\n\n        if [[     \"${i}\"                        == \"0\"      ]]  &&\n           [[     \"${_notebook_names[i]:-}\"     == \"local\"  ]]  &&\n           [[ -n  \"${_LOCAL_NOTEBOOK_PATH:-}\"               ]]\n        then # local notebook as first notebook\n          if ((_only_global))\n          then\n            continue\n          else\n            if ((_only_paths))\n            then\n              _notebook_line=\"${_notebook_paths[i]}\"\n            elif ((_notebook_color_enabled))                    &&\n                 [[ \"${_current_notebook_name}\" == \"local\"  ]]\n            then\n              _notebook_line=\"$(_color_primary \"local\" --underline)\"\n            else\n              _notebook_line=\"local\"\n            fi\n          fi\n        elif ((_only_local))\n        then\n          if [[ -z \"${_LOCAL_NOTEBOOK_PATH:-}\"      ]]\n          then\n            return 1\n          else\n            continue\n          fi\n        else\n          if ((_only_paths))\n          then\n            _notebook_line=\"${_notebook_paths[i]}\"\n          elif ! ((_notebook_color_enabled))\n          then\n            _notebook_line=\"${_notebook_names[i]}\"\n          else\n            if [[ \"${_current_notebook_name}\" == \"${_notebook_names[i]}\" ]]\n            then # it's the current repository.\n              _notebook_line=\"$(_color_primary \"${_notebook_names[i]}\")\"\n\n              if [[ \"${#_notebook_names[@]}\" -gt 1  ]]\n              then\n                _notebook_line=\"$(\n                  _color_primary \"${_notebook_names[i]}\" --underline\n                )\"\n              fi\n            else\n              _notebook_line=\"${_notebook_names[i]}\"\n            fi\n          fi\n        fi\n\n        if [[ -e \"${_notebook_paths[i]}/.archived\"  ]]\n        then\n          if ((_only_unarchived))\n          then\n            continue\n          elif ! ((_only_names)) && ! ((_only_paths))\n          then\n            _notebook_line=\"${_notebook_line} (archived)\"\n          fi\n        elif ((_only_archived))\n        then\n          continue\n        fi\n\n        if ! ((_only_names)) && ! ((_only_paths))\n        then\n          _origin_url=\"$(\n            git -C \"${_notebook_paths[i]}\" config --get remote.origin.url || echo ''\n          )\"\n\n          if [[ -n \"${_origin_url:-}\"   ]]\n          then\n            _notebook_line=\"${_notebook_line} (${_origin_url})\"\n          fi\n        fi\n\n        if [[ -n \"${_notebook_line:-}\"  ]]\n        then\n          printf \"%s\\\\n\" \"${_notebook_line:-}\"\n\n          _counter=$((_counter+1))\n        fi\n      fi\n    done\n\n    if ! ((_counter))\n    then\n      if [[ -n \"${_query_names[*]:-}\"   ]]\n      then\n        {\n          local _query_pattern=\n          _query_pattern=\"$(_join \"|\" \"${_query_names[@]:-}\")\"\n\n          {\n            _notebooks_list \"${_options[@]:-}\"  2>/dev/null\n          } | {\n            grep -i \"${_query_pattern:-}\"       2>/dev/null\n          }\n        } || {\n          _warn printf                  \\\n            \"Notebook not found: %s\\\\n\" \\\n            \"$(_color_primary \"${_query_names[*]}\" | tr '\\r\\n' ' ')\" &&\n              return 1\n        }\n      else\n        return 1\n      fi\n    fi\n  }\n\n  # _notebooks_notebook()\n  #\n  # Usage:\n  #   _notebooks_notebook [archive | open | peek | status | unarchive] <name>\n  _notebooks_notebook() {\n    local _notebook_name=\"${2%:}\"\n    local _notebook_path=\n    local _subcommand=\"${1:-}\"\n\n    if [[ -n \"${_notebook_name:-}\"  ]]\n    then\n      _notebooks_validate_name \"${_notebook_name}\"\n\n      _notebook_path=\"$(_notebooks \"${_notebook_name}\" --path)\"\n    else\n      _notebook_name=\"$(_notebooks current)\"\n      _notebook_path=\"$(_notebooks current --path)\"\n    fi\n\n    if [[ -z \"${_notebook_name:-}\"  ]]\n    then\n      _exit_1 printf \"Unable to determine notebook name.\\\\n\"\n    fi\n\n    if [[ -z \"${_notebook_path:-}\"  ]]\n    then\n      _exit_1 printf \"Unable to determine notebook path.\\\\n\"\n    fi\n\n    if [[ -z \"${_subcommand}\"       ]]\n    then\n      printf \"%s\\\\n\" \"${_notebook_name}\"\n\n      return 0\n    fi\n\n    if [[ \"${_subcommand:-}\"    =~ (^open$|^o$) ]]\n    then\n      if _open_in_gui_app \"${_notebook_path:-}\"\n      then\n        return 0\n      else\n        _exit_1 printf                                                  \\\n          \"%s doesn't know how to open directories on this system.\\\\n\"  \\\n          \"$(_color_primary \"${_ME}\")\"\n      fi\n    elif [[ \"${_subcommand:-}\"  =~ (^peek$|^p$) ]]\n    then\n      if [[ -n \"${NB_DIRECTORY_TOOL:-}\" ]]\n      then\n        \"${NB_DIRECTORY_TOOL}\" \"${_notebook_path}\"\n      elif _command_exists \"ranger\"\n      then\n        ranger \"${_notebook_path}\"\n      elif _command_exists \"mc\"\n      then\n        mc \"${_notebook_path}\"\n      elif _command_exists \"vifm\"\n      then\n        vifm \"${_notebook_path}\"\n      elif _command_exists \"exa\"\n      then\n        exa -lah --git \"${_notebook_path}\"\n      else\n        # gnu || bsd\n        ls -lah --color=always \"${_notebook_path}\" 2>/dev/null ||\n          ls -lah -G \"${_notebook_path}\"\n      fi\n    else\n      local _dotfile_path=\"${_notebook_path}/.archived\"\n\n      if [[   \"${_subcommand}\" == \"archive\"   ]]\n      then\n        if [[ ! -e \"${_dotfile_path}\"         ]]\n        then\n          touch \"${_dotfile_path}\" &&\n            _git checkpoint \"${_notebook_path}\" \"[${_ME}] Archived\"\n        fi\n\n        printf \"%s archived.\\\\n\" \"$(_color_primary \"${_notebook_name}\")\"\n      elif [[ \"${_subcommand}\" == \"status\"    ]]\n      then\n        if [[   -e \"${_dotfile_path}\"         ]]\n        then\n          printf \"%s is archived.\\\\n\" \"$(_color_primary \"${_notebook_name}\")\"\n        else\n          printf \"%s is not archived.\\\\n\" \"$(_color_primary \"${_notebook_name}\")\"\n        fi\n      elif [[ \"${_subcommand}\" == \"unarchive\" ]]\n      then\n        if [[   -e \"${_dotfile_path}\"         ]]\n        then\n          rm \"${_dotfile_path:?}\" &&\n            _git checkpoint \"${_notebook_path}\" \"[${_ME}] Unarchived\"\n        fi\n\n        printf \"%s unarchived.\\\\n\" \"$(_color_primary \"${_notebook_name}\")\"\n      fi\n    fi\n  }\n\n  # _notebooks_rename()\n  #\n  # Usage:\n  #   _notebooks_rename <old> <new>\n  _notebooks_rename() {\n    local _new=\"${2:-}\"\n    local _old=\"${1:-}\"\n\n    _notebooks_validate_name \"${_old}\"\n    _notebooks_validate_name \"${_new}\"\n\n    if [[ -z \"${_old}\" ]] || [[ -z \"${_new}\"  ]]\n    then\n      _exit_1 _help notebooks\n    elif [[ -n \"${_LOCAL_NOTEBOOK_PATH:-}\"    ]]\n    then\n      if [[ \"${_old}\" == \"local\" ]] || [[ \"${_new}\" == \"local\" ]]\n      then\n        _exit_1 cat <<HEREDOC\n\"local\" refers to the local notebook and can not be renamed.\nHEREDOC\n      fi\n    elif [[ ! -d \"${NB_DIR}/${_old}\"  ]]\n    then\n      _exit_1 printf \"%s is not a valid notebook name.\\\\n\"        \\\n        \"$(_color_primary \"${_old}\")\"\n    elif [[ -e \"${NB_DIR}/${_new}\"    ]]\n    then\n      _exit_1 printf \"A notebook named \\\"%s\\\" already exists.\\\\n\" \\\n        \"$(_color_primary \"${_new}\")\"\n    fi\n\n    mv \"${NB_DIR}/${_old}\" \"${NB_DIR}/${_new}\"\n\n    if [[ \"$(cat \"${NB_DIR}/.current\")\" == \"${_old}\" ]]\n    then\n      printf \"%s\\\\n\" \"${_new}\" > \"${NB_DIR}/.current\"\n    fi\n\n    _temp cache clear\n\n    printf \"%s is now named %s\\\\n\"  \\\n      \"$(_color_primary \"${_old}\")\" \\\n      \"$(_color_primary \"${_new}\")\"\n  }\n\n  # _notebooks_select()\n  #\n  # Usage:\n  #   _notebook_select <selector>\n  _notebooks_select() {\n    local _selector=\"${1:-}\"\n\n    if [[ -z \"${_selector:-}\"       ]]\n    then\n      _exit_1 _help \"notebooks\"\n    fi\n\n    local _notebook_path=\n    _notebook_path=\"$(\n      _notebooks_show \"${_selector:-}\" --path 2>/dev/null || :\n    )\"\n\n    if [[ -n \"${_notebook_path:-}\"  ]] &&\n       [[ -d \"${_notebook_path:-}\"  ]]\n    then\n      NB_NOTEBOOK_PATH=\"${_notebook_path}\"\n\n      return 0\n    else\n      return 1\n    fi\n  }\n\n  # _notebooks_show()\n  #\n  # Usage:\n  #   _notebooks_show (<name> | <path> | <selector>) [--archived]\n  #                   [--escaped | --name | --path | --filename [<filename>]]\n  _notebooks_show() {\n    local _file_path=\n    local _local_notebook_path=\"${_LOCAL_NOTEBOOK_PATH:-}\"\n    local _notebook_color_enabled=1\n    local _notebook_path=\n    local _only_name=0\n    local _only_path=0\n    local _print_escaped_name=0\n    local _print_unique_file_path=0\n    local _selector=\n    local _test_archived=0\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --archived)\n          _test_archived=1\n          ;;\n        --escaped)\n          _print_escaped_name=1\n          ;;\n        --name)\n          _only_name=1\n          ;;\n        --no*color)\n          _notebook_color_enabled=0\n          ;;\n        --path)\n          _only_path=1\n          ;;\n        --filename|--basename|--file*path)\n          _print_unique_file_path=1\n\n          if _option_value_is_present \"${2:-}\"\n          then\n            _file_path=\"${2}\"\n\n            shift\n          fi\n          ;;\n        *)\n          if [[ -z \"${_selector}\"   ]]\n          then\n            _selector=\"${1:-}\"\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    if [[ -z \"${_selector:-}\"       ]]\n    then\n      _exit_1 _help \"notebooks\"\n    elif [[ \"${_selector:-}\" =~ ^/  ]]\n    then\n      local _maybe_notebook_path=\"${_selector}\"\n\n      while [[ -n \"${_maybe_notebook_path:-}\"         ]] &&\n            ! {\n              [[ -d \"${_maybe_notebook_path}/.git\"    ]] &&\n              [[ -f \"${_maybe_notebook_path}/.index\"  ]]\n            } && {\n              {\n                [[    \"${_maybe_notebook_path:-}\"   =~ ^${NB_DIR}     ]]  &&\n                [[ !  \"${_maybe_notebook_path%/*}\"  == \"${NB_DIR}\"    ]]\n              } || {\n                [[ !  \"${_maybe_notebook_path:-}\"   =~ ^${NB_DIR}     ]]\n              }\n            }\n      do\n        _maybe_notebook_path=\"${_maybe_notebook_path%/*}\"\n      done\n\n      if [[ -n \"${_maybe_notebook_path:-}\"    ]]\n      then\n        if [[ -n \"${_local_notebook_path:-}\"                          ]] &&\n           [[ \"${_maybe_notebook_path}\" == \"${_local_notebook_path}\"  ]]\n        then\n          _notebook_path=\"${_local_notebook_path%/}\"\n        else\n          _notebook_path=\"${_maybe_notebook_path%/}\"\n        fi\n      fi\n    elif [[ -n \"${_selector:-}\"               ]]\n    then\n      local _selector_notebook=\"${_selector%%:*}\"\n\n      if [[ -n \"${_selector_notebook:-}\"      ]]\n      then\n        if [[ \"${_selector_notebook:-}\" == \"local\"  ]] &&\n           [[ -n \"${_local_notebook_path:-}\"        ]]\n        then\n          _notebook_path=\"${_local_notebook_path%/}\"\n        elif [[ -e \"${NB_DIR}/${_selector_notebook:-}/.git\"    ]] &&\n             [[ -f \"${NB_DIR}/${_selector_notebook:-}/.index\"  ]]\n        then\n          _notebook_path=\"${NB_DIR}/${_selector_notebook%/}\"\n        fi\n      fi\n    fi\n\n    if [[ -z \"${_notebook_path:-}\"            ]]\n    then\n      _warn \\\n        printf \"Notebook not found: %s\\\\n\" \"$(_color_primary \"${_selector}\")\"\n\n      return 1\n    fi\n\n    if ((_only_path))\n    then\n      printf \"%s\\\\n\" \"${_notebook_path}\"\n\n      return 0\n    fi\n\n    if ((_test_archived))\n    then\n      if [[ -d \"${_notebook_path}/.archived\"  ]]\n      then\n        return 0\n      else\n        return 1\n      fi\n    fi\n\n    if ((_print_unique_file_path))\n    then\n      _get_unique_relative_path \"${_file_path:-\".${NB_DEFAULT_EXTENSION}\"}\"\n\n      return 0\n    fi\n\n    local _notebook_name=\n\n    if [[   \"${_notebook_path}\"   == \"${_LOCAL_NOTEBOOK_PATH:-}\"  ]] ||\n       [[ ! \"${_notebook_path:-}\" =~ ^${NB_DIR}                   ]]\n    then\n      _notebook_name=\"local\"\n    else\n      _notebook_name=\"$(basename \"${_notebook_path}\")\"\n    fi\n\n    if ((_only_name))\n    then\n      printf \"%s\\\\n\" \"${_notebook_name}\"\n\n      return 0\n    fi\n\n    local _escaped_name=\"${_notebook_name}\"\n\n    if [[ \"${_escaped_name}\" =~ \\         ]]\n    then\n      _escaped_name=\"$(\n        printf \"%s\\\\n\" \"${_escaped_name}\" | LC_ALL=C sed -e \"s/ /\\\\\\ /g\"\n      )\"\n    fi\n\n    if ((_print_escaped_name))\n    then\n      printf \"%s\\\\n\" \"${_escaped_name:-}\"\n\n      return 0\n    fi\n\n    if ((_notebook_color_enabled))        &&\n       [[ \"${_notebook_path}\" == \"${NB_NOTEBOOK_PATH}\"  ]]\n    then\n      _escaped_name=\"$(_color_primary \"${_escaped_name}\")\"\n    fi\n\n    local _notebook_line=\"${_escaped_name}\"\n\n    if [[ -e \"${_notebook_path}/.archived\"              ]]\n    then\n      _notebook_line=\"${_notebook_line} (archived)\"\n    fi\n\n    local _remote_url=\n    _remote_url=\"$(\n      git -C \"${_notebook_path}\" config --get remote.origin.url || echo ''\n    )\"\n\n    if [[ -n \"${_remote_url:-}\"           ]]\n    then\n      _notebook_line=\"${_notebook_line} (${_remote_url})\"\n    fi\n\n    printf \"%s\\\\n\" \"${_notebook_line}\"\n  }\n\n  # _notebooks_use()\n  #\n  # Usage:\n  #   _notebooks_use <name>\n  _notebooks_use() {\n    local _name=\"${1%:}\"\n\n    if [[ -z \"${_name}\"                   ]]\n    then\n      _exit_1 _help notebooks\n    fi\n\n    _notebooks_validate_name \"${_name}\"\n\n    if [[ -n \"${_LOCAL_NOTEBOOK_PATH}\"    ]]\n    then\n      _exit_1 cat <<HEREDOC\nCurrently in a local notebook. To run a command in a global notebook,\nadd the notebook name before the command name, separated by a colon:\n  ${_ME} <notebook>:<command> [options...]\n\n$(_color_primary \"Examples\"):\n  ${_ME} home:list\n  ${_ME} example:add --title \"Example Title\"\n  ${_ME} example:search \"sample query\"\nHEREDOC\n    fi\n\n    if [[ -e \"${NB_DIR}/${_name}/.index\"  ]]\n    then\n      printf \"%s\\\\n\" \"${_name}\" > \"${NB_DIR}/.current\"\n\n      _GLOBAL_NOTEBOOK_PATH=\"${NB_DIR}/${_name}\"\n      NB_NOTEBOOK_PATH=\"${_GLOBAL_NOTEBOOK_PATH}\"\n\n      printf \"Now using: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n    else\n      _exit_1 printf \"Not found: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n    fi\n  }\n\n  # Usage: _notebooks_validate_name <name>\n  _notebooks_validate_name() {\n    if _contains                                                \\\n      \"$(printf \"%s\\\\n\" \"${1:-}\" | tr '[:upper:]' '[:lower:]')\" \\\n      \"${_RESERVED_NOTEBOOK_NAMES[@]}\"\n    then\n      _warn printf \"Name reserved: %s\\\\n\" \"$(_color_primary \"${1:-}\")\"\n\n      return 1\n    else\n      return 0\n    fi\n  }\n\n  local _name=\"${2:-}\"\n  local _subcommand=\"${1:-}\"\n\n  if ! _contains \"${_subcommand:-}\" \"add\" \"author\" \"current\" \"init\" \"list\" \"show\"\n  then\n    _notebooks_add_new\n  fi\n\n  case \"${_subcommand}\" in\n    a|add|create|new|+)\n      shift\n\n      _notebooks_add      \"${@:-}\"\n      ;;\n    author|config*)\n      shift\n\n      _notebooks_author   \"${@:-}\"\n      ;;\n    export)\n      _notebooks_export   \"${2:-}\" \"${3:-}\"\n      ;;\n    import)\n      _notebooks_import   \"${2:-}\" \"${3:-}\"\n      ;;\n    init)\n      shift\n\n      _notebooks_init     \"${@:-}\"\n      ;;\n    current)\n      shift\n\n      _notebooks_current  \"${@:-}\"\n      ;;\n    d|delete|remove|rm|trash|-)\n      _notebooks_delete   \"${_name:-}\" \"${3:-}\"\n      ;;\n    list)\n      shift\n\n      _notebooks_list     \"${@:-}\"\n      ;;\n    rename|mv|move)\n      _notebooks_rename   \"${_name:-}\" \"${3:-}\"\n      ;;\n    select)\n      _notebooks_select   \"${2:-}\"\n      ;;\n    s|show)\n      shift\n\n      _notebooks_show     \"${@:-}\"\n      ;;\n    u|use)\n      _notebooks_use      \"${_name:-}\"\n      ;;\n    ar|archive|open|o|peek|p|st|status|unar|unarchive)\n      _notebooks_notebook \"${_subcommand}\" \"${_name:-}\"\n      ;;\n    *)\n      _notebooks_list     \"${@}\"\n      ;;\n  esac\n}\n_alias_subcommand \"notebooks\" \"n\"\n_alias_subcommand \"notebooks\" \"nb\"\n_alias_subcommand \"notebooks\" \"nbs\"\n_alias_subcommand \"notebooks\" \"notebook\"\n_alias_subcommand \"notebooks\" \"ns\"\n\n# subcommands · ################################################# · subcommands\n\n_describe_subcommands() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} subcommands [add <name>...] [alias <name> <alias>]\n                 [describe <name> <usage>]\n\n$(_color_primary \"Subcommands\"):\n  add       Add a new subcommand.\n  alias     Create an <alias> of a given subcommand <name>, with linked help.\n            Note that aliases must also be added with \\`subcommands add\\`.\n  describe  Set the usage text displayed with \\`${_ME} help <subcommand>\\`.\n            This can be assigned as a heredoc, which is recommended, or\n            as a string argument.\n\n$(_color_primary \"Description\"):\n  List, add, alias, and describe subcommands. New subcommands, aliases, and\n  descriptions are not persisted, so \\`add\\`, \\`alias\\`, \\`describe\\` are\n  primarily for plugins.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-plugins\n\n$(_color_primary \"See Also\"):\n  ${_ME} help plugins\nHEREDOC\n}\n_subcommands() {\n  case \"${1:-}\" in\n    add)\n      if [[ -n \"${2:-}\" ]]\n      then\n        shift\n\n        NB_PLUGIN_SUBCOMMANDS+=(\"${@:-}\")\n      fi\n      ;;\n    alias)\n      if [[ -n \"${2:-}\" ]] &&\n         [[ -n \"${3:-}\" ]]\n      then\n        _alias_subcommand \"${2:-}\" \"${3:-}\"\n      fi\n      ;;\n    describe)\n      shift\n\n      describe \"${@:-}\"\n      ;;\n    *)\n      printf \"%s\\\\n\" \"${_DOCUMENTED_SUBCOMMANDS[*]}\"\n      ;;\n  esac\n}\n_alias_subcommand \"subcommands\" \"commands\"\n\n###############################################################################\n# Plugins\n###############################################################################\n\n# $NB_PLUGIN_SUBCOMMANDS\n#\n# The list of subcommands exposed by plugins.\nNB_PLUGIN_SUBCOMMANDS=()\n\n# User defined plugins can be installed in the $NB_DIR/.plugins directory.\n# Plugins have a .nb-plugin or .nb-theme extension and are written in a\n# Bash-compatible shell scripting language.\n#\n# NOTE: Themes are loaded separately.\n__load_plugins() {\n  if [[ -d \"${NB_DIR}/.plugins\" ]]\n  then\n    set +f\n    local __file=\n    for   __file in \"${NB_DIR}/.plugins\"/*.\"${_ME}\"-plugin*\n    do\n      [[ -f \"${__file}\"                           ]] || continue\n      [[    \"${__file}\"  =~ /copy.${_ME}-plugin$  ]] && continue\n\n      source \"${__file}\" 2>/dev/null || :\n    done\n    set -f\n  fi\n}; __load_plugins\n\n###############################################################################\n# Program Option Parsing\n###############################################################################\n\n# _normalize_options()\n#\n# Usage:\n#   _normalize_options <option>...\n#\n# Description:\n#   Iterate over options, breaking -ab into -a -b and --foo=bar into --foo bar\n#   also turns -- into --endopts to avoid issues with things like '-o-', the\n#   '-' should not indicate the end of options, but be an invalid option (or\n#   the argument to the option, such as wget -qO-)\n#\n# Source:\n#   https://github.com/e36freak/templates/blob/master/options\n_NORMALIZED_OPTIONS=()\n_normalize_options() {\n  local _character=\n  local _character_string=\n  local _options=()\n\n  while ((${#}))\n  do\n    case \"${1}\" in\n      # if option is of type -ab\n      -[!-]?*)\n        if  [[ -n \"${_options[*]:-}\" ]]                 &&\n            _contains \"${_options[${#_options[@]}-1]}\"  \\\n              \"--append\"                                \\\n              \"--content\"                               \\\n              \"--overwrite\"                             \\\n              \"--prepend\"                               \\\n              \"add\"                                     \\\n              \"a\"                                       \\\n              \"+\"                                       \\\n              \"new\"\n        then\n          _options+=(\"${1}\")\n\n          shift\n        else\n          # loop over each character starting with the second\n          local i=\n          for ((i=1; i < ${#1}; i++))\n          do\n            _character=\"${1:i:1}\"\n            _character_string+=\"${_character}\"\n\n            if [[ ! \"${_character}\"     =~ [0-9]  ]] ||\n               [[ ! \"${1:$((i + 1)):1}\" =~ [0-9]  ]]\n            then\n              _options+=(\"-${_character_string}\")\n              _character_string=\n            fi\n          done\n\n          shift\n        fi\n        ;;\n      # if option is of type --foo=bar, split on first '='\n      --?*=*)\n        _options+=(\"${1%%=*}\" \"${1#*=}\")\n\n        shift\n        ;;\n      # end of options, stop breaking them up\n      --)\n        _options+=(--endopts)\n\n        shift\n\n        _options+=(\"${@}\")\n\n        break\n        ;;\n      # otherwise, nothing special\n      *)\n        _options+=(\"${1}\")\n\n        shift\n        ;;\n    esac\n  done\n\n  _NORMALIZED_OPTIONS=(\"${_options[@]}\")\n}; _normalize_options \"${@:-}\"\n\n# set new positional parameters to altered options. Set default to blank.\nset -- \"${_NORMALIZED_OPTIONS[@]:-}\"\n\n# Usage: _print_normalized_options\n_print_normalized_options() {\n  printf \"%s\\\\n\" \"${_NORMALIZED_OPTIONS[@]}\"\n}\n\n# Parse Options ###############################################################\n\n# Initialize program option variables.\n_ARGUMENTS=()\n_QUIET=0\n_SUBCOMMAND=\n_USE_DEBUG=0\n\n# $_SUBCOMMANDS\n#\n# All available subcommands.\n_SUBCOMMANDS=(\n  a\n  add\n  ar\n  archive\n  b\n  bk\n  bm\n  bookmark\n  bookmarks\n  br\n  browse\n  browser\n  close\n  commands\n  completions\n  config\n  copy\n  count\n  create\n  d\n  delete\n  \"do\"\n  \"done\"\n  duplicate\n  e\n  edit\n  export\n  env\n  f\n  folder\n  folders\n  git\n  grep\n  h\n  help\n  helpers\n  history\n  i\n  import\n  index\n  init\n  list\n  ls\n  move\n  mv\n  n\n  nb\n  nbs\n  new\n  notebook\n  notebooks\n  ns\n  o\n  open\n  p\n  peek\n  pin\n  plugin\n  plugins\n  preview\n  q\n  r\n  remote\n  rename\n  reset\n  rm\n  run\n  s\n  search\n  set\n  settings\n  shell\n  show\n  st\n  stat\n  status\n  subcommands\n  sync\n  t\n  task\n  tasks\n  trash\n  to\n  todo\n  todos\n  u\n  unar\n  unarchive\n  undo\n  undone\n  unpin\n  unset\n  update\n  upgrade\n  use\n  version\n  view\n  ${NB_PLUGIN_SUBCOMMANDS[@]:-}\n)\n\n# $_DOCUMENTED_SUBCOMMANDS\n#\n# Primary subcommands that appear in documentation. For example, some aliases\n# are omitted from this list. This list is also used for tab completion.\n_DOCUMENTED_SUBCOMMANDS=(\n  +\n  -\n  add\n  archive\n  b\n  bookmark\n  browse\n  commands\n  completions\n  copy\n  count\n  delete\n  \"do\"\n  edit\n  export\n  env\n  folders\n  git\n  help\n  history\n  import\n  init\n  list\n  ls\n  move\n  mv\n  notebooks\n  open\n  peek\n  pin\n  plugins\n  preview\n  q\n  remote\n  rename\n  run\n  search\n  set\n  settings\n  shell\n  show\n  st\n  status\n  subcommands\n  sync\n  tasks\n  todo\n  u\n  unarchive\n  undo\n  unpin\n  unset\n  update\n  use\n  version\n  ${NB_PLUGIN_SUBCOMMANDS[@]:-}\n)\n\n# $_GIT_SUBCOMMANDS\n#\n# Subcommands that initiate background cleanup commits and sync with remotes.\n_GIT_SUBCOMMANDS=(\n  a\n  add\n  ar\n  archive\n  b\n  bk\n  bm\n  bookmark\n  bookmarks\n  br\n  browse\n  browser\n  close\n  copy\n  count\n  create\n  d\n  delete\n  \"do\"\n  \"done\"\n  duplicate\n  e\n  edit\n  export\n  f\n  folder\n  folders\n  grep\n  i\n  import\n  list\n  ls\n  move\n  mv\n  n\n  nb\n  nbs\n  new\n  notebook\n  notebooks\n  ns\n  o\n  open\n  p\n  peek\n  pin\n  preview\n  q\n  rename\n  rm\n  s\n  show\n  search\n  t\n  task\n  tasks\n  to\n  todo\n  todos\n  u\n  unar\n  unarchive\n  undo\n  undone\n  unpin\n  use\n  view\n  ${NB_PLUGIN_SUBCOMMANDS[@]:-}\n)\n\n# $_SUBCOMMANDS_PATTERN\n#\n# The contents of the `$_SUBCOMMANDS` array, joined with '|'.\n_SUBCOMMANDS_PATTERN=\"^$(_join '$|^' \"${_SUBCOMMANDS[@]}\")$|^\\+$|^\\-$\"\n\n# $_GIT_SUBCOMMANDS_PATTERN\n#\n# The contents of the `$_GIT_SUBCOMMANDS` array, joined with '|'.\n_GIT_SUBCOMMANDS_PATTERN=\"^$(_join '$|^' \"${_GIT_SUBCOMMANDS[@]}\")$|^\\+$|^\\-$\"\n\n# _is_valid_subcommand()\n#\n# Usage:\n#   _is_valid_subcommand <name>\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If the given <name> is a valid subcommand name.\n#   1 (error,  false)  If not.\n_is_valid_subcommand() {\n  [[ -n \"${1:-}\" ]] &&  [[ \"${1:-}\" =~ ${_SUBCOMMANDS_PATTERN} ]]\n}\n\n# _parse_options()\n#\n# Usage:\n#   _parse_options <option>...\n#\n# Description:\n#   Parse program options.\n_parse_options() {\n  local _current_option=\n  local _non_option_arguments=()\n  local _previous_option=\n\n  while ((${#}))\n  do\n    _previous_option=\"${_current_option:-}\"\n\n    _current_option=\"${1:-}\"\n\n    shift\n\n    case \"${_current_option}\" in\n      -)\n        if [[ -z \"${_SUBCOMMAND:-}\"     ]]\n        then\n          _SUBCOMMAND=\"delete\"\n        else\n          _ARGUMENTS+=(\"delete\")\n        fi\n        ;;\n      +)\n        if [[ -z \"${_SUBCOMMAND:-}\"     ]]\n        then\n          _SUBCOMMAND=\"add\"\n        else\n          _ARGUMENTS+=(\"add\")\n        fi\n        ;;\n      -h|--help)\n        case \"${_SUBCOMMAND:-}\" in\n          git|run)\n            _ARGUMENTS+=(\"${_current_option}\")\n            ;;\n          *)\n            if [[ -n \"${_SUBCOMMAND:-}\" ]]\n            then\n              _ARGUMENTS+=(\"${_SUBCOMMAND}\")\n            fi\n\n            _SUBCOMMAND=\"help\"\n            ;;\n        esac\n        ;;\n      --debug)\n        _USE_DEBUG=1\n        ;;\n      --no*color)\n        _COLOR_ENABLED=0\n        ;;\n      --no*git|--skip*git)\n        _GIT_ENABLED=0\n        ;;\n      --quiet)\n        _QUIET=1\n        ;;\n      --version)\n        if [[ -n \"${_SUBCOMMAND:-}\"     ]]\n        then\n          _ARGUMENTS+=(\"${_current_option}\")\n        else\n          _SUBCOMMAND=\"version\"\n        fi\n        ;;\n      -i|--interactive)\n        case \"${_SUBCOMMAND:-}\" in\n          git|run)\n            _ARGUMENTS+=(\"${_current_option}\")\n            ;;\n          *)\n            _SUBCOMMAND=\"shell\"\n            ;;\n        esac\n        ;;\n      --welcome)\n        _print_welcome\n        ;;\n      *:*)\n        if [[ ! \"${_current_option:-}\"  =~ ^-         ]] &&\n           [[ ! \"${_previous_option:-}\" =~ ^-         ]]\n        then\n          _non_option_arguments+=(\"${_current_option}\")\n        fi\n\n        if [[ -z \"${_SUBCOMMAND:-}\"                   ]] &&\n            _string_is_url \"${_current_option}\"\n        then\n          _SUBCOMMAND=\"bookmark\"\n          _ARGUMENTS+=(\"${_current_option}\")\n        elif _notebooks current --selected\n        then\n          _ARGUMENTS+=(\"${_current_option}\")\n        elif _contains \"${_SUBCOMMAND:-\"${1:-}\"}\" \"copy\" \"move\" \"mv\" \"rename\" &&\n             (($((${#_non_option_arguments[@]} - 1))))\n        then\n          _ARGUMENTS+=(\"${_current_option}\")\n        elif [[ \"${_SUBCOMMAND:-}\" == \"delete\"        ]]\n        then\n          _ARGUMENTS+=(\"${_current_option}\")\n        elif _contains \"${_previous_option:-}\" \"-r\" \"--related\" \"--via\" \"--also\"\n        then\n          _ARGUMENTS+=(\"${_current_option}\")\n        else\n          local _selector_suffix=\"${_current_option#*:}\"\n\n          if [[ -z \"${_selector_suffix:-}\"            ]] &&\n             [[ -n \"${_SUBCOMMAND:-}\"                 ]] &&\n             [[ ! \"${_SUBCOMMAND}\" =~ (^ls$|^list$)   ]]\n          then\n            _ARGUMENTS+=(\"${_current_option}\")\n          else\n            if ! _notebooks select \"${_current_option}\"\n            then\n              if [[ -n \"${_SUBCOMMAND:-}\"             ]] ||\n                 [[    \"${_previous_option}\" =~ ^-    ]]\n              then\n                _ARGUMENTS+=(\"${_current_option}\")\n\n                continue\n              else\n                _exit_1 printf                \\\n                  \"Notebook not found: %s\\\\n\" \\\n                  \"$(_color_primary \"${_current_option%%:*}\")\"\n              fi\n            fi\n\n            if _is_valid_subcommand \"${_selector_suffix}\"\n            then\n              _SUBCOMMAND=\"${_selector_suffix}\"\n            else\n              if _string_is_url \"${_selector_suffix}\"\n              then\n                _SUBCOMMAND=\"bookmark\"\n                _ARGUMENTS+=(\"${_selector_suffix}\")\n              elif [[ \"${_selector_suffix}\" =~ ^-   ]]\n              then\n                _ARGUMENTS+=(\"${_selector_suffix}\")\n              else\n                _ARGUMENTS+=(\"${_current_option}\")\n              fi\n            fi\n          fi\n        fi\n        ;;\n      --endopts)\n        # Terminate option parsing.\n        break\n        ;;\n      *)\n        if [[     ! \"${_previous_option}\"   =~ ^-   ]]\n        then\n          if [[ -z \"${_SUBCOMMAND:-}\"               ]] &&\n             _is_valid_subcommand \"${_current_option}\"\n          then\n            _SUBCOMMAND=\"${_current_option}\"\n          else\n            if [[ ! \"${_current_option:-}\"  =~ ^-   ]]\n            then\n              _non_option_arguments+=(\"${_current_option}\")\n            fi\n\n            _ARGUMENTS+=(\"${_current_option}\")\n          fi\n        else\n          _ARGUMENTS+=(\"${_current_option}\")\n        fi\n        ;;\n    esac\n  done\n}; _parse_options \"${@:-}\"\n\n_debug printf \"\\${_SUBCOMMAND}:           '%s'\\\\n\"  \"${_SUBCOMMAND}\"\n_debug printf \"\\${NB_NOTEBOOK_PATH}:      '%s'\\\\n\"  \"${NB_NOTEBOOK_PATH}\"\n_debug printf \"\\${_LOCAL_NOTEBOOK_PATH}:  '%s'\\\\n\"  \"${_LOCAL_NOTEBOOK_PATH}\"\n_debug printf \"\\${_ARGUMENTS[*]:-}:       '%s'\\\\n\"  \"${_ARGUMENTS[*]:-}\"\n\n###############################################################################\n# Deprecated Functions and Variables\n#\n# TODO: Remove\n###############################################################################\n\n# _get_notebook_identifier()\n_get_notebook_identifier()  { _notebooks show \"${@}\" --escaped;   }\n\n# _get_selection_basename()\n_get_selection_basename()   { _show \"${@}\" --filename;            }\n\n# _get_unique_basename()\n_get_unique_basename()      { _get_unique_relative_path \"${@:-}\"; }\n\n# _set_selection_notebook() <selector>\n_set_selection_notebook()   {\n  if [[ \"${1:-}\" =~ : ]]\n  then\n    if _notebooks select \"${1:-}\"\n    then\n      _NOTEBOOK_PATH=\"${NB_NOTEBOOK_PATH}\"\n    fi\n  elif [[ \"${_NOTEBOOK_PATH:-}\" != \"${NB_NOTEBOOK_PATH}\" ]]\n  then\n    _NOTEBOOK_PATH=\"${NB_NOTEBOOK_PATH}\"\n  fi\n}\n\n# $_NOTEBOOK_PATH\n# shellcheck disable=SC2034\nexport _NOTEBOOK_PATH=\"${_NOTEBOOK_PATH:-\"${NB_NOTEBOOK_PATH}\"}\"\n\n# $_SCOPE\n# shellcheck disable=SC2034\n# _SCOPE=\"$(_notebooks current --name)\"\n_SCOPE=\"$(basename \"${NB_NOTEBOOK_PATH}\")\"\n\n# $_SCOPED\n# shellcheck disable=SC2034\n_SCOPED=\"$(\n  # if _notebooks current --selected\n  if [[ \"${NB_NOTEBOOK_PATH}\" != \"${_GLOBAL_NOTEBOOK_PATH}\" ]]\n  then\n    printf \"1\\\\n\"\n  else\n    printf \"0\\\\n\"\n  fi\n)\"\n\n# color functions\n_color_dim()          { _color_muted    \"${@:-}\"; }\n_highlight()          { _color_primary  \"${@:-}\"; }\n_id_brackets_color()  { _color_brackets \"${@:-}\"; }\n\n###############################################################################\n# _defer()\n###############################################################################\n\n# $_DEFERRED_COMMAND\n#\n# The function and arguments to run after the script has loaded.\n_DEFERRED_COMMAND=()\n\n# _defer()\n#\n# Usage:\n#   _defer <name> [<argument>...]\n#\n# Description:\n#   Assign a command to run after the script has loaded.\n_defer() {\n  _DEFERRED_COMMAND=(\"${@:-}\")\n}\n\n# _call_deferred_command()\n#\n# Usage:\n#   _call_deferred_command --group <num>\n#\n# Description:\n#   Call the deferred command.\n_call_deferred_command() {\n  [[ -z \"${_DEFERRED_COMMAND[0]:-}\" ]] && exit 0\n\n  local _group=\"${2:-}\"\n  local _group_3_names=(\n    _ar _archive _b _bookmark _br _browse _browser _close _config _copy _do   \\\n    _done _duplicate _f _folder _folders _h _help _helpers _set _plugin       \\\n    _plugins _remote _reset _settings _shell _st _stat _status _sync _t _task \\\n    _tasks _to _todo _todos _unar _unarchive _undo _undone _unset _update     \\\n    _upgrade\n  )\n\n  if {\n       [[ \"${_group:-}\" -eq 2 ]] &&\n         _contains \"${_DEFERRED_COMMAND[0]:-}\" \"${_group_3_names[@]}\"\n     } || {\n       [[ \"${_group:-}\" -eq 3 ]] &&\n       ! _contains \"${_DEFERRED_COMMAND[0]:-}\" \"${_group_3_names[@]}\"\n     }\n  then\n    return 0\n  else\n    \"${_DEFERRED_COMMAND[@]:-}\"\n\n    return 0\n  fi\n}\n\n###############################################################################\n# _main()\n###############################################################################\n\n# _main()\n#\n# Usage:\n#   _main \"$@\"\n#\n# Description:\n#   Primary entry point for the program logic. Call this function at the end\n#   of the script after everything has been defined.\n_main() {\n  if [[ -z \"${_SUBCOMMAND:-}\" ]]\n  then\n    _SUBCOMMAND=\"ls\"\n  fi\n\n  case \"${_SUBCOMMAND}\" in\n    init|sync)\n      _git required\n      _defer \"_${_SUBCOMMAND}\" \"${@:-}\"\n      ;;\n    commands|completions|env|git|h|help*|r|run|set|settings|subcommands|update|version)\n      _defer \"_${_SUBCOMMAND}\" \"${@:-}\"\n      ;;\n    *)\n      _git required\n\n      # Call `_init()` if configuration hasn't been initialized.\n      if [[ ! -e \"${NB_DIR}\"            ]] ||\n         [[ ! -e \"${NB_NOTEBOOK_PATH}\"  ]]\n      then\n        _init \"${@:-}\"\n\n        _ls || true # returns 0 due to empty repository.\n\n        return 0\n      fi\n\n      if [[ \"${_SUBCOMMAND}\" =~ ${_GIT_SUBCOMMANDS_PATTERN} ]]\n      then\n        if _git dirty \"${NB_NOTEBOOK_PATH}\"\n        then\n          _index reconcile\n\n          _git checkpoint \"${NB_NOTEBOOK_PATH}\" --wait\n        elif _git autosyncable \"${NB_NOTEBOOK_PATH}\" && _git out_of_sync\n        then\n          _git checkpoint \"${NB_NOTEBOOK_PATH}\" --wait\n        fi\n      fi\n\n      if [[ \"${_SUBCOMMAND}\" == \"ls\" ]]\n      then\n        # Run `ls` on its own, exiting at the end in order to avoid running /\n        # loading the rest of the script.\n        \"_${_SUBCOMMAND}\" \"${@}\" --exit\n      else\n        # Defer subcommand call until the rest of the script has been loaded.\n        _defer \"_${_SUBCOMMAND}\" \"${@:-}\"\n\n        return 0\n      fi\n      ;;\n  esac\n}\n\n_main \"${_ARGUMENTS[@]:-}\"\n\n###############################################################################\n# Configuration: Group 2                                 Configuration: Group 2\n# ----------------------                                 ----------------------\n###############################################################################\n# --------------------------------------------------------------------------- #\n\n# $NB_BROWSE_MARKDOWN_READER\n#\n# Default: 'markdown+emoji+raw_html+east_asian_line_breaks'\n#\n# The Pandoc reader, including extensions, to use for converting Markdown to\n# HTML in `nb browse`.\n#\n# More information:\n# https://pandoc.org/MANUAL.html#extensions\n# https://pandoc.org/MANUAL.html#general-options-1\nexport NB_BROWSE_MARKDOWN_READER=\"${NB_BROWSE_MARKDOWN_READER:-\"markdown+emoji+raw_html+east_asian_line_breaks\"}\"\n\n# $NB_BROWSE_SERVER_TOOL\n#\n# Default: '' (automatically assigned)\n#\n# Supported Values: accept, bash, ncat, nc, netcat\nexport NB_BROWSE_SERVER_TOOL=\"${NB_BROWSE_SERVER_TOOL:-}\"\n\n__set_browse_server_tool() {\n  if [[ -z \"${NB_BROWSE_SERVER_TOOL:-}\"     ]]\n  then\n    if [[ \"${OSTYPE}\" =~ cygwin|msys|win32  ]]\n    then\n      if _command_exists \"socat\"\n      then\n        NB_BROWSE_SERVER_TOOL=\"socat\"\n      elif _command_exists \"ncat\"\n      then\n        NB_BROWSE_SERVER_TOOL=\"ncat\"\n      fi\n    elif _command_exists \"ncat\"\n    then\n      NB_BROWSE_SERVER_TOOL=\"ncat\"\n    elif _command_exists \"socat\"\n    then\n      NB_BROWSE_SERVER_TOOL=\"socat\"\n    elif _command_exists \"nc\" && nc --help &>/dev/null\n    then # GNU nc / netcat is present\n      NB_BROWSE_SERVER_TOOL=\"nc\"\n    elif [[ \"${BASH_VERSINFO[0]}\" -ge 5             ]] &&\n         [[ \"${BASH_VERSINFO[1]}\" -ge 2             ]] &&\n         [[ -f \"${BASH%/bin/bash}/lib/bash/accept\"  ]]\n    then\n      NB_BROWSE_SERVER_TOOL=\"accept\"\n    fi\n  fi\n}; __set_browse_server_tool\n\n###############################################################################\n# Helpers: Group 2                                             Helpers: Group 2\n# ----------------                                             ----------------\n###############################################################################\n# --------------------------------------------------------------------------- #\n\n# _build_related_list()\n#\n# Usage:\n#   _build_related_list (<url> | <selector>)...\n#\n# Description:\n#   Build a Markdown-formatted list of <url>s and <selector>s for bookmarks\n#   and todos.\n_build_related_list() {\n  local _list_content=\n  local _related_identifiers=(\"${@:-}\")\n\n  local __identifier=\n  for   __identifier in \"${_related_identifiers[@]:-}\"\n  do\n    [[ -n \"${__identifier:-}\" ]] || continue\n\n    if _string_is_url \"${__identifier:-}\"\n    then\n      _list_content+=\"- <${__identifier:-}>${_NEWLINE}\"\n    else\n      if [[ \"${__identifier:-}\" =~ \\[\\[.*\\]\\] ]]\n      then\n        __identifier=\"$(\n          LC_ALL=C sed -E -e \"s/\\[\\[(.*)\\]\\]/\\1/g\" <<< \"${__identifier:-}\"\n        )\"\n      fi\n\n      _list_content+=\"- [[${__identifier:-}]]${_NEWLINE}\"\n    fi\n  done\n\n  printf \"%s\\\\n\" \"${_list_content:-}\"\n}\n\n# _decrypt_file()\n#\n# Usage:\n#   _decrypt_file <path> <password>\n_decrypt_file() {\n  local _encrypted_path=\"${1:-}\"\n  local _password=\"${2:-}\"\n\n  if [[ -z \"${_encrypted_path}\" ]]\n  then\n    return 1\n  fi\n\n  local _notebook_and_relative_path=\"${_encrypted_path#\"${NB_DIR}\"/}\"\n\n  local _unencrypted_path=\n  _unencrypted_path=\"$(_temp file \"${_notebook_and_relative_path%.enc}\")\"\n\n  local _file_command_response=\n  _file_command_response=\"$(file \"${_encrypted_path}\" 2>/dev/null || :)\"\n\n  local _decryption_tool=\n  _decryption_tool=\"$(_get_decryption_tool \"${_encrypted_path:-}\")\"\n\n  case \"${_decryption_tool:-}\" in\n    age)\n      if _command_exists \"age\"\n      then\n        age                                 \\\n          --decrypt                         \\\n          --output \"${_unencrypted_path}\"   \\\n          \"${_encrypted_path}\"\n      else\n        _exit_1 printf                      \\\n\"This item was encrypted with \\`age\\`, but the \\`age\\` command was not found.\\\\n\"\n      fi\n      ;;\n    gpg)\n      if _command_exists \"gpg\"\n      then\n        printf \"%s\\\\n\" \"${_password}\"       \\\n          | gpg                             \\\n            --batch                         \\\n            --quiet                         \\\n            --passphrase-fd 0               \\\n            --output \"${_unencrypted_path}\" \\\n            --decrypt \"${_encrypted_path}\"\n      else\n        _exit_1 printf                      \\\n\"This item was encrypted with GPG, but the GPG command was not found.\\\\n\"\n      fi\n      ;;\n    openssl)\n      openssl enc                           \\\n        -d                                  \\\n        -aes-256-cbc                        \\\n        -in   \"${_encrypted_path}\"          \\\n        -md   sha256                        \\\n        -out  \"${_unencrypted_path}\"        \\\n        -pass file:<(printf \"%s\\\\n\" \"${_password}\") 2> /dev/null      || {\n          if [[ -f \"${_unencrypted_path:?}\" ]]\n          then\n            rm \"${_unencrypted_path:?}\"\n          fi\n\n          openssl enc                       \\\n            -d                              \\\n            -aes-256-cbc                    \\\n            -in   \"${_encrypted_path}\"      \\\n            -md   md5                       \\\n            -out  \"${_unencrypted_path}\"    \\\n            -pass file:<(printf \"%s\\\\n\" \"${_password}\") 2> /dev/null  ||\n              if [[ -f \"${_unencrypted_path:?}\" ]]\n              then\n                rm \"${_unencrypted_path:?}\"\n              fi\n        }\n      ;;\n    *)\n      _exit_1 printf \"Unable to decrypt file.\\\\n\"\n      ;;\n  esac\n\n  if [[ ! -e \"${_unencrypted_path}\" ]]\n  then\n    _exit_1 printf \"Decryption error.\\\\n\" 1>&2\n  fi\n\n  printf \"%s\\\\n\" \"${_unencrypted_path}\"\n}\n\n# _download_from()\n#\n# Usage:\n#   _download_from <url> [<outfile>] [--no-chrome]\n#\n# Description:\n#   Download the file at <url> and print to standard output or <outfile>, if\n#   present.\n_download_from() {\n  local _download_command=\"${NB_DOWNLOAD_TOOL:-}\"\n  local _downloaded=0\n  local _no_chrome=0\n  local _target_path=\n  local _timeout=15\n  local _url=\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      --no*chrome|--skip*chrome)\n        _no_chrome=1\n        ;;\n      *)\n        if [[   -z \"${_url:-}\"          ]]\n        then\n          _url=\"${1:-}\"\n        elif [[ -z \"${_target_path:-}\"  ]]\n        then\n          _target_path=\"${1:-}\"\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  if [[ -z \"${_url}\" ]] ||\n     [[ !  \"${_url}\" =~ (^https\\:|^http\\:|^file\\:|^ftp\\:|^sftp\\:) ]]\n  then\n    return 1\n  fi\n\n  if  ! ((_no_chrome))                          &&\n      [[ -z \"${_download_command:-}\"        ]]  &&\n      {\n        [[ \"${_url}\"    =~ \\.html$          ]]  ||\n        [[ \"${_url}\"    =~ \\.php$           ]]  ||\n        [[ ! \"${_url}\"  =~ \\.[a-zA-Z0-9]+$  ]]\n      }                                         &&\n      [[ ! \"${_url}\" =~ ^https://www.reddit.com ]]\n  then\n    if _command_exists \"google-chrome\"\n    then\n      _download_command=\"google-chrome\"\n    elif _command_exists \"chromium\"\n    then\n      _download_command=\"chromium\"\n    elif _command_exists \"chromium-browser\"\n    then\n      _download_command=\"chromium-browser\"\n    elif [[ -x \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\" ]]\n    then\n      _download_command=\"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\"\n    elif [[ -x \"/Applications/Chromium.app/Contents/MacOS/Chromium\"           ]]\n    then\n      _download_command=\"/Applications/Chromium.app/Contents/MacOS/Chromium\"\n    fi\n  fi\n\n  if ((_no_chrome)) && [[ \"${_download_command:-}\" =~ hrome|hromium ]]\n  then\n    _download_command=\n  fi\n\n  if [[ -z \"${_download_command:-}\" ]]\n  then\n    if _command_exists \"curl\"\n    then\n      _download_command=\"curl\"\n    elif _command_exists \"wget\"\n    then\n      _download_command=\"wget\"\n    fi\n  fi\n\n  case \"${_download_command:-}\" in\n    *hrome*|*hromium*)\n      {\n        \"${_download_command:-}\"  \\\n          --dump-dom              \\\n          --headless              \\\n          \"${_url}\"               \\\n          2>/dev/null\n      } | {\n        if [[ -n \"${_target_path:-}\" ]]\n        then\n          cat > \"${_target_path:-}\"\n        else\n          cat\n        fi\n      } && _downloaded=1\n      ;;\n    curl*)\n      local _curl_options=(\n        --silent\n        --location\n        --connect-timeout \"${_timeout}\"\n        --compressed\n        \"${_url}\"\n      )\n\n      [[ -n \"${NB_USER_AGENT:-}\" ]]   &&\n        _curl_options+=(--user-agent \"${NB_USER_AGENT}\")\n\n      if [[ -n \"${_target_path}\" ]]\n      then\n        curl                          \\\n          \"${_curl_options[@]}\"       \\\n          --output \"${_target_path}\"  \\\n          && _downloaded=1\n      else\n        curl                          \\\n          \"${_curl_options[@]}\"       \\\n          && _downloaded=1\n      fi\n      ;;\n    wget*)\n      local _wget_options=(\n        --quiet\n        --connect-timeout=\"${_timeout}\"\n        --dns-timeout=\"${_timeout}\"\n        --compression=auto\n        \"${_url}\"\n      )\n\n      [[ -n \"${NB_USER_AGENT:-}\" ]]   &&\n        _wget_options+=(--user-agent=\"${NB_USER_AGENT}\")\n\n      if [[ -n \"${_target_path}\" ]]\n      then\n        wget                          \\\n          \"${_wget_options[@]}\"       \\\n          -O \"${_target_path}\"        \\\n          2>/dev/null                 \\\n          && _downloaded=1\n      else\n        wget                          \\\n          \"${_wget_options[@]}\"       \\\n          -O -                        \\\n          2>/dev/null                 \\\n          && _downloaded=1\n      fi\n      ;;\n  esac\n\n  if ! ((_downloaded))\n  then\n    return 1\n  fi\n}\n\n# _edit_file()\n#\n# Usage:\n#   _edit_file <path> [--no-wait]\n#\n# Description:\n#   Open the file in $EDITOR. Use the `-f` option in vim and `--wait` option in\n#   other GUI editors to wait until the file is closed in the editor before\n#   continuing, unless `--no-wait`.\n_edit_file() {\n  local _file_path=\"${1:-}\"\n  local _wait=1\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      --no-wait)\n        _wait=0\n        ;;\n      *)\n        if [[ -z \"${_file_path}\"  ]]\n        then\n          _file_path=\"${__arg}\"\n        fi\n        ;;\n    esac\n  done\n\n  if [[ -z \"${_file_path}\"        ]]\n  then\n    return 1\n  fi\n\n  local _current_notebook_path=\n  _current_notebook_path=\"$(_notebooks current --path)\"\n\n  cd \"${_current_notebook_path}\"  ||  return 1\n\n  if [[ -e \"${_file_path}\"            ]]\n  then\n    if _file_is_encrypted \"${_file_path}\"\n    then\n      _exit_1 printf                  \\\n\"File must be decrypted before editing.\\\\n\"\n    fi\n\n    if _file_is_archive \"${_file_path}\"   &&\n       [[ ! \"${_file_path}\" =~ docx$  ]]\n    then\n      _exit_1 printf                  \\\n\"Can't edit archives. Export archive and expand to edit.\\\\n\"\n    fi\n\n    if ! _file_is_text \"${_file_path}\"    &&\n       [[ ! -d \"${_file_path}\"        ]]\n    then\n      if _open_in_gui_app \"${_file_path:-}\"\n      then\n        return 0\n      else\n        _exit_1 printf                                \\\n          \"%s doesn't know how to edit this file.\\\\n\" \\\n          \"$(_color_primary \"${_ME}\")\"\n      fi\n    fi\n  fi\n\n  local _editor_command=\"${NB_EDITOR}\"\n\n  # turn on case-insensitive matching\n  shopt -s nocasematch\n\n  if ((_wait))\n  then\n    case \"${NB_EDITOR}\" in\n      *gvim*|*mvim*)\n        _editor_command=\"${_editor_command} -f\"\n        ;;\n      *code*|*mate*|*subl*)\n        _editor_command=\"${_editor_command} --wait\"\n        ;;\n    esac\n  fi\n\n  if [[ -d \"${_file_path}\"    ]] &&\n     [[ \"${NB_EDITOR}\" =~ vim ]]\n  then\n    cd \"${_file_path}\" && \"${_editor_command:-}\"\n  else\n    if [[ \"${NB_EDITOR}\" =~ typora  ]] &&\n       [[ ! -f \"${_file_path:-}\"    ]]\n    then\n      touch \"${_file_path:-}\"\n    fi\n\n    eval \"${_editor_command} \\\"${_file_path}\\\"\"\n\n    if [[ \"${NB_EDITOR}\" =~ (typora|open\\ -a) ]]\n    then\n      printf \"Editing with %s\\\\n\" \"$(_color_primary \"${NB_EDITOR}\")\"\n\n      while true\n      do\n        read -n 1 -s -r -p \"Press any key to save changes and exit$(_color_muted \"...\")\"\n\n        printf \"\\\\n\"\n\n        break\n      done\n    fi\n  fi\n\n  # turn off case-insensitive matching\n  shopt -u nocasematch\n\n  return 0\n}\n\n# _encrypt_file()\n#\n# Usage:\n#   _encrypt_file <unencrypted-path> <encrypted-path>\n#                 [--password <password>] [--tool <tool>]\n_encrypt_file() {\n  local _encrypted_path=\"${2:-}\"\n  local _password=\n  local _tool=\"${NB_ENCRYPTION_TOOL}\"\n  local _unencrypted_path=\"${1:-}\"\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      --password)\n        if _option_value_is_present \"${2:-}\"\n        then\n          _password=\"${2:-}\"\n\n          shift\n        fi\n        ;;\n      --tool)\n        if _option_value_is_present \"${2:-}\"\n        then\n          _tool=\"${2:-}\"\n\n          shift\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  if [[ -z \"${_password:-}\"       ]]  &&\n     [[    \"${_tool}\" != \"age\"    ]]\n  then\n    _exit_1 printf \"Password required.\\\\n\"\n  fi\n\n  if [[ -z \"${_unencrypted_path}\" ]]  ||\n     [[ -z \"${_encrypted_path}\"   ]]\n  then\n    _exit_1 printf \"Encrypted and unencrypted paths required.\\\\n\"\n  fi\n\n  if [[   \"${_tool}\" == \"age\"         ]]\n  then\n    age                               \\\n      --encrypt                       \\\n      --output \"${_encrypted_path}\"   \\\n      --passphrase                    \\\n      \"${_unencrypted_path}\"\n  elif [[ \"${_tool}\" == \"gpg\"         ]]\n  then\n    printf \"%s\\\\n\" \"${_password}\"     \\\n      | gpg                           \\\n        --batch                       \\\n        --cipher-algo AES256          \\\n        --quiet                       \\\n        --output \"${_encrypted_path}\" \\\n        --passphrase-fd 0             \\\n        --symmetric                   \\\n        \"${_unencrypted_path}\"\n  elif [[ \"${_tool}\" == \"openssl\"     ]]\n  then\n    openssl enc                       \\\n      -aes-256-cbc                    \\\n      -in   \"${_unencrypted_path}\"    \\\n      -md   sha256                    \\\n      -out  \"${_encrypted_path}\"      \\\n      -pass file:<(printf \"%s\\\\n\" \"${_password}\") 2>/dev/null\n  else\n    _exit_1 printf                    \\\n      \"\\$NB_ENCRYPTION_TOOL must be set to 'gpg' or 'openssl'.\\\\n\"\n  fi\n\n  if [[ ! -e \"${_encrypted_path}\"     ]]\n  then\n    _exit_1 printf \"Encryption error.\\\\n\"\n  fi\n}\n\n# _get_decryption_tool()\n#\n# Usage:\n#   _get_decryption_tool <path>\n#\n# Description:\n#   Print the name of the tool to use to decrypt the file at <path>.\n_get_decryption_tool() {\n  local _decryption_tool=\n  local _encrypted_path=\"${1:-}\"\n\n  if _command_exists \"file\"\n  then\n    local _file_command_response=\n    _file_command_response=\"$(file \"${_encrypted_path}\" 2>/dev/null || :)\"\n\n    if [[   \"${_file_command_response}\" =~ (GPG|PGP)  ]]\n    then\n      _decryption_tool=\"gpg\"\n    elif [[ \"${_file_command_response}\" =~ openssl    ]]\n    then\n      _decryption_tool=\"openssl\"\n    elif [[ \"${_file_command_response}\" =~ data       ]]\n    then\n      local         __first_line=\n      IFS=  read -r __first_line < \"${_encrypted_path}\"\n\n      if [[ \"${__first_line:-}\" =~ age-encryption     ]]\n      then\n        _decryption_tool=\"age\"\n      fi\n    fi\n  else\n    # Read the first line and first 16 bytes (for binary signatures)\n    local _first_line=\n    IFS= read -r _first_line < \"${_encrypted_path}\"\n\n    local _first_bytes=\n    _first_bytes=\"$(head -c 16 \"${_encrypted_path}\" | xxd -p)\"\n\n    if [[ \"${_first_line}\" == age-encryption* ]]\n    then # age\n      _decryption_tool=\"age\"\n    elif [[ \"${_first_line}\" == \"-----BEGIN PGP MESSAGE-----\" ]] ||\n         [[ \"${_first_line}\" == \"-----BEGIN GPG MESSAGE-----\" ]]\n    then # GPG/PGP ASCII armored header\n      _decryption_tool=\"gpg\"\n    elif [[ \"${_first_bytes}\" =~ ^8c ]] || [[ \"${_first_bytes}\" =~ ^99 ]]\n    then # GPG binary (magic number: 0x8c/0x99 at start, but can be more complicated)\n      _decryption_tool=\"gpg\"\n    elif head -c 8 \"${_encrypted_path}\" | grep -q \"^Salted__\"\n    then # OpenSSL (Salted__ in ASCII at start)\n      _decryption_tool=\"openssl\"\n    fi\n  fi\n\n  printf \"%s\\\\n\" \"${_decryption_tool:-}\"\n}\n\n# _get_hash()\n#\n# Usage:\n#   _get_hash <path>\n#\n# Description:\n#   Generate a hash for the file or directory at <path>.\n_get_hash() {\n  # Usage: _get_hash_with_command <path> <command>\n  _get_hash_with_command() {\n    local _command=\n    IFS=' ' read -ra _command <<< \"${2:-}\"\n\n    local _path=\"${1:-}\"\n\n    [[ -n \"${_command[*]:-}\" ]] && [[ -n \"${_path}\" ]] || return 1\n\n    if [[ -d \"${_path}\" ]]\n    then\n      tar -P -cf - \"${_path}\"     \\\n        | \"${_command[@]}\"        \\\n        | awk '{ print $1 }'\n    else\n      \"${_command[@]}\" \"${_path}\" \\\n        | awk '{print $1}'\n    fi\n  }\n\n  local _path=\"${1:-}\"\n  [[ -n \"${_path:-}\" ]] || return 1\n\n  if _command_exists \"shasum\"\n  then\n    _get_hash_with_command \"${_path}\" \"shasum -a 256\"\n  elif _command_exists \"md5sum\"\n  then\n    _get_hash_with_command \"${_path}\" \"md5sum\"\n  elif _command_exists \"md5\"\n  then\n    _get_hash_with_command \"${_path}\" \"md5 -q\"\n  else\n    _exit_1 printf \"No hashing tool found.\\\\n\"\n  fi\n}\n\n# _get_http_status()\n#\n# Usage:\n#   _get_http_status <url>\n#\n# Description:\n#   Print the http status response code for <url>.\n_get_http_status() {\n  local _url=\"${1:-}\"\n  [[ -n \"${_url:-}\" ]] || return 1\n\n  if _command_exists \"curl\"\n  then\n    local _curl_options=(\n      --head\n      --silent\n      --output /dev/null\n      -w \"%{http_code}\\\\n\"\n    )\n\n    [[ -n \"${NB_USER_AGENT:-}\" ]] &&\n      _curl_options+=(--user-agent \"${NB_USER_AGENT}\")\n\n    curl \"${_curl_options[@]}\" \"${_url}\" || return 0\n  elif _command_exists \"wget\"\n  then\n    local _wget_options=(\n      --server-response\n    )\n\n    [[ -n \"${NB_USER_AGENT:-}\" ]] &&\n      _wget_options+=(--user-agent=\"${NB_USER_AGENT}\")\n\n    wget \"${_wget_options[@]}\" \"${_url}\" 2>&1 \\\n      | grep \"HTTP/\" | awk '{print $2}' || return 0\n  fi\n}\n\n# _get_sanitized_filename()\n#\n# Usage:\n#   _get_sanitized_file_name <input>\n#\n# Description:\n#   Get a santized filename derived from an input string, such as a title.\n_get_sanitized_filename() {\n  printf \"%s\" \"${1:-}\"                          \\\n    | LC_ALL=C sed -E                           \\\n        -e 's/^[[:space:]]+//g'                 \\\n        -e 's/[[:space:]]+$//g'                 \\\n        -e 's/\\[[[:space:]]*\\][[:space:]]*//g'  \\\n        -e 's/\\[x\\][[:space:]]*//g'             \\\n    | tr '[:upper:]' '[:lower:]'                \\\n    | tr '[:space:]:*/\\\\<>?|' '_'               \\\n    | tr \"\\\"\" '_'\n}\n\n# _get_unique_path()\n#\n# Usage:\n#   _get_unique_path <path>\n#\n# Description:\n#   Get a unique full path that doesn't conflict with any existing file.\n_get_unique_path() {\n  local _path=\"${1:-}\"\n\n  local _dir_path=\n  _dir_path=\"$(dirname \"${_path}\")\"\n\n  local _basename=\n  _basename=\"$(basename \"${_path}\")\"\n\n  local _file_name=\"${_basename%%.*}\"\n  local _file_extension=\"${_basename#*.}\"\n\n  if [[ -n \"${_file_extension:-}\"               ]] &&\n     [[ \"${_basename}\"  =~ \\.                   ]] &&\n     [[ \"${_file_name}\" != \"${_file_extension}\" ]]\n  then\n    _file_extension=\".${_file_extension}\"\n  else\n    _file_extension=\n  fi\n\n  local _unique_file_name=\"${_file_name}\"\n  local _uniqueness_counter=0\n\n  while [[ -e \"${_dir_path}/${_unique_file_name}${_file_extension}\"     ]] ||\n        [[ -e \"${_dir_path}/${_unique_file_name}${_file_extension}.enc\" ]]\n  do\n    _uniqueness_counter=\"$((_uniqueness_counter+1))\"\n\n    printf -v _unique_file_name -- \"%s-%01d\"  \\\n      \"${_file_name}\"                         \\\n      \"${_uniqueness_counter}\"\n  done\n\n  printf \"%s\\\\n\" \"${_dir_path}/${_unique_file_name}${_file_extension}\"\n}\n\n# _get_unique_relative_path()\n#\n# Usage:\n#   _get_unique_relative_path [<file-path>[<extension>] [<notebook-path>]\n#\n# Description:\n#   Get a unique basename that doesn't conflict with any existing file.\n_get_unique_relative_path() {\n  local _file_path=\"${1:-}\"\n  local _notebook_path=\"${2:-\"$(_notebooks current --path)\"}\"\n\n  local _file_basename=\"${_file_path##*/}\" # strip ancestors\n  local _file_name=\"${_file_basename%%.*}\" # strip extension\n  local _folder_path=\n  local _target_basename=\n  local _unique_path=\n\n  if [[ -z \"${_file_name:-}\"    ]]\n  then\n    _file_name=\"$(date \"+%Y%m%d%H%M%S\")\"\n  fi\n\n  if [[ \"${_file_path:-}\" =~ /  ]]\n  then\n    _folder_path=\"${_file_path%\\/*}\"\n  fi\n\n  if [[ \"${_file_basename:-}\" =~ ^\\.  ]]\n  then\n    local _file_type=\"${_file_basename#*.}\"\n\n    _target_basename=\"${_file_name}.${_file_type}\"\n  elif [[ -n \"${_file_basename:-}\"    ]]\n  then\n    _target_basename=\"${_file_basename}\"\n  else\n    _target_basename=\"${_file_name}\"\n  fi\n\n  _unique_path=\"$(\n    if [[ -n \"${_folder_path:-}\" ]]\n    then\n      _get_unique_path \"${_notebook_path}/${_folder_path}/${_target_basename}\"\n    else\n      _get_unique_path \"${_notebook_path}/${_target_basename}\"\n    fi\n  )\"\n\n  printf \"%s\" \"${_unique_path#\"${_notebook_path}\"/}\"\n}\n\n# _get_uri()\n#\n# Usage:\n#   _get_uri [--encode | --decode] <string>\n#\n# Description:\n#   Encode or decode a URI.\n_get_uri() {\n  # Usage: _get_uri_decode <string>\n  _get_uri_decode() {\n    # https://unix.stackexchange.com/a/187256\n    local _input=\"${1:-}\"\n\n    _input=\"${_input//+/ }\"\n    _input=\"${_input//$'\\r'}\"\n\n    printf \"%b\\\\n\" \"${_input//%/\\\\x}\"\n  }\n\n  # Usage: _get_uri_encode <string>\n  _get_uri_encode() {\n    local _encoding=\"${1//'%'/%25}\"\n\n    _encoding=\"${_encoding//' '/%20}\"\n    _encoding=\"${_encoding//'\"'/%22}\"\n    _encoding=\"${_encoding//'#'/%23}\"\n    _encoding=\"${_encoding//'$'/%24}\"\n    _encoding=\"${_encoding//'&'/%26}\"\n    _encoding=\"${_encoding//'+'/%2B}\"\n    _encoding=\"${_encoding//','/%2C}\"\n    _encoding=\"${_encoding//${_SLASH}/%2F}\"\n    _encoding=\"${_encoding//':'/%3A}\"\n    _encoding=\"${_encoding//';'/%3B}\"\n    _encoding=\"${_encoding//'='/%3D}\"\n    _encoding=\"${_encoding//'?'/%3F}\"\n    _encoding=\"${_encoding//'@'/%40}\"\n    _encoding=\"${_encoding//'['/%5B}\"\n    _encoding=\"${_encoding//'\\n'/%0A}\"\n\n    local _encoded=\"${_encoding//']'/%5D}\"\n\n    printf \"%s\\\\n\" \"${_encoded:-}\"\n  }\n\n  case \"${1:-}\" in\n    --decode)                 _get_uri_decode \"${2:-}\"  ;;\n    --encode)                 _get_uri_encode \"${2:-}\"  ;;\n    http%3A%2F*|https%3A%2F*) _get_uri_decode \"${1:-}\"  ;;\n    http://*|https://*)       _get_uri_encode \"${1:-}\"  ;;\n  esac\n}\n\n# _normalize_encoding()\n#\n# Usage:\n#   _normalize_encoding <input>\n#\n# Description:\n#   Use python3 or perl to normalize encoding of a string.\n_normalize_encoding() {\n  {\n    printf \"%s\" \"${1:-}\"\n  } | {\n    if _command_exists \"python3\"\n    then\n      python3 -c \"import sys,unicodedata; print(unicodedata.normalize('NFC', sys.stdin.read()), end='')\"\n    elif _command_exists \"perl\"\n    then\n      perl -MUnicode::Normalize -CS -ne 'print NFC($_)'\n    else\n      cat\n    fi\n  }\n}\n\n# _option_get_tags()\n#\n# Usage:\n#   _option_get_tags <option> <comma,separated,tags>\n#\n# Description:\n#   Convert a comma-separated list of tags to a string of hashtags.\n_option_get_tags() {\n  local _tag_list=\n  _tag_list=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\" || return 1\n\n  local _tags=()\n  IFS=',' read -ra _tags <<< \"${_tag_list}\"\n\n  local _normalized_tags=()\n\n  local __tag=\n  for   __tag in \"${_tags[@]:-}\"\n  do\n    _normalized_tags+=(\"#${__tag#\\#}\")\n  done\n\n  local _tag_string=\n  _tag_string=\"$(_join \" \" \"${_normalized_tags[@]-}\")\"\n\n  printf \"%s\\\\n\" \"${_tag_string:-}\"\n}\n\n# _render()\n#\n# Usage:\n#   [<input> |] _render [<path>] [--body] [--from] [--pandoc]\n#                       [--source-extension] [--title <title>]\n#                       [<pandoc-option>...]\n#\n# Options:\n#   --body              Only render body, without <head> and <body> opening\n#                       or closing tags.\n#   --from              The format to convert content from.\n#   --pandoc            Use pandoc to convert file.\n#   --source-extension  The extension of the original file. Used to select\n#                       syntax mode in Ace.\n#   --title             <title> content.\n_render() {\n  # Usage: _render_prepare_file <path> <pandoc-enabled>\n  _render_prepare_file() {\n    local _input_file_path=\"${1:?}\"\n    local _prepared_file_path=\"${_input_file_path:-}\"\n    local _use_pandoc=\"${2:-0}\"\n\n    local _code_extensions=(\n      asm aspx awd awk bash bat bats bib c c++ cc cgi class cls cmake coffee\n      cpp cs cson cxx d diff \"do\" el f fs gcl go h hs haml hbs hx j jade java\n      jl js json jsp jsx kts ksh \"less\" lsp lua m matlab ml mk mm perl php pl\n      pm prl pug py rb r rh rs sass scala scpt scss sh sql styl swift tcl toml\n      tpl ts tsx vb vba vbscript vim xml xsl xslt yaml yml zsh\n    )\n\n    if ((_use_pandoc))\n    then\n      _code_extensions+=($(\n        pandoc --list-highlight-languages \\\n          | sed -e \"/html/d\" -e \"/latex/d\" -e \"/markdown/d\"\n      ))\n    fi\n\n    local _source_extension=\"${_input_file_path##*\\.}\"\n\n    if _contains \"${_source_extension}\" \"${_code_extensions[@]:-}\"\n    then\n      if ((_use_pandoc))\n      then\n        local _code_block_temp_path=\n        _code_block_temp_path=\"$(_temp file \".md\" --touch)\"\n\n        printf \"${_BT}${_BT}${_BT}%s\\\\n%s\\\\n${_BT}${_BT}${_BT}\\\\n\"  \\\n          \"${_source_extension}\"                                    \\\n          \"$(cat \"${_input_file_path:-}\")\" >> \"${_code_block_temp_path:-}\"\n      else\n        local _code_block_temp_path=\n        _code_block_temp_path=\"$(_temp file \".html\" --touch)\"\n\n        printf \"<code>\\\\n%s\\\\n</code>\\\\n\" \\\n          \"$(cat \"${_input_file_path:-}\")\" >> \"${_code_block_temp_path:-}\"\n      fi\n\n      _prepared_file_path=\"${_code_block_temp_path:-}\"\n    fi\n\n    printf \"%s\\\\n\" \"${_prepared_file_path:-}\"\n  }\n\n  # Usage: _render_print_head [--title <title>]\n  _render_print_head() {\n    local _custom_css=\"${NB_CUSTOM_CSS:-}\"\n    local _custom_css_element=\n    local _custom_css_url=\"${NB_CUSTOM_CSS_URL:-}\"\n    local _custom_javascript=\"${NB_CUSTOM_JAVASCRIPT:-${NB_CUSTOM_JS:-}}\"\n    local _custom_javascript_element=\n    local _custom_javascript_url=\"${NB_CUSTOM_JAVASCRIPT_URL:-${NB_CUSTOM_JS_URL:-}}\"\n    local _html_title=\"${_ME}\"\n\n    if [[ \"${1:-}\" == \"--title\" ]] && [[ -n \"${2:-}\" ]]\n    then\n      _html_title=\"${2:-}\"\n    fi\n\n    local _ansi_hex_values=(\n      '000000' '800000' '008000' '808000' '000080' '800080' '008080' 'c0c0c0'\n      '808080' 'ff0000' '00ff00' 'ffff00' '0000ff' 'ff00ff' '00ffff' 'ffffff'\n      '000000' '00005f' '000087' '0000af' '0000d7' '0000ff' '005f00' '005f5f'\n      '005f87' '005faf' '005fd7' '005fff' '008700' '00875f' '008787' '0087af'\n      '0087d7' '0087ff' '00af00' '00af5f' '00af87' '00afaf' '00afd7' '00afff'\n      '00d700' '00d75f' '00d787' '00d7af' '00d7d7' '00d7ff' '00ff00' '00ff5f'\n      '00ff87' '00ffaf' '00ffd7' '00ffff' '5f0000' '5f005f' '5f0087' '5f00af'\n      '5f00d7' '5f00ff' '5f5f00' '5f5f5f' '5f5f87' '5f5faf' '5f5fd7' '5f5fff'\n      '5f8700' '5f875f' '5f8787' '5f87af' '5f87d7' '5f87ff' '5faf00' '5faf5f'\n      '5faf87' '5fafaf' '5fafd7' '5fafff' '5fd700' '5fd75f' '5fd787' '5fd7af'\n      '5fd7d7' '5fd7ff' '5fff00' '5fff5f' '5fff87' '5fffaf' '5fffd7' '5fffff'\n      '870000' '87005f' '870087' '8700af' '8700d7' '8700ff' '875f00' '875f5f'\n      '875f87' '875faf' '875fd7' '875fff' '878700' '87875f' '878787' '8787af'\n      '8787d7' '8787ff' '87af00' '87af5f' '87af87' '87afaf' '87afd7' '87afff'\n      '87d700' '87d75f' '87d787' '87d7af' '87d7d7' '87d7ff' '87ff00' '87ff5f'\n      '87ff87' '87ffaf' '87ffd7' '87ffff' 'af0000' 'af005f' 'af0087' 'af00af'\n      'af00d7' 'af00ff' 'af5f00' 'af5f5f' 'af5f87' 'af5faf' 'af5fd7' 'af5fff'\n      'af8700' 'af875f' 'af8787' 'af87af' 'af87d7' 'af87ff' 'afaf00' 'afaf5f'\n      'afaf87' 'afafaf' 'afafd7' 'afafff' 'afd700' 'afd75f' 'afd787' 'afd7af'\n      'afd7d7' 'afd7ff' 'afff00' 'afff5f' 'afff87' 'afffaf' 'afffd7' 'afffff'\n      'd70000' 'd7005f' 'd70087' 'd700af' 'd700d7' 'd700ff' 'd75f00' 'd75f5f'\n      'd75f87' 'd75faf' 'd75fd7' 'd75fff' 'd78700' 'd7875f' 'd78787' 'd787af'\n      'd787d7' 'd787ff' 'd7af00' 'd7af5f' 'd7af87' 'd7afaf' 'd7afd7' 'd7afff'\n      'd7d700' 'd7d75f' 'd7d787' 'd7d7af' 'd7d7d7' 'd7d7ff' 'd7ff00' 'd7ff5f'\n      'd7ff87' 'd7ffaf' 'd7ffd7' 'd7ffff' 'ff0000' 'ff005f' 'ff0087' 'ff00af'\n      'ff00d7' 'ff00ff' 'ff5f00' 'ff5f5f' 'ff5f87' 'ff5faf' 'ff5fd7' 'ff5fff'\n      'ff8700' 'ff875f' 'ff8787' 'ff87af' 'ff87d7' 'ff87ff' 'ffaf00' 'ffaf5f'\n      'ffaf87' 'ffafaf' 'ffafd7' 'ffafff' 'ffd700' 'ffd75f' 'ffd787' 'ffd7af'\n      'ffd7d7' 'ffd7ff' 'ffff00' 'ffff5f' 'ffff87' 'ffffaf' 'ffffd7' 'ffffff'\n      '080808' '121212' '1c1c1c' '262626' '303030' '3a3a3a' '444444' '4e4e4e'\n      '585858' '626262' '6c6c6c' '767676' '808080' '8a8a8a' '949494' '9e9e9e'\n      'a8a8a8' 'b2b2b2' 'bcbcbc' 'c6c6c6' 'd0d0d0' 'dadada' 'e4e4e4' 'eeeeee'\n    )\n\n    # #1a1a1a #1b1b20 #17171c #19191f #18181c\n    local _color_background_hex=\"#141418\"\n    local _color_background_alt_hex=\"#17171c\" # #1b1b20 #1e1e25 #212121\n    local _color_muted_hex=\"#626480\"\n    local _color_primary_hex=\"#7593eb\"\n    # TODO: local _color_secondary_hex=\n    local _color_text_hex=\"#c5c4cc\"           # #e6e6e6 #dedede\n\n    if [[ \"${NB_COLOR_PRIMARY}\" -lt 256 ]]\n    then\n      _color_primary_hex=\"#${_ansi_hex_values[${NB_COLOR_PRIMARY}]}\"\n      # TODO: _color_secondary_hex=\"#${_ansi_hex_values[${NB_COLOR_SECONDARY}]}\"\n\n      # desaturate select colors\n      case \"${_color_primary_hex}\" in\n        \\#5f87ff) _color_primary_hex=\"#7593eb\" ;;\n        \\#ffff5f) _color_primary_hex=\"#ebeb75\" ;;\n      esac\n    fi\n\n    if [[ -n \"${_custom_javascript:-}\"      ]]\n    then\n      _custom_javascript_element=\"\\\n<script>${_NEWLINE}${_custom_javascript:-}${_NEWLINE}</script>\"\n    fi\n\n    if [[ -n \"${_custom_javascript_url:-}\"  ]]\n    then\n      _custom_javascript_url_element=\"\\\n<script src=\\\"${_custom_javascript_url:-}\\\"></script>\"\n    fi\n\n    if [[ -n \"${_custom_css:-}\"             ]]\n    then\n      _custom_css_element=\"\\\n<style>${_NEWLINE}${_custom_css:-}${_NEWLINE}</style>\"\n    fi\n\n    if [[ -n \"${_custom_css_url:-}\"         ]]\n    then\n      _custom_css_url_element=\"\\\n<link rel=\\\"stylesheet\\\" href=\\\"${_custom_css_url:-}\\\"/>\"\n    fi\n\n    cat <<HEREDOC\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">\n\n<title>${_html_title}</title>\n\n<link rel=\"icon\" type=\"image/x-icon\" href=\"data:image/x-icon;base64,\\\nAAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAACQWAAAkFgAAAAAAAA\\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAon8IB59/AlSegwFunYgCVJ+RBhGdlAFcnZkAbp2eAkqc\\\npwMxm6sBaJuxAzCbtwJim7wChZrAAlCaxgUHmsQEAKN+CQafgQJqnYUB2p6JA2WfkQYPnpYDdp2aAd\\\nmengNXnKgEMZutAsCbsgHNm7cCiZu9AnGZwwG8mMcCbo6pAACehgIAnYYCIJ2HAbeeigMYnpUFAJ6c\\\nBSednQK1nqAEE5irAACbsQKTm7MBlp++DwKZxgIAmccCPZjKAbuZzQQXnogCAJ2IAiCdigG8no0EHZ\\\n6XBQCenwUnnZ8CtZ6iBBOZrgAAm7MCkZu1AmqatAAAmcsEAJnLAx2YzQG9mc8EKJ2LAgCdigIenY0B\\\n152RAlqdlwAAnqEEL52iAbaepQQQmLAAAJu2ApObuAGbncQKBJjLAQCZzQJBmM8BupnRBBafiQUOnY\\\nsBep2OAdOdlAKsnZoChZ2gAaidowKVoKwOA5a3AACbuAKQm7sC0ZrCApCYyAF8mM0Bv5jPAmeTxgAA\\\nn4oGDJ6MA1WekANJnpcEIp2cAmudoAJsnaQDGp2jAgCVuwAAm7sCkJu9A3GZxAJUmcgCe5nNAkaa0Q\\\nUGmdAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKjBJwCZuwAAnLkFFZu9AqSbvwNkmr4AAAAAAAAA\\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACowSYAl7sAAJu6A1iavQGym8EDQprAAQ\\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqcMpAJu9AACcvAUEnMAECJ3E\\\nCAKcwwcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAAABAAAAAQAAiI\\\ngAAIiYAACIiAAAAIEAAAGBAAD/HwAA/x8AAP8fAAD//wAA//8AAA==\">\n\n<style>\nhtml {\n  background-color:   ${_color_background_hex};\n  color:              ${_color_text_hex};\n  font-size:          16px;\n  line-height:        1.5;\n}\n\n@media (min-width: 992px) {\n  html {\n    font-size:        17px;\n  }\n}\n\nhtml,\ninput,\ntextarea {\n  font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;\n}\n\nbody {\n  font-kerning:       normal;\n  hyphens:            none;\n  margin:             0;\n  text-rendering:     optimizeLegibility;\n  word-wrap:          break-word;\n}\n\n@media (max-width: 600px) {\n  body {\n    font-size:        0.9em;\n  }\n}\n\n@media print {\n  body {\n    background-color: transparent;\n    color:            black;\n    font-size:        12pt;\n  }\n\n  h2, h3, p {\n    orphans:          3;\n    widows:           3;\n  }\n\n  h2, h3, h4 {\n    page-break-after: avoid;\n  }\n}\n\nh1, h2, h3, h4, h5, h6 {\n  margin-bottom:      1rem;\n  margin-top:         1rem;\n}\n\nh1  { font-size:      1.5rem;   }\nh2  { font-size:      1.3rem;   }\nh3  { font-size:      1.17rem;  }\n\nh5, h6 {\n  font-size: 1em;\n  font-style: italic;\n}\n\nh6  {  font-weight:   normal; }\n\np {\n  margin:             1em 0;\n  overflow:           hidden;\n}\n\na         {  color:   ${_color_primary_hex}; text-decoration: none;       }\na:hover   {  color:   ${_color_primary_hex}; text-decoration: underline;  }\na:visited {  color:   ${_color_primary_hex}; text-decoration: none;       }\n\n:focus {\n  outline:            1px solid #2d2d2d;\n}\n\nbody.using-mouse a:focus,\nbody.using-mouse input:focus {\n  outline:            none;\n}\n\nh1 a,\nh1 a:hover,\nh1 a:visited,\nnav a,\nnav a:hover,\nnav a:visited,\na.list-item,\na.list-item:hover,\na.list-item:visited {\n  color:              ${_color_text_hex};\n  text-decoration:    none;\n}\n\nblockquote {\n  border-left:        2px solid #4d4d4d;\n  color:              #878787;            /* #606060 */\n  margin:             1em 0 1em 1.7em;\n  padding-left:       1em;\n}\n\ncode {\n  background-color:   ${_color_background_alt_hex};\n  font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;\n  font-size:          85%;\n  margin:             0;\n  padding:            0.2em 0.4em;\n  white-space:        pre-wrap;\n}\n\npre {\n  background-color:   ${_color_background_alt_hex};\n  border:             1px solid ${_color_background_alt_hex};\n  border-radius:      1px;\n  margin:             1rem 0;\n  overflow:           auto;\n  padding:            1rem;\n}\n\npre.sourceCode {\n  padding:            1rem;\n}\n\npre code {\n  overflow:           visible;\n  padding:            0;\n}\n\nhr  {\n  background-color:   #4d4d4d;\n  border:             none;\n  height:             1px;\n  margin:             1em 0;\n}\n\nimg {\n  border-radius:      1px;\n  max-width:          100%;\n}\n\nol, ul {\n  padding-left:       1.7em;\n  margin-top:         1em;\n}\n\nli > ol, li > ul {\n  margin-top:         0;\n}\n\ntable {\n  border-collapse:    collapse;\n  border-color:       transparent;\n  display:            block;\n  font-variant-numeric: lining-nums tabular-nums;\n  margin:             1em 0;\n  overflow-x:         auto;\n  width:              100%;\n}\n\nth {\n  border-top:         1px solid #4d4d4d;\n  padding:            0.25em 0.5em 0.25em 0.5em;\n}\n\ntbody {\n  border: none;\n  border-bottom:      1px solid #4d4d4d;\n  margin-top:         0.5em;\n}\n\ntd {\n  padding:            0 0 1rem 0;\n}\n\ntd > table {\n  margin:             0;\n}\n\ntable caption {\n  margin-bottom:      0.75em;\n}\n\ncol {\n  width:              auto !important;\n}\n\naudio {\n  padding:            1rem 0;\n}\n\naudio,\nvideo {\n  margin:             0 auto;\n  width:              100%;\n}\n\naudio:focus,\nvideo:focus {\n  outline:            ${_color_background_hex};\n}\n\nvideo {\n  height:             auto;\n  max-height:         50rem;\n}\n\n.media-item {\n  padding:            2rem 0 1rem;\n}\n\nheader {\n  margin-bottom:      4em;\n  text-align:         center;\n}\n\n.center {\n  text-align:         center;\n}\n\n.header-crumbs {\n  font-size:          1rem;\n  font-weight:        normal;\n  line-height:        2;\n  margin:             0 auto;\n  max-width:          45rem;\n  padding:            1.75rem 2rem 0rem;\n  text-align:         left;\n}\n\n/* <strong> for bold in terminal browsers only */\n.header-crumbs strong {\n  font-weight:        normal;\n}\n\n.header-crumbs-spacer {\n  display:            none;\n}\n\n.main {\n  margin:             0 auto;\n  max-width:          45rem;\n  padding:            0rem 2rem 2rem;\n}\n\n.main h1:first-child {\n  padding-top:        0.35rem;\n}\n\n.main p:first-child,\n.main .sourceCode:first-child {\n  padding-top:        0.5rem;\n}\n\n.math.display:focus,\n.MathJax:focus {\n  outline:            none;\n}\n\n.item-list {\n  margin-top:         0;\n}\n\n.list-item  {\n  display:            inline-block;\n  max-width:          45rem;\n  overflow:           hidden;\n  text-overflow:      ellipsis;\n  white-space:        nowrap;\n  vertical-align:     top;\n}\n\n.identifier {         color: ${_color_primary_hex}; }\n.muted      {         color: ${_color_muted_hex};   }\n\nform {\n  padding-top:        1rem;\n}\n\n#search {\n  position:           relative;\n}\n\nlabel[for=search-input] {\n  display:            none;\n}\n\n#search-input {\n  background-color:   ${_color_background_hex};\n  border:             none;\n  border-bottom:      1px solid #4d4d4d;\n  color:              ${_color_text_hex};\n  font-size:          1rem;\n  padding:            0.5rem 0;\n  width:              100%;\n}\n\n#search-input:focus {\n  outline:            0;\n}\n\n.search-spacer {\n  display:            none;\n}\n\n#search\ti {\n  animation-name:     blink;\n  animation-duration: 3000ms;\n  animation-iteration-count: infinite;\n  background-color:   #a6a659;\n  display:            none;\n  height:             80%;\n  left:               5px;\n  opacity:            0.5;\n  position:           absolute;\n  top:                10%;\n  width:              1em;\n}\n\n#search input:focus + i {\n  display:            none;\n}\n\n@keyframes blink {\n  from  { opacity:    1; }\n  to    { opacity:    0; }\n}\n\nform br {\n  display:            none;\n}\n\ninput[type=\"submit\"] {\n  background:         none;\n  border:             none;\n  color:              ${_color_primary_hex};\n  font-size:          1rem;\n  outline:            0 solid ${_color_background_hex};\n  padding:            1rem;\n}\n\ninput[type=\"submit\"]:active {\n  border-bottom:      1px solid #bae7ff;\n  color:              #bae7ff;\n}\n\ninput[type=\"submit\"]:focus {\n  outline:            1px solid #2d2d2d;\n}\n\ninput[type=\"submit\"]:hover {\n  border-bottom:      1px solid ${_color_primary_hex};\n}\n\n.last-saved {\n  padding-left:       1rem;\n}\n\ntextarea,\n.ace_editor {\n  background-color:   ${_color_background_alt_hex};\n  border:             none;\n  box-sizing:         border-box;\n  color:              #dddddd;\n  font-size:          0.875rem;\n  line-height:        1.5;\n  margin-bottom:      1rem;\n  margin-top:         1rem;\n  outline:            1px solid ${_color_background_hex};\n  padding:            0;\n  vertical-align:     top;\n  width:              100%;\n}\n\ntextarea {\n  padding:            1rem;\n}\n\n#TOC li {\n  list-style:         none;\n}\n\n#TOC a:not(:hover) {\n  text-decoration:    none;\n}\n\ndiv.column {\n  display:            inline-block;\n  vertical-align:     top;\n  width:              50%;\n}\n\ndiv.hanging-indent {\n  margin-left:        1.5em;\n  text-indent:        -1.5em;\n}\n\nspan.smallcaps {\n  font-variant:       small-caps;\n}\n\nspan.underline {\n  text-decoration:    underline;\n}\n\nul.task-list {\n  list-style:         none;\n}\n\nul.task-list input[type=\"checkbox\"] {\n  -webkit-appearance: none;\n  -moz-appearance:    none;\n  background-color:   #2d2d2d;\n  border-radius:      3px;\n  font-size:          1.2rem;\n  padding:            0 0.3rem;\n}\n\nul.task-list input[type=\"checkbox\"]:before {\n  color:              transparent;\n  content:            \"\\0000A0\";\n}\n\nul.task-list input[type=\"checkbox\"]:checked:before {\n  color:              ${_color_primary_hex};\n  content:            \"x\";\n}\n\n/*\n * #93a5cc #ffcfaf #7f9f7f #dca3a3 #f0dfaf #dfdfbf #dcdccc #c3bf9f #c0bed1\n * #efef8f #b7bcd8 #cccc96 #7290b1\n * /\n\n/* Ace Editor & Syntax */\n\n.ace_editor {\n  /* border:             1rem solid ${_color_background_alt_hex}; */\n}\n\n.ace_gutter {\n  padding:            1rem 0;\n}\n\n.ace_gutter-cell {\n  padding:            0 0.5rem;\n}\n\n.ace_content {\n  padding:            1rem 0.5rem;\n}\n\n.ace_scroller.ace_scroll-left {\n  box-shadow:         initial !important;\n}\n\n.ace-twilight .ace_constant,\n.ace-twilight .ace_constant.ace_character,\n.ace-twilight .ace_constant.ace_character.ace_escape,\n.ace-twilight .ace_constant.ace_other,\n.ace-twilight .ace_heading,\n.ace-twilight .ace_markup.ace_heading,\n.ace-twilight .ace_support.ace_constant {\n  color:              #9191a1;\n}\n\n.ace-tm .ace_gutter,\n.ace-tm .ace_gutter-active-line,\n.ace-twilight .ace_gutter {\n  color:              #E2E2E2;\n  background-color:   ${_color_background_hex};\n}\n\n.ace-tm .ace_gutter-active-line {\n  filter:             brightness(1.25);\n}\n\n.ace-twilight .ace_indent-guide-active {\n  filter: invert(1) grayscale(100%) brightness(0.75);\n}\n\n.ace-twilight .ace_invisible {\n  color:              #333333;\n}\n\n.ace-twilight .ace_list,\n.ace-twilight .ace_markup.ace_list,\n.ace-twilight .ace_storage,\n.ace-twilight .ace_string.ace_strong {\n  color:              #cccc96;\n}\n\n.ace-twilight .ace_print-margin {\n  background:         none;\n}\n\n.ace_separator {\n  color:              #7290b1;\n}\n\n.ace-twilight .ace_keyword,\n.ace-twilight .ace_meta {\n  color:              #7290b1;\n}\n\n.ace-twilight .ace_string {\n  color:              ${_color_primary_hex};\n}\n\n.normal-mode .ace_cursor {\n  background-color:   rgba(255,255,0,0.5);\n}\n\n.normal-mode .ace_hidden-cursors .ace_cursor {\n  border:             1px solid yellow;\n}\n\n/* Pandoc Syntax */\n\npre > code.sourceCode {\n  position:           relative;\n  white-space:        pre;\n}\n\npre > code.sourceCode > span  {\n  display:            inline-block;\n  line-height:        1.25;\n}\n\npre > code.sourceCode > span:empty {\n  height:             1.2em;\n}\n\ncode.sourceCode > span {\n  color:              inherit;\n  text-decoration:    inherit;\n}\n\n@media screen {\n  div.sourceCode {\n    overflow:         auto;\n  }\n}\n\n@media print {\n  pre > code.sourceCode {\n    white-space:      pre-wrap;\n  }\n\n  pre > code.sourceCode > span {\n    padding-left:     5em;\n    text-indent:      -5em;\n  }\n}\n\npre.numberSource code {\n  counter-reset:      source-line 0;\n}\n\npre.numberSource code > span {\n  counter-increment:  source-line;\n  left:               -4em;\n  position:           relative;\n}\n\npre.numberSource code > span > a:first-child::before {\n  border:             none;\n  content:            counter(source-line);\n  display:            inline-block;\n  left:               -1em;\n  padding:            0 4px;\n  position:           relative;\n  text-align:         right;\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select:   none;\n  -ms-user-select:    none;\n  user-select:        none;\n  vertical-align:     baseline;\n  width:              4em;\n}\n\npre.numberSource {\n  margin-left:        3em;\n  padding-left:       4px;\n}\n\ndiv.sourceCode {\n  color:              #cccccc;\n}\n\n@media screen {\n  pre > code.sourceCode > span > a:first-child::before {\n    text-decoration:  underline;\n  }\n}\n\ncode span.al { color: #ffcfaf;                          } /*     Alert      */\ncode span.an { color: #7f9f7f;      font-weight: bold;  } /*   Annotation   */\ncode span.at {                                          } /*   Attribute    */\ncode span.bn { color: #dca3a3;                          } /*     BaseN      */\ncode span.bu {                                          } /*    BuiltIn     */\ncode span.cf { color: #7290b1;                          } /*  ControlFlow   */\ncode span.ch { color: #8987a0;                          } /*      Char      */\ncode span.cn { color: #8987a0;      font-weight: bold;  } /*    Constant    */\ncode span.co { color: ${_color_muted_hex};              } /*    Comment     */\ncode span.cv { color: #7f9f7f;      font-weight: bold;  } /*   CommentVar   */\ncode span.do { color: ${_color_muted_hex};              } /* Documentation  */\ncode span.dt { color: #cccc96;                          } /*    DataType    */\ncode span.dv { color: #cccc96;                          } /*     DecVal     */\ncode span.er { color: #cccc96;                          } /*     Error      */\ncode span.ex {                                          } /*   Extension    */\ncode span.fl { color: #c0bed1;                          } /*     Float      */\ncode span.fu { color: #7290b1;                          } /*    Function    */\ncode span.im {                                          } /*     Import     */\ncode span.in { color: #7f9f7f;      font-weight: bold;  } /*  Information   */\ncode span.kw { color: #7290b1;                          } /*    Keyword     */\ncode span.op { color: #f0efd0;                          } /*   Operator     */\ncode span.ot { color: #cccc96;                          } /*     Other      */\ncode span.pp { color: #ffcfaf;      font-weight: bold;  } /*  Preprocessor  */\ncode span.sc { color: #8987a0;                          } /*  SpecialChar   */\ncode span.ss { color: ${_color_primary_hex};            } /* SpecialString  */\ncode span.st { color: ${_color_primary_hex};            } /*     String     */\ncode span.va {                                          } /*    Variable    */\ncode span.vs { color: ${_color_primary_hex};            } /* VerbatimString */\ncode span.wa { color: #93a5cc;      font-weight: bold;  } /*    Warning     */\n</style>\n\n<script>\n// hide broken images\ndocument.addEventListener(\"DOMContentLoaded\", function(event) {\n  document.querySelectorAll('img').forEach(function(img) {\n    img.onerror = function() { this.style.display = 'none'; };\n  })\n});\n\n// let the document know when the mouse is being used\ndocument.addEventListener('mousedown', function() {\n  document.body.classList.add('using-mouse');\n});\n\n// re-enable focus styling when <tab> is pressed\ndocument.addEventListener('keydown', function(event) {\n  if (event.keyCode === 9) {\n    document.body.classList.remove('using-mouse');\n  }\n});\n</script>\n${_custom_css_url_element:-}\n${_custom_javascript_url_element:-}\n${_custom_css_element:-}\n${_custom_javascript_element:-}\n<meta name=\"referrer\" content=\"no-referrer\" />\n</head>\n<body>\nHEREDOC\n  }\n\n  local _from=\n  local _html_title=\n  local _input_file_path=\n  local _input_string=\n  local _only_body=0\n  local _pandoc_arguments=(\"--highlight-style=zenburn\")\n  local _source_extension=\"${NB_DEFAULT_EXTENSION:-md}\"\n  local _filter_bookmark_content=0\n  local _use_pandoc=0\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      \"\")         :                                           ;;\n      --body)     _only_body=1                                ;;\n      --bookmark) _filter_bookmark_content=1                  ;;\n      --from)     _from=\"${2:?}\" && _use_pandoc=1   && shift  ;;\n      --*pandoc)  _use_pandoc=1                               ;;\n      --source*)  _source_extension=\"${2:?}\"        && shift  ;;\n      --title)    _html_title=\"${2:?}\"              && shift  ;;\n      -*)         _pandoc_arguments+=(\"${1:-}\")               ;;\n      *)\n        if [[ -z \"${_input_file_path:-}\"  ]] &&\n           [[ -f \"${1:-}\"                 ]]\n        then\n          _input_file_path=\"${1:-}\"\n        elif [[ -z \"${_input_string:-}\"   ]]\n        then\n          _input_string=\"${1:-}\"\n        else\n          _pandoc_arguments+=(\"${1:-}\")\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  local _prepared_file_path=\"${_input_file_path:-}\"\n\n  if ! _command_exists \"pandoc\"\n  then\n    _use_pandoc=0\n  fi\n\n  if [[ -n \"${_input_file_path:-}\"  ]]\n  then\n    _prepared_file_path=\"$(\n      _render_prepare_file \"${_input_file_path:-}\" \"${_use_pandoc:-0}\"\n    )\"\n  fi\n\n  {\n    # body\n    if ((_use_pandoc))\n    then\n      if [[ -n \"${_from:-}\"                   ]]\n      then\n        _pandoc_arguments+=(\"--from=${_from:-}\")\n      elif [[ -z \"${_prepared_file_path:-}\"   ]] ||\n           _contains \"${_prepared_file_path##*.}\" \"md\" \"markdown\"\n      then\n        _pandoc_arguments+=(\"--from=${NB_BROWSE_MARKDOWN_READER:-}\")\n      fi\n\n      if ((${NB_MATHJAX_ENABLED:-0}))\n      then\n        _pandoc_arguments+=(\"--mathjax=/--mathjax/tex-chtml.js\")\n      fi\n\n      {\n        if _piped_input\n        then\n          _pandoc                             \\\n            --standard-input                  \\\n            \"${_pandoc_arguments[@]:-}\"       \\\n            2>/dev/null\n        fi\n\n        if [[ -n \"${_prepared_file_path:-}\"   ]]\n        then\n          _pandoc                             \\\n            \"${_prepared_file_path:-}\"        \\\n            \"${_pandoc_arguments[@]:-}\"       \\\n            2>/dev/null\n        fi\n      } | {\n        if [[ -n \"${_input_string}\"           ]]\n        then\n          printf \"%s\\\\n\" \"${_input_string}\"   \\\n            | _pandoc                         \\\n                --standard-input              \\\n                \"${_pandoc_arguments[@]:-}\"   \\\n                2>/dev/null\n        fi\n\n        cat\n      }\n    else\n      {\n        if _piped_input\n        then\n          cat\n        fi\n\n        if [[ -n \"${_prepared_file_path:-}\"   ]]\n        then\n          if _file_is_text \"${_prepared_file_path}\"\n          then\n            cat \"${_prepared_file_path}\"\n          else\n            cat <<HEREDOC\nFile type not yet supported: ${_prepared_file_path##*.}\nHEREDOC\n          fi\n        fi\n      } | {\n        if [[ -n \"${_input_string}\"           ]]\n        then\n          printf \"%s\\\\n\" \"${_input_string}\"\n        fi\n\n        cat\n      }\n    fi\n  } | {\n    # head\n    if ! ((_only_body))\n    then\n      _render_print_head --title \"${_html_title}\"\n    fi\n\n    cat\n  } | {\n    # footer / tail\n    cat\n\n    if ! ((_only_body))\n    then\n      if ((${NB_ACE_ENABLED:-0}))\n      then\n        cat <<HEREDOC\n<script src=\"/--ace/ace.js\"></script>\n<script src=\"/--ace/ext-modelist.js\"></script>\n<script>\n  function initializeAceEditor() {\n    var aceModeList = ace.require(\"ace/ext/modelist\");\n\n    var textarea    = document.querySelector('textarea');\n\n    if (!textarea) return;\n\n    var editDiv = document.createElement('div');\n\n    editDiv.setAttribute(\n      'style',\n      'height:' + textarea.offsetHeight + 'px;' +\n      'width:'  + textarea.offsetWidth  + 'px;'\n    )\n\n    editDiv.style.height    = textarea.offsetHeight + 'px';\n    editDiv.style.width     = textarea.offsetWidth  + 'px';\n    editDiv.classList.add(textarea.classList[0]);\n\n    textarea.parentNode.insertBefore(editDiv, textarea);\n\n    textarea.style.display  = 'none';\n\n    var editor = ace.edit(editDiv);\n\n    editor.getSession().setValue(textarea.value);\n\n    var mode = aceModeList.getModeForPath('example.${_source_extension:-md}').mode;\n    editor.getSession().setMode(mode);\n\n    editor.setOptions({\n      autoScrollEditorIntoView: true,\n      copyWithEmptySelection:   true,\n      displayIndentGuides:      true,\n      fadeFoldWidgets:          true,\n      fixedWidthGutter:         true,\n      highlightActiveLine:      true,\n      navigateWithinSoftTabs:   true,\n      newLineMode:              'unix',\n      printMargin:              false,\n      relativeLineNumbers:      false,\n      scrollPastEnd:            0.5,\n      showFoldWidgets:          true,\n      showGutter:               true,\n      showInvisibles:           true,\n      showLineNumbers:          true,\n      tabSize:                  2,\n      useSoftTabs:              true,\n      wrap:                     false\n    });\n\n    if ('${_source_extension:-md}' === 'md') {\n      if ('${NB_ACE_MD_GUTTER:-1}' === '1') {\n        editor.setOptions({\n          wrap:                 true\n        });\n      } else {\n        editor.setOptions({\n          wrap:                 true,\n          showFoldWidgets:      false,\n          showLineNumbers:      false,\n          showGutter:           false\n        });\n      }\n    }\n\n    if ('${NB_ACE_RELATIVE_LINE_NUMBERS:-0}' === '1') {\n      editor.setOptions({\n        relativeLineNumbers:    true\n      })\n    }\n\n    if ('${NB_ACE_SOFT_TABS:-0}' === '0') {\n      editor.setOptions({\n        useSoftTabs:            false\n      })\n    }\n\n    var keyboard = '${NB_ACE_KEYBOARD:-ace}';\n\n    if (['emacs', 'sublime', 'vim', 'vscode'].indexOf(keyboard) !== -1) {\n      editor.setKeyboardHandler('ace/keyboard/' + keyboard);\n    }\n\n    editor.setTheme('ace/theme/${NB_ACE_THEME:-twilight}');\n\n    textarea.form.addEventListener('submit', function() {\n      textarea.value = editor.getSession().getValue();\n    });\n  }\n\n  (function() {\n    if (document.readyState !== 'loading') {\n      setTimeout(initializeAceEditor, 0);\n    } else {\n      document.addEventListener('DOMContentLoaded', initializeAceEditor);\n    }\n  }());\n</script>\nHEREDOC\n      fi\n\n      if ((${NB_MATHJAX_ENABLED:-0}))\n      then\n        cat <<HEREDOC\n<script id=\"MathJax-script\" async src=\"/--mathjax/tex-chtml.js\"></script>\nHEREDOC\n      fi\n\n      cat <<HEREDOC\n</body>\n</html>\nHEREDOC\n    fi\n  } | {\n    if ((_filter_bookmark_content))\n    then\n      local _in_content=0\n\n      {\n        local               __line=\n        while IFS= read -r  __line\n        do\n          if ! ((_in_content))  &&\n             [[ \"${__line:-}\" =~  (^\\<h2\\ id=\\\"content\\\"|^\\<h2\\ id=\\\"page-content\\\") ]]\n          then\n            _in_content=1\n          fi\n\n          if ((_in_content))\n          then\n            # add line marker\n            printf \"%s-content-%s%s\\\\n\" \"${_ME}\" \"${_ME}\" \"${__line:-}\"\n          else\n            printf \"%s\\\\n\" \"${__line:-}\"\n          fi\n        done\n      } | {\n        # strip bookmark <img> images\n        LC_ALL=C sed -E -e \"/^${_ME}-content-${_ME}/ s/<img[^>]*>//g\"\n      } | {\n        # remove empty <p> paragraph elements\n        LC_ALL=C sed -E -e \"/^${_ME}-content-${_ME}/ s/.*<p>[ ]*<\\/p>$//g\"\n      } | {\n        # remove line marker\n        LC_ALL=C sed -E -e \"s/^${_ME}-content-${_ME}//g\"\n      }\n    else\n      cat\n    fi\n  } | {\n    LC_ALL=C sed -e \"s/<a\\ /<a\\ rel=\\\"noopener\\ noreferrer\\\"\\ /g\"\n  } | {\n    # mark up checkboxes\n    local _checkbox_pattern_open=\"<span class=\\\"muted\\\">[<\\/span><span class=\\\"identifier\\\">\"\n    local _checkbox_pattern_close=\"<\\/span><span class=\\\"muted\\\">\\]<\\/span>\"\n\n    LC_ALL=C sed -E                                                                       \\\n-e \"1, /<textarea/ s/\\[x\\]/${_checkbox_pattern_open}x${_checkbox_pattern_close}/g\"        \\\n-e \"1, /<textarea/ s/\\[ \\]/${_checkbox_pattern_open}${_NBSP}${_checkbox_pattern_close}/g\" \\\n-e \"1, /<textarea/ s/\\[\\]/${_checkbox_pattern_open}${_NBSP}${_checkbox_pattern_close}/g\"\n  }\n}\n\n# _resolve_links()\n#\n# Usage:\n#   <input> | _resolve_links <notebook-path> [--browse] [--limit <limit>]\n#                            [--terminal] [--type <type>]\n#\n# Options:\n#   --browse  Link to web server, link #tags, and redirect outbound links.\n#\n# Description:\n#   Read standard input, resolve all [[wiki-style links]] and wrap each\n#   one in a link to the target item, then print the updated file contents.\n#   When the --browse option is specified, #tags are linked to the search\n#   page for each tag and outbound links are updated to redirect through the\n#   root level of the app to avoid leaking information via the referer header.\n#\n#   By default, links are created with file:// URLs to the item on the\n#   local filesystem. With --browse, links are created with internal web\n#   server URLs.\n_resolve_links() {\n  # Usage: <input> | _resolve_links_get_matches <pattern> [<path>]\n  _resolve_links_get_matches() {\n    local _arguments=()\n\n    case \"${1:-}\" in\n      '') return 1 ;;\n      *)\n        _arguments+=(\"-e\" \"${1:?}\")\n        [[ -n \"${2:-}\" ]] && _arguments+=(\"${2:-}\")\n        ;;\n    esac\n\n    if _command_exists \"rg\"\n    then\n      rg                      \\\n        --color=never         \\\n        --no-filename         \\\n        --only-matching       \\\n        --text                \\\n        \"${_arguments[@]:-}\"  \\\n        2>/dev/null || :\n    else\n      grep                    \\\n        --extended-regexp     \\\n        -h                    \\\n        --only-matching       \\\n        --text                \\\n        \"${_arguments[@]:-}\"  \\\n        2>/dev/null || :\n    fi\n  }\n\n  local _bookmark=0\n  local _columns=\"${NB_BROWSE_COLUMNS:-70}\"\n  local _for_browsing=0\n  local _input_type=\"html\"\n  local _limit=\n  local _terminal=0\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      --bookmark) _bookmark=1                                 ;;\n      --browse)   _for_browsing=1                             ;;\n      --col*)     _columns=\"${2:?}\"                 && shift  ;;\n      --limit|-n|--num|--number|--per*)\n        _limit=\"${2:?}\"\n\n        shift\n        ;;\n      --page)     _option_value_is_present \"${2:-}\" && shift  ;;\n      --terminal) _terminal=1                                 ;;\n      --type)     _input_type=\"${2:?}\"              && shift  ;;\n      *)\n        if [[ -z \"${_notebook_path:-}\"  ]]\n        then\n          _notebook_path=\"${1:-}\"\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  [[ ! -d \"${_notebook_path:-}\" ]] && return 1\n\n  local _url_params_pattern=\n\n  if ((_terminal))\n  then\n    _url_params_pattern=\"?--columns=${_columns:-}\\&--limit=${_limit:-}\"\n  fi\n\n  local _notebook_name=\"${_notebook_path##*/}\"\n\n  if [[ ! \"${_notebook_path:-}\" =~ ^${NB_DIR} ]]\n  then\n    _notebook_name=\"local\"\n\n    local _encoded_local_notebook_path=\n    _encoded_local_notebook_path=\"$(\n      _get_uri --encode \"${_notebook_path:-}\"\n    )\"\n\n    case \"${_url_params_pattern:-}\" in\n      '') _url_params_pattern+=\"?--local=${_encoded_local_notebook_path:-}\"   ;;\n      *)  _url_params_pattern+=\"\\&--local=${_encoded_local_notebook_path:-}\"  ;;\n    esac\n  fi\n\n  # hashtag patterns\n\n  local _hashtag_match_pattern=\"(^|${_ME}-linkable-${_ME}|[>|\\ ])\\#([A-Za-z0-9_\\/\\-]+)\"\n  local _hashtag_replacement_url=\"\\/\\/${NB_SERVER_HOST}:${NB_SERVER_PORT}\\/${_notebook_name}:\"\n\n  case \"${_url_params_pattern:-}\" in\n    '') _hashtag_replacement_url+=\"?--query=%23\\\\2\"                         ;;\n    *)  _hashtag_replacement_url+=\"${_url_params_pattern}\\&--query=%23\\\\2\"  ;;\n  esac\n\n  local _hashtag_pattern=\n\n  case \"${_input_type:-}\" in\n    html) _hashtag_pattern=\"<a\\ href=\\\"${_hashtag_replacement_url//' '/%20}\\\">\\#\\\\2<\\/a>\" ;;\n    org)  _hashtag_pattern=\"[[${_hashtag_replacement_url//' '/%20}][\\#\\\\2]]\"              ;;\n    *)    _hashtag_pattern=\"\\#\\\\2\"                                                        ;;\n  esac\n\n  # temp file\n\n  local _input_temp_file_path=\n  _input_temp_file_path=\"$(_temp file \".${_input_type}\" --touch)\"\n\n  cat >> \"${_input_temp_file_path}\"\n\n  {\n    cat \"${_input_temp_file_path}\"\n  } | {\n    # link #hashtags to internal search URLs\n\n    if ! ((_for_browsing)) || [[ \"${_input_type:-}\" == \"html\" ]]\n    then\n      cat\n    else\n      LC_ALL=C sed -E -e \"s/${_hashtag_match_pattern}/\\1${_hashtag_pattern}/g\"\n    fi\n  } | {\n    # resolve and link [[wiki-style links]]\n    # TODO: HTML uses `sed` streaming replacement. The current Org\n    # implementation uses querying to ensure link is not an\n    # outbound URL, which requires a separate matching operation. The\n    # match replacement code supports both HTML and Org, with HTML unused.\n\n    if ((_for_browsing)) && [[ \"${_input_type:-}\" == \"html\" ]]\n    then\n      # patterns for wrapping [[wiki-style links]] in HTML links\n      local _host_port_pattern=\"${NB_SERVER_HOST}:${NB_SERVER_PORT}\"\n      local _link_match_pattern=\"\\[\\[([^#|][^]|]*)\\]\\]\"\n      local _url_pattern=\"\\/\\/${_host_port_pattern}\\/\\1${_url_params_pattern:-}\"\n      local _replacement_pattern=\"<a\\ href=\\\"${_url_pattern}\\\">[[\\1]]<\\/a>\"\n\n      local _labeled_link_match_pattern=\"\\[\\[([^#][^]|]+)\\|([^]]+)\\]\\]\"\n      local _labeled_url_pattern=\"\\/\\/${_host_port_pattern}\\/\\1${_url_params_pattern:-}\"\n      local _labeled_replacement_pattern=\"<a\\ href=\\\"${_labeled_url_pattern}\\\">[[\\2]]<\\/a>\"\n\n      # patterns for adding notebook prefixes to just-linked URLs\n      local _notebookless_pattern=\"${_host_port_pattern}\\/([^:?\\\"-]+[\\?\\\"])\"\n      local _notebookless_replacement_pattern=\"${_host_port_pattern}\\/${_notebook_name}:\\1\"\n\n      local _linkable_initial=1\n\n      if grep -q \"<\\/body>\" \"${_input_temp_file_path}\"\n      then\n        _linkable_initial=0\n      fi\n\n      {\n        local _linkable=\"${_linkable_initial}\"\n\n        local               __line=\n        while IFS= read -r  __line\n        do\n          if ((_linkable))\n          then\n            if [[ \"${__line:-}\" =~ ^[[:space:]]*(<p[[:space:]]*>)?(<pre[[:space:]]*>)?\\<(nav|code)  ]]\n            then\n              _linkable=0\n            elif ((_bookmark)) && [[ \"${__line:-}\" =~ ^[[:space:]]*\\<h2[^\\<]*\\>(Content|Source)     ]]\n            then\n              _linkable=0\n            fi\n          elif ! ((_linkable))\n          then\n            if [[ \"${__line:-}\" =~ ^[[:space:]]*\\<body ]]\n            then\n              _linkable=1\n            fi\n          fi\n\n          if ((_linkable))\n          then\n            printf \"%s-linkable-%s%s\\\\n\" \"${_ME}\" \"${_ME}\" \"${__line:-}\"\n          else\n            printf \"%s\\\\n\" \"${__line:-}\"\n          fi\n\n          if ((_linkable))\n          then\n            if [[ \"${__line:-}\" =~ ^[[:space:]]*\\</body ]]\n            then\n              _linkable=0\n            fi\n          else\n            if [[ \"${__line:-}\" =~ \\<\\/(nav|code)[[:space:]]*\\>(</pre[[:space:]]*>)?(</p[[:space:]]*>)?[[:space:]]*$ ]]\n            then\n              _linkable=1\n            fi\n          fi\n        done\n      } | {\n        # Replace [[ with placeholder INSIDE <code>...</code> (including <p><code>)\n        LC_ALL=C sed -E                                                         \\\n          -e 's/(<code[^>]*>[^<]*)\\[\\[([^<]*<\\/code>)/\\1__LEFTDBLBRACKET__\\2/g' \\\n          -e 's/(<p[[:space:]]*><code[^>]*>[^<]*)\\[\\[([^<]*<\\/code>[[:space:]]*<\\/p>)/\\1__LEFTDBLBRACKET__\\2/g'\n      } | {\n        # Replace # with placeholder INSIDE <code>...</code> (including <p><code>)\n        LC_ALL=C sed -E                                                         \\\n          -e 's/(<code[^>]*>[^<]*)\\#([^<]*<\\/code>)/\\1__HASH_PLACEHOLDER__\\2/g' \\\n          -e 's/(<p[[:space:]]*><code[^>]*>[^<]*)\\#([^<]*<\\/code>[[:space:]]*<\\/p>)/\\1__HASH_PLACEHOLDER__\\2/g'\n      } | {\n        # wrap [[wiki-style links]] in HTML links and add missing notebooks\n        LC_ALL=C sed -E                                                                           \\\n-e \"/^${_ME}-linkable-${_ME}/ s/${_link_match_pattern}/${_replacement_pattern}/g\"                 \\\n-e \"/^${_ME}-linkable-${_ME}/ s/${_labeled_link_match_pattern}/${_labeled_replacement_pattern}/g\" \\\n-e \"/^${_ME}-linkable-${_ME}/ s/${_notebookless_pattern}/${_notebookless_replacement_pattern}/g\"  \\\n-e \"/^${_ME}-linkable-${_ME}/ s/${_hashtag_match_pattern}/\\1${_hashtag_pattern}/g\"\n      } | {\n        LC_ALL=C sed -E                   \\\n          -e 's/__LEFTDBLBRACKET__/[[/g'  \\\n          -e 's/__HASH_PLACEHOLDER__/#/g'\n      } | {\n        LC_ALL=C sed -E -e \"s/^${_ME}-linkable-${_ME}//g\"\n      }\n    else\n      local __match=\n      for   __match in  $(_resolve_links_get_matches  \\\n                          \"\\[\\[[^\\[]+\\]\\]\"            \\\n                          \"${_input_temp_file_path}\")\n      do\n        local _link=\n        local _link_label=\n\n        [[ -z \"${__match:-}\" ]] && continue\n\n        local _selector=\"${__match#[[}\"\n\n        if [[ \"${__match}\" =~ \\| ]]\n        then\n          _selector=\"${_selector%%|*}\"\n\n          _link_label=\"${__match##*|}\"\n          _link_label=\"${_link_label%]]}\"\n        else\n          _selector=\"${_selector%]]}\"\n          _link_label=\"${_selector}\"\n        fi\n\n        if ((_for_browsing))\n        then\n          if [[ -z \"${_selector:-}\" ]]\n          then\n            _link=\"${__match}\"\n          else\n            local _link_notebook_name=\n            local _query_selector=\n\n            if [[ \"${_selector:-}\" =~ : ]] && [[ ! \"${_selector:-}\" =~ :// ]]\n            then\n              _link_notebook_name=\"${_selector%%:*}\"\n              _query_selector=\"${_selector}\"\n            else\n              _link_notebook_name=\"${_notebook_name}\"\n              _query_selector=\"${_link_notebook_name}:${_selector}\"\n            fi\n\n            local _selector_path=\n            _selector_path=\"$(_selector_resolve_path \"${_query_selector:-}\")\"\n\n            local _id_selector=\n            _id_selector=\"$(\n              _get_id_selector \"${_link_notebook_name}:${_selector_path}\" 2>/dev/null || :\n            )\"\n\n            if [[ -n \"${_selector#*:}\" ]] && [[ -z \"${_selector_path:-}\" ]]\n            then\n              _link=\"[[${_selector:-}]]\"\n            else\n              local _target_url=\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_id_selector}${_url_params_pattern:-}\"\n\n              case \"${_input_type:-}\" in\n                html)\n                  _link=\"<a href=\\\"${_target_url//' '/%20}\\\">[[${_link_label:-}]]</a>\"\n                  ;;\n                org)\n                  _link=\"[[${_target_url:-}][[[${_link_label:-}]]]]\"\n                  ;;\n                *)\n                  _link=\"[[${_selector:-}]]\"\n                  ;;\n              esac\n            fi\n          fi\n        else\n          local _link_path=\n          _link_path=\"$(_show \"${_selector}\" --path 2>/dev/null || :)\"\n\n          if [[ -z \"${_link_path:-}\" ]]\n          then\n            _link=\"[[${_selector}]]\"\n          else\n            case \"${_input_type:-}\" in\n              html)\n                _link=\"<a href=\\\"file://${_link_path//' '/%20}\\\">[[${_link_label:-}]]</a>\"\n                ;;\n              org)\n                _link=\"[[file://${_link_path//' '/%20}][[[${_link_label:-}]]]]\"\n                ;;\n              *)\n                _link=\"[[${_selector:-}]]\"\n                ;;\n            esac\n          fi\n        fi\n\n        local _escaped_match=\"${__match//${_SLASH}/\\\\/}\"\n        _escaped_match=\"${_escaped_match//\\[/\\\\[}\"\n        _escaped_match=\"${_escaped_match//\\]/\\\\]}\"\n        _escaped_match=\"${_escaped_match//\\(/\\(}\"\n        _escaped_match=\"${_escaped_match//\\)/\\)}\"\n\n        local _escaped_replacement=\"${_link//${_SLASH}/\\\\/}\"\n        _escaped_replacement=\"${_escaped_replacement//\\[/\\\\[}\"\n        _escaped_replacement=\"${_escaped_replacement//\\]/\\\\]}\"\n        _escaped_replacement=\"${_escaped_replacement//\\(/\\(}\"\n        _escaped_replacement=\"${_escaped_replacement//\\)/\\)}\"\n\n        if [[ -n \"${_escaped_match:-}\"        ]] &&\n           [[ -n \"${_escaped_replacement:-}\"  ]] &&\n           ! _contains \"${_escaped_match}\" \"${_seen_matches[@]:-}\"\n        then\n          _sed_arguments+=(\"-e\" \"s/${_escaped_match}/${_escaped_replacement}/g\")\n          _seen_matches+=(\"${_escaped_match}\")\n        fi\n      done\n\n      LC_ALL=C sed \"${_sed_arguments[@]:-}\"\n    fi\n  } | {\n    # rewrite outbound links to use an exit page\n\n    if ! ((_for_browsing))\n    then\n      cat\n    else\n      local _outbound_url_pattern=\n\n      case \"${_input_type:-}\" in\n        org)  _outbound_url_pattern=\"\\[\\[https?://[^]]+\"      ;;\n        html) _outbound_url_pattern=\"href=\\\"https?://[^\\\"]+\"  ;;\n      esac\n\n      local _sed_arguments=()\n      local _seen_matches=()\n\n      local __match=\n      for   __match in  $(_resolve_links_get_matches    \\\n                          \"${_outbound_url_pattern:-}\"  \\\n                          \"${_input_temp_file_path}\")\n      do\n        [[ -z \"${__match:-}\" ]] && continue\n\n        if [[ \"${__match}\" =~ https?://${NB_SERVER_HOST} ]]\n        then\n          continue\n        fi\n\n        case \"${_input_type:-}\" in\n          org)  local _target_url=\"${__match#\\[\\[}\"     ;;\n          html) local _target_url=\"${__match#href=\\\"}\"  ;;\n        esac\n\n        # NOTE: skip _get_uri() for performance\n        # use ${_SLASH} for macOS bash support\n\n        local _encoding=\"${_target_url//'%'/%25}\"\n        _encoding=\"${_encoding//' '/%20}\"\n        _encoding=\"${_encoding//'\"'/%22}\"\n        _encoding=\"${_encoding//'#'/%23}\"\n        _encoding=\"${_encoding//'$'/%24}\"\n        _encoding=\"${_encoding//'&'/%26}\"\n        _encoding=\"${_encoding//'+'/%2B}\"\n        _encoding=\"${_encoding//','/%2C}\"\n        _encoding=\"${_encoding//${_SLASH}/%2F}\"\n        _encoding=\"${_encoding//':'/%3A}\"\n        _encoding=\"${_encoding//';'/%3B}\"\n        _encoding=\"${_encoding//'='/%3D}\"\n        _encoding=\"${_encoding//'?'/%3F}\"\n        _encoding=\"${_encoding//'@'/%40}\"\n        _encoding=\"${_encoding//'['/%5B}\"\n        local _encoded_url=\"${_encoding//']'/%5D}\"\n\n        local _replacement_url=\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}?url=${_encoded_url}\"\n        local _replacement=\"${_replacement_url}\"\n\n        case \"${_input_type:-}\" in\n          org)\n            if [[ \"${__match:-}\" =~ ^\\[\\[ ]]\n            then\n              _replacement=\"[[${_replacement}\"\n            fi\n            ;;\n          html)\n            _replacement=\"href=\\\"${_replacement}\"\n            ;;\n        esac\n\n        local _escaped_match=\"${__match//${_SLASH}/\\\\/}\"\n        _escaped_match=\"${_escaped_match//\\[/\\\\[}\"\n        _escaped_match=\"${_escaped_match//\\]/\\\\]}\"\n        _escaped_match=\"${_escaped_match//\\(/\\(}\"\n        _escaped_match=\"${_escaped_match//\\)/\\)}\"\n\n        local _escaped_replacement=\"${_replacement//${_SLASH}/\\\\/}\"\n        _escaped_replacement=\"${_escaped_replacement//\\[/\\\\[}\"\n        _escaped_replacement=\"${_escaped_replacement//\\]/\\\\]}\"\n        _escaped_replacement=\"${_escaped_replacement//\\(/\\(}\"\n        _escaped_replacement=\"${_escaped_replacement//\\)/\\)}\"\n\n        if [[ -n \"${_escaped_match:-}\"        ]] &&\n           [[ -n \"${_escaped_replacement:-}\"  ]] &&\n           ! _contains \"${_escaped_match}\" \"${_seen_matches[@]:-}\"\n        then\n          _sed_arguments+=(\"-e\" \"s/${_escaped_match}/${_escaped_replacement}/g\")\n          _seen_matches+=(\"${_escaped_match}\")\n        fi\n      done\n\n      LC_ALL=C sed \"${_sed_arguments[@]:-}\"\n    fi\n  }\n}\n\n# _web_browser()\n#\n# Usage:\n#   _web_browser [[<url>] [--dump] | --check]\n#\n# Options:\n#   --check   Return with status 0 if a browser is available, or 1 if not.\n#   --dump    Print the page to standard output.\n#\n# Description:\n#   Interact with the preferred or available terminal web browser. When called\n#   with no input or arguments, or with only the --check option, test if a\n#   terminal web browser is available. With <url> or standard input, view in\n#   the preferred or available browser.\n#\n# Exit / Error / Return Status:\n#   0 (success, true)  If a terminal browser is available.\n#   1 (error,  false)  if not.\n_web_browser() {\n  local _arguments=()\n  local _check=0\n  local _check_gui=0\n  local _dump=0\n  local _url=\n  local _web_browser_command=()\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      --check)\n        _check=1\n        ;;\n      --dump|--print)\n        _dump=1\n        ;;\n      --gui)\n        _check_gui=1\n        ;;\n      *)\n        [[ -z \"${_url:-}\" ]] && _url=\"${__arg}\"\n        ;;\n    esac\n  done\n\n  if [[ -n \"${NB_BROWSER:-}\" ]]\n  then\n    _web_browser_command=(\"${NB_BROWSER}\")\n  else\n    if _command_exists \"w3m\"\n    then\n      _web_browser_command+=(\"w3m\")\n    elif _command_exists \"links\"\n    then\n      _web_browser_command+=(\"links\")\n    fi\n  fi\n\n  # checks\n\n  if [[ -z \"${_web_browser_command[*]:-}\" ]]\n  then\n    _warn cat <<HEREDOC\nWeb browser not found. Try \\`w3m\\`: $(_color_primary \"http://w3m.sourceforge.net\")\nHEREDOC\n    exit 1\n  fi\n\n  if ((_check_gui))\n  then\n    shopt -s nocasematch\n\n    if [[ \"${_web_browser_command[*]}\" =~ (firefox|chrom|brave|edg) ]]\n    then\n      return 0\n    else\n      return 1\n    fi\n\n    shopt -u nocasematch\n  fi\n\n  if ((_check))\n  then\n    if ((_dump)) && [[ -n \"${_web_browser_command[*]:-}\" ]]\n    then\n      printf \"%s\\\\n\" \"${_web_browser_command[*]:-}\"\n    fi\n\n    return 0\n  fi\n\n  # behaviors\n\n  if ! _piped_input && [[ -z \"${_url:-}\"        ]]\n  then\n    return 0\n  else\n    if [[ \"${_web_browser_command[*]:-}\" =~ w3m ]]\n    then\n      _web_browser_command+=(\"-I\" \"UTF-8\")\n      _web_browser_command+=(\"-O\" \"UTF-8\")\n\n      if [[ -n \"${_url:-}\" ]]\n      then\n        _web_browser_command+=(\"${_url:-}\")\n      fi\n\n      if ((_dump))\n      then\n        \"${_web_browser_command[@]:-}\" -T text/html -dump\n      else\n        \"${_web_browser_command[@]:-}\" -T text/html 2>/dev/null\n      fi\n\n      return 0\n    elif [[ \"${_web_browser_command[*]:-}\" =~ lynx    ]]\n    then\n      ((_dump)) && _arguments+=(\"-dump\")\n\n      if [[ -n \"${_url:-}\" ]]\n      then\n        _arguments+=(\"${_url:-}\")\n      else\n        _arguments+=(\"-stdin\")\n      fi\n\n      _arguments+=(\"-nomargins\")\n      _arguments+=(\"-noreferer\")\n      _arguments+=(\"-notitle\")\n\n      \"${_web_browser_command[@]:-}\" \"${_arguments[@]:-}\"\n\n      return 0\n    elif [[ \"${_web_browser_command[*]:-}\" =~ links   ]]\n    then\n      ((_dump)) && _arguments+=(\"-dump\")\n\n      if [[ ! \"${_web_browser_command[*]}\" =~ elinks  ]]\n      then # links\n        _arguments+=(\"-html-assume-codepage\" \"Unicode UTF-8\")\n      fi\n\n      if [[ -n \"${_url:-}\" ]]\n      then\n        _arguments+=(\"${_url:-}\")\n      fi\n\n      \"${_web_browser_command[@]:-}\" \"${_arguments[@]:-}\"\n    else\n      if [[ -n \"${_url:-}\" ]]\n      then\n        _web_browser_command+=(\"${_url:-}\")\n      fi\n\n      \"${_web_browser_command[@]}\"\n\n      return 0\n    fi\n  fi\n}\n\n###############################################################################\n# Subcommands: Group 2                                     Subcommands: Group 2\n# --------------------                                     --------------------\n###############################################################################\n# --------------------------------------------------------------------------- #\n\n# add ##################################################################### add\n\n_describe_add() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} add [<notebook>:][<folder-path>/][<filename>] [<content>]\n         [-b | --browse] [-c <content> | --content <content>] [--edit]\n         [-e | --encrypt] [-f <filename> | --filename <filename>]\n         [--folder <folder-path>] [--no-template] [--tags <tag1>,<tag2>...]\n         [--template <template>] [-t <title> | --title <title>] [--type <type>]\n  ${_ME} add bookmark [<bookmark-options>...]\n  ${_ME} add folder [<name>]\n  ${_ME} add todo [<todo-options>...]\n\n$(_color_primary \"Options\"):\n  -b, --browse                Add using a terminal or GUI web browser.\n  -c, --content <content>     The content for the new note.\n  --edit                      Open the note in the editor before saving when\n                              content is piped or passed as an argument.\n  -e, --encrypt               Encrypt the note with a password.\n  -f, --filename <filename>   The filename for the new note.\n  --folder <folder-path>      Add within the folder located at <folder-path>.\n  --no-template               Skip the template when one is assigned.\n  --tags <tag1>,<tag2>...     A comma-separated list of tags.\n  --template <template>       A string template or path to a template file.\n  -t, --title <title>         The title for a new note. If \\`--title\\` is\n                              present, the filename is derived from the\n                              title, unless \\`--filename\\` is specified.\n  --type <type>               The file type for the new note, as a file\n                              extension.\n\n$(_color_primary \"Description\"):\n  Create a new note or folder.\n\n  If no arguments are passed, a new blank note file is opened with \\`\\$EDITOR\\`,\n  currently set to: ${NB_EDITOR}\n\n  If a non-option argument is passed, \\`${_ME}\\` will treat it as a <filename≥\n  if a file extension is found. If no file extension is found,  \\`${_ME}\\` will\n  treat the string as <content> and will create a new note without opening the\n  editor. \\`${_ME} add\\` can also create a new note with piped content.\n\n  \\`${_ME}\\` creates Markdown files by default. To create a note with a\n  different file type, use the extension in the filename or use the \\`--type\\`\n  option. To change the default file type, use \\`${_ME} set default_extension\\`.\n\n  When the \\`-e\\` / \\`--encrypt\\` option is used, \\`${_ME}\\` will encrypt the\n  note with AES-256 using OpenSSL by default, or GPG, if configured in\n  \\`${_ME} set encryption_tool\\`.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#adding\n\n$(_color_primary \"See Also\"):\n  ${_ME} help bookmark\n  ${_ME} help browse\n  ${_ME} help delete\n  ${_ME} help edit\n  ${_ME} help folders\n  ${_ME} help import\n  ${_ME} help show\n  ${_ME} help todo\n\n$(_color_primary \"Examples\"):\n  ${_ME} add\n  ${_ME} add example.md\n  ${_ME} add \"Note content.\"\n  ${_ME} add example.md --title \"Example Title\" --content \"Example content.\"\n  echo \"Note content.\" | ${_ME} add\n  ${_ME} add -t \"Secret Document\" --encrypt\n  ${_ME} add example/document.md\n  ${_ME} add folder sample/demo\n  ${_ME} example:add\n  ${_ME} example:add -t \"Title\"\n  ${_ME} a\n  ${_ME} a \"Note content.\"\n  ${_ME} example:a\n  ${_ME} example:a -t \"Title\"\n\n$(_color_primary \"Aliases\"):\n  ${_ME} create\n  ${_ME} new\n\n$(_color_primary \"Shortcut Aliases\"):\n  ${_ME} a\n  ${_ME} +\nHEREDOC\n}\n_add() {\n  local _add_type=\n  local _arguments=()\n  local _browse=0\n  local _defer_arguments=()\n  local _edit_before_commit=0\n  local _encrypt=0\n  local _file_type=\"${NB_DEFAULT_EXTENSION}\"\n  local _folder_prompt=0\n  local _no_template=0\n  local _option_content=\n  local _option_folder_relative_path=\n  local _option_relative_path=\n  local _password=\n  local _skip_standard_input=0\n  local _tag_list=\n  local _template=\n  local _title=\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      -b|-br|--browse)\n        _browse=1\n        ;;\n      -c|--content)\n        if [[ -z \"${2:-}\"                   ]]\n        then\n          _exit_1 printf                          \\\n            \"%s requires a valid argument.\\\\n\"    \\\n            \"$(_color_primary \"${1:-}\")\"\n        else\n          if [[ -n \"${_option_content:-}\"   ]]\n          then\n            _option_content+=\"${_NEWLINE}${_NEWLINE}\"\n          fi\n\n          _option_content+=\"$(printf \"%s\\\\n\" \"${2:-}\")\"\n          _defer_arguments+=(\"${1}\" \"${2:-}\")\n\n          shift\n        fi\n        ;;\n      --edit)\n        _edit_before_commit=1\n        ;;\n      -e|--encrypt*)\n        if [[ -z \"${NB_ENCRYPTION_TOOL:-}\"  ]]  ||\n           ! _command_exists \"${NB_ENCRYPTION_TOOL:-}\"\n        then\n          _exit_1 printf                        \\\n            \"Encryption tool not found: %s\\\\n\"  \\\n            \"$(_color_primary \"${NB_ENCRYPTION_TOOL:-}\")\"\n        else\n          _encrypt=1\n        fi\n        ;;\n      -f|--file*|--*path|--target*)\n        _option_relative_path=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n        _defer_arguments+=(\"${1}\" \"${2:-}\")\n\n        shift\n        ;;\n      --folder)\n        _option_folder_relative_path=\"$(\n          _option_get_value \"${1}\" \"${2:-}\" | LC_ALL=C sed -e 's/\\/$//'\n        )\"\n        _defer_arguments+=(\"${1}\" \"${_option_folder_relative_path:-}\")\n\n        shift\n        ;;\n      --folder*prompt)\n        _folder_prompt=1\n        ;;\n      --no*color)\n        _COLOR_ENABLED=0\n        ;;\n      --no*template|--skip*template)\n        _no_template=1\n        ;;\n      --password)\n        _password=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --quiet)\n        _QUIET=1\n        ;;\n      --skip*standard*input)\n        _skip_standard_input=1\n        ;;\n      --tag*)\n        [[ -n \"${_tag_list:-}\" ]] && _tag_list+=\" \"\n        _tag_list+=\"$(_option_get_tags \"${1}\" \"${2:-}\")\"\n        _defer_arguments+=(\"${1}\" \"${2:-}\")\n\n        shift\n        ;;\n      --template)\n        _template=\"${2:-}\"\n        _defer_arguments+=(\"${1}\" \"${2:-}\")\n\n        [[ -z \"${2:-}\" ]] && _no_template=1\n\n        shift\n        ;;\n      -t|--title|--name)\n        # TODO: Detect tag list for dynamic -t for --titles and --tags?\n        _title=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n        _defer_arguments+=(\"${1}\" \"${2:-}\")\n\n        shift\n        ;;\n      --type)\n        _file_type=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n        _defer_arguments+=(\"${1}\" \"${2:-}\")\n\n        shift\n        ;;\n      bookmark)\n        _add_type=\"bookmark\"\n        ;;\n      folder|folders|directory)\n        _file_type=\"folder\"\n        _defer_arguments+=(\"${1}\")\n        ;;\n      todo)\n        _add_type=\"todo\"\n        ;;\n      *)\n        _arguments+=(\"${1:-}\")\n        ;;\n    esac\n\n    shift\n  done\n\n  case \"${_add_type:-}\" in\n    bookmark)\n      _defer \"_bookmark\"    \"${_arguments[@]:-}\" \"${_defer_arguments[@]:-}\"\n\n      return 0\n      ;;\n    todo)\n      _defer \"_todo\" \"add\"  \"${_arguments[@]:-}\" \"${_defer_arguments[@]:-}\"\n\n      return 0\n      ;;\n  esac\n\n  if ((_browse))\n  then\n    _defer \"_browse\" \"add\"  \"${_arguments[@]:-}\" \"${_defer_arguments[@]:-}\"\n\n    return 0\n  fi\n\n  local _common_tlds_excluding_text_file_extensions=(\n    app agency au com company biz blog buzz ca cloud club de design dev cf ch\n    cn edu email es fr fun ga gov guru icu info it jp link life live ly media\n    mil net new nl no online nyc page rocks ru se shop site solutions space\n    store tech top tk tv uk us vip wang website work xyz\n  )\n\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  local _selector_content=\n  local _selector_filename=\n  local _selector_folder_relative_path=\n\n  local i=\n  for ((i=0; i < ${#_arguments[@]}; i++))\n  do\n    local _argument_content=\n\n    if [[ -n \"${_arguments[i]:-}\"         ]]\n    then # argument is not blank\n      if [[ -z \"${_selector_content:-}\"   ]]  &&\n         [[ -n \"${_selector_filename:-}\"  ]]\n      then # argument #2 and the first argument was a selector with filename\n        _argument_content+=\"${_arguments[i]:-}\"\n      else\n        local _content_or_filename_extension=\n        local _selector_notebook_path=\n        local _selector_relative_path=\"${_arguments[i]}\"\n\n        if [[ \"${_arguments[i]:-}\" =~ \\.[A-Za-z0-9]+$ ]]\n        then # argument appears to be a file extension\n          _content_or_filename_extension=\"${_arguments[i]##*\\.}\"\n        fi\n\n        if _string_is_url    \"${_arguments[i]:-}\"           ||\n           _string_is_email  \"${_arguments[i]:-}\"           ||\n           _contains \"${_content_or_filename_extension:-}\"  \\\n                     \"${_common_tlds_excluding_text_file_extensions[@]}\"\n        then # argument contains content\n          _argument_content+=\"${_arguments[i]:-} \"\n        else\n          if [[ \"${_arguments[i]}\" =~ (:|^/)                ]]\n          then\n            if [[ -n \"${_selector_filename:-}\"              ]] ||\n               [[ -n \"${_selector_folder_relative_path:-}\"  ]]\n            then\n              _argument_content+=\"${_arguments[i]:-} \"\n            else\n              _selector_notebook_path=\"$(\n                _notebook show \"${_arguments[i]%%:*}\" --path 2>/dev/null || :\n              )\"\n\n              if [[ -n \"${_selector_notebook_path}\"         ]]\n              then # argument is a selector with a valid notebook\n                _notebook_path=\"${_selector_notebook_path}\"\n\n                if [[ \"${_arguments[i]:-}\" =~ ^/            ]]\n                then\n                  _selector_relative_path=\"${_arguments[i]#${_notebook_path}/}\"\n                else\n                  _selector_relative_path=\"${_arguments[i]#*:}\"\n                fi\n              else # argument is not a selector\n                _argument_content+=\"${_arguments[i]:-} \"\n              fi\n            fi\n          fi\n\n          if [[ -z \"${_argument_content:-}\"                 ]]\n          then # still a candidate selector\n            if [[ \"${_selector_relative_path:-}\" =~ /       ]] &&\n               [[ -z \"${_selector_folder_relative_path:-}\"  ]]\n            then # argument appears to contain a relative path\n              _selector_folder_relative_path=\"${_selector_relative_path%\\/*}\"\n            fi\n\n            if [[ -z \"${_option_relative_path}\"                     ]]  &&\n               [[ -z \"${_selector_filename}\"                        ]]  &&\n               {\n                 _contains \"${_file_type:-}\" \"folder\" \"directory\"       ||\n                 [[ \"${_arguments[i]:-}\" =~ (\\.[A-Za-z0-9]+$|/|:)   ]]\n               }\n            then\n              _selector_filename=\"${_selector_relative_path##*\\/}\"\n            elif [[ -n \"${_selector_content:-}\"             ]]\n            then\n              _argument_content+=\"${_arguments[i]:-} \"\n            elif [[ !   \"${_selector_relative_path}\" =~ /$  ]] &&\n                 [[ -z  \"${_selector_notebook_path:-}\"      ]]\n            then\n              _selector_folder_relative_path=\"\"\n              _argument_content+=\"${_arguments[i]:-} \"\n            fi\n          fi\n        fi\n      fi\n    fi\n\n    if [[ -n \"${_argument_content:-}\" ]]\n    then\n      _selector_content+=\"${_argument_content}\"\n    fi\n  done\n\n  if [[ -n \"${_selector_content:-}\"   ]]\n  then\n    _selector_content=\"${_selector_content%\\ }\"\n  fi\n\n  # Filename\n  # --------\n\n  local _target_filename=\n\n  if [[ -n \"${_option_relative_path:-}\"   ]]\n  then\n    _target_filename=\"${_option_relative_path##*\\/}\"\n  elif [[ -n \"${_selector_filename:-}\"    ]]\n  then\n    _target_filename=\"${_selector_filename:-}\"\n  fi\n\n  if [[ -z \"${_target_filename:-}\"        ]] &&\n     [[ -z \"${_option_relative_path:-}\"   ]]\n  then\n    if [[ -n \"${_title:-}\" ]] &&\n       ! _contains \"${_file_type:-}\" \"folder\" \"directory\"\n    then\n      _target_filename=\"$(_get_sanitized_filename \"${_title}\")\"\n    fi\n\n    if [[ -n \"${_file_type}\"              ]] &&\n       [[ \"${_file_type:-}\" != \"folder\"   ]]\n    then\n      # NOTE: ${_target_filename} can be blank, resulting in '.type'\n      _target_filename=\"${_target_filename:-}.${_file_type}\"\n    elif [[ \"${_file_type:-}\" == \"folder\" ]] &&\n         [[ -z \"${_target_filename:-}\"    ]]\n    then\n      _target_filename=\"folder\"\n    fi\n  fi\n\n  _target_filename=\"$(_normalize_encoding \"${_target_filename}\")\"\n\n  # Folder\n  # ------\n\n  local _target_folder_relative_path=\n\n  if [[ \"${_option_relative_path}\" =~ /           ]]\n  then\n    _target_folder_relative_path=\"${_option_relative_path%%\\/*}\"\n  fi\n\n  if [[ -n \"${_option_folder_relative_path:-}\"    ]]\n  then\n    _target_folder_relative_path=\"${_option_folder_relative_path}/${_target_folder_relative_path:-}\"\n  fi\n\n  if [[ -n \"${_selector_folder_relative_path:-}\"  ]]\n  then\n    _resolved_selector_folder_relative_path=\"$(\n      _selector_resolve_folders               \\\n        \"${_selector_folder_relative_path}/\"  \\\n        --build || :\n    )\"\n\n    if [[ -n \"${_resolved_selector_folder_relative_path:-}\" ]]\n    then\n      _target_folder_relative_path=\"${_resolved_selector_folder_relative_path:-}/${_target_folder_relative_path}\"\n    fi\n  fi\n\n  _target_folder_relative_path=\"${_target_folder_relative_path%/}\"\n\n  # Target\n  # ------\n\n  local _target_relative_path=\"${_target_folder_relative_path:-}/${_target_filename:-}\"\n  _target_relative_path=\"${_target_relative_path#/}\"\n\n  local _target_unique_relative_path=\n\n  if [[     \"${_target_relative_path}\" =~ ^\\..* ]] &&\n     [[ -n  \"${_option_relative_path:-}\"        ]]\n  then\n    local _target_unique_path=\n    _target_unique_path=\"$(\n      _get_unique_path \"${_notebook_path}/${_target_relative_path}\"\n    )\"\n\n    _target_unique_relative_path=\"${_target_unique_path#\"${_notebook_path}\"/}\"\n  else\n    _target_unique_relative_path=\"$(\n      _notebooks current --filename \"${_target_relative_path}\"\n    )\"\n  fi\n\n  local _target_basename=\n  _target_basename=\"$(basename \"${_target_unique_relative_path}\")\"\n\n  local _target_path=\"${_notebook_path}/${_target_unique_relative_path}\"\n\n  if _contains \"${_file_type:-}\" \"folder\" \"directory\"\n  then\n    if ! mkdir -p \"${_target_path:?}\" 2>/dev/null\n    then\n      _exit_1 printf \"Unable to create folder: %s\\\\n\"       \\\n        \"$(_color_primary \"${_target_unique_relative_path}\")\"\n    fi\n\n    touch \"${_target_path:?}/.index\"\n\n    if [[ -n \"${_target_folder_relative_path:-}\" ]]\n    then\n      _index reconcile                                      \\\n        \"${_notebook_path}/${_target_folder_relative_path}\" \\\n        --ancestors\n    fi\n  else\n    if ((_encrypt))\n    then\n      if [[ -z \"${_password}\"                   ]] &&\n         [[ \"${NB_ENCRYPTION_TOOL:-}\" != \"age\"  ]]\n      then\n        # request password without displaying it\n        printf \"%s: \" \"$(_color_primary \"Password\")\"\n\n        local _password=\n        IFS='' read -r -e -d $'\\n' -s _password </dev/tty\n\n        if [[ -z \"${_password:-}\"               ]]\n        then\n          _exit_1 printf \"Password required.\\\\n\"\n        fi\n\n        local _password_confirmation=\n\n        # request password without displaying it\n        printf \"%s: \" \"$(_color_primary \"Confirm Password\")\"\n\n        local _password_confirmation=\n        IFS='' read -r -e -d $'\\n' -s _password_confirmation </dev/tty\n\n        if [[ \"${_password}\" != \"${_password_confirmation}\" ]]\n        then\n          _exit_1 printf \"Password mismatch.\\\\n\"\n        fi\n      fi\n\n      if [[ -n \"${_target_folder_relative_path:-}\"  ]]\n      then\n        if ! mkdir -p \"$(_temp directory)/${_target_folder_relative_path}\" 2>/dev/null\n        then\n          _exit_1 printf \"Unable to create temporary folder: %s\\\\n\" \\\n            \"$(_color_primary \"$(_temp directory)/${_target_folder_relative_path}\")\"\n        fi\n      fi\n\n      _target_path=\"$(_temp directory)/${_target_unique_relative_path}\"\n    fi\n\n    if [[ -n \"${_target_folder_relative_path:-}\"                      ]] &&\n       [[ ! -d \"${_notebook_path}/${_target_folder_relative_path:-}\"  ]]\n    then\n      if [[ -e \"${_notebook_path}/${_target_folder_relative_path:-}\"  ]]\n      then\n        _exit_1 printf \"File exists at: %s\\\\n\"  \\\n          \"$(_color_primary \"${_target_folder_relative_path:-}\")\"\n      else\n        if ((_folder_prompt))\n        then\n          local _target_folder_selector=\"${_target_folder_relative_path:-}/\"\n\n          if _notebooks current --selected\n          then\n            _target_folder_selector=\"$(_notebooks current --name):${_target_folder_selector}\"\n          fi\n\n          printf \"Creating new folder: %s\\\\n\"   \\\n            \"$(_color_primary \"${_target_folder_selector}\")\"\n\n          while true\n          do\n            local __yn=\n            IFS='' read -r -e -d $'\\n' -p       \\\n\"$(_color_primary \"Proceed?\") $(_color_brackets \"y/N\") \" __yn\n\n            case \"${__yn}\" in\n              [Yy]*)\n                break\n                ;;\n              *)\n                printf \"Exiting...\\\\n\"\n\n                exit 0\n                ;;\n            esac\n          done\n        fi\n\n        if ! mkdir -p \"${_notebook_path:?}/${_target_folder_relative_path}\" 2>/dev/null\n        then\n          _exit_1 printf \"Unable to create folder: %s\\\\n\" \\\n            \"$(_color_primary \"${_target_folder_relative_path}\")\"\n        fi\n      fi\n    fi\n\n    local _title_prefix=\n\n    case \"${_target_path:-}\" in\n      *.adoc|*.asciidoc)\n        _title_prefix=\"=\"\n        ;;\n      *.org)\n        _title_prefix=\"#+TITLE:\"\n        ;;\n      *)\n        _title_prefix=\"#\"\n        ;;\n    esac\n\n    # prepare content\n\n    local _content_temp_file_path=\n    _content_temp_file_path=\"$(_temp file --touch)\"\n\n    local _piped_content_temp_file_path=\n    _piped_content_temp_file_path=\"$(_temp file --touch)\"\n\n    local _print_content_spacing=0\n\n    if [[ -n \"${_selector_content:-}\"   ]]\n    then # argument content\n      printf \"%s\\\\n\" \"${_selector_content}\"   >> \"${_content_temp_file_path}\"\n      _print_content_spacing=1\n    fi\n\n    if [[ -n \"${_option_content:-}\"     ]]\n    then # argument content\n      ((_print_content_spacing)) &&\n        printf \"\\\\n\"                          >> \"${_content_temp_file_path}\"\n\n      printf \"%s\\\\n\" \"${_option_content}\"     >> \"${_content_temp_file_path}\"\n      _print_content_spacing=1\n    fi\n\n    if _piped_input && ! ((_skip_standard_input))\n    then # piped input\n      ((_print_content_spacing)) &&\n        printf \"\\\\n\"                          >> \"${_content_temp_file_path}\"\n\n      cat                                     >> \"${_piped_content_temp_file_path}\"\n      cat \"${_piped_content_temp_file_path}\"  >> \"${_content_temp_file_path}\"\n    fi\n\n    # set default template\n\n    if [[ -z \"${_template:-}\"           ]]  &&\n       [[ -n \"${NB_DEFAULT_TEMPLATE:-}\" ]]\n    then\n      _template=\"${NB_DEFAULT_TEMPLATE}\"\n    fi\n\n    # build document\n\n    if [[ -z \"${_template:-}\"           ]] ||\n       ((_no_template))\n    then # no template\n      if [[ -n \"${_title}\"              ]]\n      then\n        printf \"%s\\\\n\\\\n\" \"${_title_prefix} ${_title}\" >> \"${_target_path}\"\n      fi\n\n      local _print_spacing=0\n\n      if [[ -n \"${_tag_list:-}\"         ]]\n      then\n        printf \"%s\\\\n\" \"${_tag_list}\"       >> \"${_target_path}\"\n        _print_spacing=1\n      fi\n\n      if [[ -s \"${_content_temp_file_path:-}\"          ]]\n      then\n        ((_print_spacing)) && printf \"\\\\n\"  >> \"${_target_path}\"\n\n        cat \"${_content_temp_file_path}\"    >> \"${_target_path}\"\n      fi\n    else # template\n      local _template_content=\n      _template_content=\"$(cat \"${_content_temp_file_path}\")\"\n\n      local _piped_template_content=\n      _piped_template_content=\"$(cat \"${_piped_content_temp_file_path}\")\"\n\n      {\n        if [[ -f \"${_template}\" ]] && _file_is_text \"${_template}\"\n        then\n          cat \"${_template}\"\n        else\n          printf \"%s\\\\n\" \"${_template}\"\n        fi\n      } | {\n        # shellcheck disable=SC2016\n        LC_ALL=C sed -E                                           \\\n          -e 's/\\{\\{title_prefix}}/${_title_prefix}/g'            \\\n          -e 's/\\{\\{title}}/${_title}/g'                          \\\n          -e 's/\\{\\{tags}}/${_tag_list}/g'                        \\\n          -e 's/\\{\\{content}}/${_template_content}/g'             \\\n          -e 's/\\{\\{selector_content}}/${_selector_content}/g'    \\\n          -e 's/\\{\\{option_content}}/${_option_content}/g'        \\\n          -e 's/\\{\\{piped_content}}/${_piped_template_content}/g' \\\n          -e 's/\\{\\{(date[^}]+)}}/$(\\1)/g'\n      } | {\n        eval \"echo \\\"$(cat)\\\"\"\n      } >> \"${_target_path}\"\n    fi\n\n    if ((_edit_before_commit))              ||\n       {\n         ! _piped_input                     &&\n         [[ -z \"${_selector_content:-}\" ]]  &&\n         [[ -z \"${_option_content:-}\"   ]]\n       }\n    then\n      _edit_file \"${_target_path}\"\n    fi\n\n    # walk up and delete empty directories when file not created\n    if [[ ! -e \"${_target_path:?}\"                                    ]] &&\n       [[   -n \"${_target_folder_relative_path:-}\"                    ]] &&\n       [[   -e \"${_notebook_path:?}/${_target_folder_relative_path}\"  ]]\n    then\n      cd \"${_notebook_path:?}/${_target_folder_relative_path:?}\"\n\n      while [[ \"${PWD:?}\" =~ ^${_notebook_path:?}       ]] &&\n            [[ \"${PWD:?}\" != \"${_notebook_path:?}\"      ]] &&\n            [[ -z \"$(find \"${PWD}/.\" ! -name . -prune)\" ]]\n      do\n        local _empty_directory_path=\"${PWD:?}\"\n\n        cd ..\n\n        if [[ -d \"${_empty_directory_path:?}\"                             ]] &&\n           [[ -z \"$(find \"${_empty_directory_path}/.\" ! -name . -prune)\"  ]]\n        then\n          rm -r \"${_empty_directory_path:?}\"\n        fi\n      done\n    fi\n\n    if ((_encrypt)) && [[ -e \"${_target_path}\" ]]\n    then\n      _target_basename=\"${_target_basename}.enc\"\n\n      local _decrypted_path=\"${_target_path}\"\n      local _encrypted_path=\"${_notebook_path}/${_target_unique_relative_path}.enc\"\n\n      _encrypt_file           \\\n        \"${_decrypted_path}\"  \\\n        \"${_encrypted_path}\"  \\\n        --password \"${_password}\"\n\n      if [[ -n \"${_decrypted_path}\" ]] && [[ -e \"${_decrypted_path}\" ]]\n      then\n        rm \"${_decrypted_path:?}\"\n      fi\n\n      _target_unique_relative_path=\"${_target_unique_relative_path}.enc\"\n      _target_path=\"${_encrypted_path}\"\n    fi\n  fi\n\n  if [[ -e \"${_target_path}\"              ]]\n  then\n    if [[ ! \"${_target_path##*/}\" =~ ^\\.  ]]\n    then\n      _index add                          \\\n        \"${_target_basename}\"             \\\n        \"${_notebook_path:?}/${_target_folder_relative_path:-}\"\n    fi && _git checkpoint                 \\\n      \"${_notebook_path}\"                 \\\n      \"[${_ME}] Add: ${_target_unique_relative_path}\"\n\n    local _info=\n    _info=\"$(\n      _show \"${_notebook_path:?}/${_target_unique_relative_path:?}\" --info-line\n    )\"\n\n    if ! ((_QUIET))\n    then\n      printf \"Added: %s\\\\n\" \"${_info}\"\n    fi\n  fi\n}\n_alias_subcommand \"add\" \"+\"\n_alias_subcommand \"add\" \"a\"\n_alias_subcommand \"add\" \"create\"\n_alias_subcommand \"add\" \"new\"\n\n# bookmark ########################################################### bookmark\n\n_describe_bookmark() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} bookmark [<ls-options>...]\n  ${_ME} bookmark [<notebook>:][<folder-path>/] <url>...\n              [-c <comment> | --comment <comment>] [--edit] [-e | --encrypt]\n              [-f <filename> | --filename <filename>] [--no-request]\n              [-q <quote> | --quote <quote>] [--save-source]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]...\n              [-t <tag1>,<tag2>... | --tags <tag1>,<tag2>...] [--title <title>]\n  ${_ME} bookmark list [<list-options>...]\n  ${_ME} bookmark (edit | delete | open | peek | url)\n              ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} bookmark search <query>\n\n$(_color_primary \"Options\"):\n  -c, --comment <comment>      A comment or description for this bookmark.\n  --edit                       Open the bookmark in your editor before saving.\n  -e, --encrypt                Encrypt the bookmark with a password.\n  -f, --filename <filename>    The filename for the bookmark. It is\n                               recommended to omit the extension so the\n                               default bookmark extension is used.\n  --no-request                 Don't request or download the target page.\n  -q, --quote <quote>          A quote or excerpt from the saved page.\n                               Alias: \\`--excerpt\\`\n  -r, --related <selector>     A selector for an item related to the\n                               bookmarked page.\n  -r, --related <url>          A URL for a page related to the bookmarked page.\n                               Multiple \\`--related\\` flags can be used in a\n                               command to save multiple related URLs and\n                               selectors.\n  --save-source                Save the page source as HTML.\n  -t, --tags <tag1>,<tag2>...  A comma-separated list of tags.\n  --title <title>              The bookmark title. When not specified,\n                               \\`${_ME}\\` will use the html <title> tag.\n\n$(_color_primary \"Subcommands\"):\n  (default)  Add a new bookmark for <url>, or list bookmarks.\n             Bookmarks can also be added with \\`${_ME} <url>\\`\n  delete     Delete a bookmark.\n  edit       Edit a bookmark.\n  list       List bookmarks in the current notebook.\n             Shortcut Alias: \\`ls\\`\n  open       Open the bookmarked page in your system's primary web browser.\n             Shortcut Alias: \\`o\\`\n  peek       Open the bookmarked page in your terminal web browser.\n             Alias: \\`preview\\`\n             Shortcut Alias: \\`p\\`\n  search     Search bookmarks for <query>.\n             Shortcut Alias: \\`q\\`\n  url        Print the URL for the specified bookmark.\n\n$(_color_primary \"Description\"):\n  Create, view, search, edit, and delete bookmarks.\n\n  By default, the html page content is saved within the bookmark, making the\n  bookmarked page available for full-text search. When Pandoc [1] is\n  installed, the HTML content is converted to Markdown before saving.\n  When readability-cli [2] is install, markup is cleaned up to focus on\n  content.\n\n  \\`peek\\` opens the page in \\`w3m\\` [3] or \\`links\\` [4] when available.\n  To specify a preferred browser, set the \\`\\$BROWSER\\` environment variable\n  in your .bashrc, .zshrc, or equivalent, e.g.: export BROWSER=\"links\"\n\n  Bookmarks are identified by the \\`.bookmark.md\\` file extension. The\n  bookmark URL is the first URL in the file within \"<\" and \">\" characters:\n\n    <https://www.example.com>\n\n    1. https://pandoc.org/\n    2. https://gitlab.com/gardenappl/readability-cli\n    3. https://en.wikipedia.org/wiki/W3m\n    4. https://en.wikipedia.org/wiki/Links_(web_browser)\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-bookmark\n\n$(_color_primary \"See Also\"):\n  ${_ME} help browse\n  ${_ME} help open\n  ${_ME} help peek\n  ${_ME} help show\n\n$(_color_primary \"Examples\"):\n  ${_ME} https://example.com\n  ${_ME} example: https://example.com\n  ${_ME} https://example.com --encrypt\n  ${_ME} https://example.com --tags example,sample,demo\n  ${_ME} https://example.com/about -c \"Example comment.\"\n  ${_ME} https://example.com/faqs -f example-filename\n  ${_ME} https://example.com --quote \"Example quote or excerpt.\"\n  ${_ME} bookmark list\n  ${_ME} bookmark search \"example query\"\n  ${_ME} bookmark open 5\n  ${_ME} bk\n\n$(_color_primary \"Shortcut Aliases\"):\n  ${_ME} bk\n  ${_ME} bm\nHEREDOC\n}\n_bookmark() {\n  # Usage: _bookmark_cleanup_tag_content <string>\n  _bookmark_cleanup_tag_content() {\n    local _character_removal_pattern=\n    _character_removal_pattern=\"$(\n      printf \"\\xE2\\x80\\xAA|\\xE2\\x80\\xAB|\\xE2\\x80\\xAC\"\n    )\"\n\n    # `awk` condenses and trims whitespace\n    # `sed` removes select unicode characters\n    # `w3m` converts HTML entities\n    printf \"%s\\\\n\" \"${1:-}\"                                     \\\n      | awk '$1=$1'                                             \\\n      | LC_ALL=C sed -E -e \"s/${_character_removal_pattern}//g\" \\\n      | if _command_exists \"w3m\"\n        then\n           w3m -dump -T text/html -cols 9999\n         else\n           cat\n        fi\n  }\n\n  # Usage: _bookmark_view_in_terminal_browser (<url>)\n  _bookmark_view_in_terminal_browser() {\n    local _target_url=\"${1:-}\"\n\n    if _web_browser --check\n    then\n      _web_browser \"${_target_url}\"\n\n      return 0\n    elif _command_exists \"curl\" || _command_exists \"wget\"\n    then\n      _download_from \"${_target_url}\"               \\\n        | if _command_exists \"pandoc\"\n          then\n            _pandoc                                 \\\n              --standard-input                      \\\n              --from  html-native_divs-native_spans \\\n              --to    markdown                      \\\n              | _highlight_syntax_if_available \"md\"\n          else\n            cat\n          fi | _pager\n\n      return 0\n    else\n      _exit_1 printf \"Terminal web browser not detected.\\\\n\"\n    fi\n  }\n\n  local _arguments=()\n  local _bookmark_content=\n  local _comment=\n  local _content_cleanup_tool=\"readability\"\n  local _content_conversion_tool=\"pandoc\"\n  local _edit_before_commit=0\n  local _encrypt=0\n  local _non_url_arguments=()\n  local _password=\n  local _quote=\n  local _related_identifiers=()\n  local _request_page=1\n  local _save_source=0\n  local _secondary_urls=()\n  local _selector=\n  local _skip_content=0\n  local _skip_folder_prompt=0\n  local _subcommand=\n  local _tag_list=\n  local _target_filename=\n  local _title=\n  local _url=\n\n  if [[ -n \"${NB_BOOKMARK_CONTENT_CLEANUP_TOOL+x}\"    ]]\n  then\n    _content_cleanup_tool=\"${NB_BOOKMARK_CONTENT_CLEANUP_TOOL}\"\n  fi\n\n  if [[ -n \"${NB_BOOKMARK_CONTENT_CONVERSION_TOOL+x}\" ]]\n  then\n    _content_conversion_tool=\"${NB_BOOKMARK_CONTENT_CONVERSION_TOOL}\"\n  fi\n\n  local _previous_arg=\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    if [[ \"${_previous_arg:-}\" =~ ^-- ]] ||\n       ! _string_is_url \"${__arg:-}\"\n    then\n      _non_url_arguments+=(\"${__arg:-}\")\n    fi\n\n    _previous_arg=\"${__arg:-}\"\n  done\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      -c|--comment*)\n        _comment=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --content*cleanup*tool)\n        _content_cleanup_tool=\"${2:-}\"\n\n        shift\n        ;;\n      --content*conversion*tool)\n        _content_conversion_tool=\"${2:-}\"\n\n        shift\n        ;;\n      --download|--fetch|--online|--request)\n        _request_page=1\n        ;;\n      --edit)\n        _edit_before_commit=1\n        ;;\n      -e|--encrypt*)\n        _encrypt=1\n        ;;\n      -f|--filename)\n        _target_filename=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --no*download|--no*fetch|--no*request|--offline)\n        _request_page=0\n        ;;\n      --password)\n        _password=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n        _arguments+=(\"${1:-}\" \"${2:-}\")\n\n        shift\n        ;;\n      --quiet)\n        _QUIET=1\n        ;;\n      -q|--quote|--excerpt)\n        _quote=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      -r|--via|--also|--related)\n        _related_identifiers+=(\"$(_option_get_value \"${1}\" \"${2:-}\")\")\n\n        shift\n        ;;\n      --save*source|--source|--save*html|--html|--raw*content|--raw*html)\n        _save_source=1\n        ;;\n      --skip*content|--no*content)\n        _skip_content=1\n        ;;\n      --skip*folder*prompt)\n        _skip_folder_prompt=1\n        ;;\n      -t|--tag*)\n        _tag_list=\"$(_option_get_tags \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --title)\n        _title=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      d|delete|remove|rm|trash|-)\n        _delete \"${2:-}\" \"${3:-}\"\n\n        return 0\n        ;;\n      edit)\n        _edit \"${2:-}\"\n\n        return 0\n        ;;\n      help)\n        _help \"bookmark\"\n\n        return 0\n        ;;\n      ls|list)\n        _subcommand=\"list\"\n        ;;\n      search|q)\n        _subcommand=\"search\"\n        ;;\n      open|o|peek|p|preview|url)\n        if _option_value_is_present \"${2:-}\"\n        then\n          if [[ \"${1}\" =~ (^open$|^o$)  ]]\n          then\n            _subcommand=\"open\"\n          elif [[ \"${1}\" =~ (^peek$|^p$|^preview$) ]]\n          then\n            _subcommand=\"peek\"\n          elif [[ \"${1}\" == \"url\"       ]]\n          then\n            _subcommand=\"url\"\n          fi\n\n          _selector=\"${2:-}\"\n\n          shift\n        else\n          _exit_1                                     \\\n            printf \"%s requires a valid argument.\\\\n\" \\\n            \"$(_color_primary \"bookmark ${1}\")\"\n        fi\n        ;;\n      *)\n        if [[ ! \"${_subcommand:-}\"  =~ (^list$|^search$)  ]] &&\n           _string_is_url \"${1}\"\n        then\n          if [[ -z \"${_url:-}\" ]]\n          then\n            _url=\"${1}\"\n          else\n            _secondary_urls+=(\"${1}\")\n          fi\n        elif [[ -z \"${_subcommand:-}\"                     ]] ||\n             [[ \"${_subcommand}\"    =~ (^list$|^search$)  ]]\n        then\n          if [[ \"${1:-}\" =~ (:|^/) ]] && [[ -z \"${_selector:-}\" ]]\n          then\n            _selector=\"${1:-}\"\n          fi\n\n          _arguments+=(\"${1}\")\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  _debug echo \"\\${_content_cleanup_tool}: '${_content_cleanup_tool:-}'\"\n  _debug echo \"\\${_content_conversion_tool}: '${_content_conversion_tool:-}'\"\n\n  # `bookmark list`\n\n  if [[ \"${_subcommand}\" == \"list\"  ]]\n  then\n    if [[ -n \"${_arguments[*]:-}\"   ]]\n    then\n      _list --bookmarks \"${_arguments[@]}\"\n\n      return 0\n    else\n      _list --bookmarks\n\n      return 0\n    fi\n  fi\n\n  # `bookmark search`\n\n  if [[ \"${_subcommand}\" == \"search\" ]]\n  then\n    _search --bookmarks \"${_arguments[@]}\"\n\n    return 0\n  fi\n\n  # `bookmark open`, `bookmark peek`, `bookmark url`\n\n  {\n    if [[ \"${_subcommand}\" =~ (^open$|^peek$|^url$) ]]\n    then\n      local _relative_path=\n      _relative_path=\"$(_show \"${_selector}\" --relative-path)\"\n\n      local _notebook_path=\n      _notebook_path=\"$(_notebooks current --path)\"\n\n      if [[ -z \"${_relative_path}\"                  ]]\n      then\n        if [[ \"${_subcommand}\" =~ (^open$|^peek$)   ]]\n        then\n          local _maybe_notebook=\"${_selector:-}\"\n          _maybe_notebook=\"$(\n            printf \"%s\\\\n\" \"${_maybe_notebook}\" | LC_ALL=C sed 's/\\:$//'\n          )\"\n\n          if [[ -d \"${NB_DIR}/${_maybe_notebook}/.git\" ]]\n          then\n            _notebooks \"${_subcommand}\" \"${_maybe_notebook}\" && return 0\n          fi\n        fi\n        _exit_1 printf \"Not found: %s\\\\n\" \"$(_color_primary \"${_selector}\")\"\n      fi\n\n      local _target_path=\"${_notebook_path}/${_relative_path}\"\n\n      # handle non-bookmarks\n      if [[ \"${_subcommand}\" =~ (^open$|^peek$) ]]\n      then\n        if [[ \"${_relative_path}\" =~ \\.html$  ]]\n        then\n          if [[ \"${_subcommand}\" == \"open\"  ]]\n          then\n            _open_in_gui_app \"${_target_path:-}\" && return 0\n          elif [[ \"${_subcommand}\" == \"peek\"  ]]\n          then\n            _bookmark_view_in_terminal_browser \"file://${_target_path}\"\n\n            return 0\n          fi\n        elif [[ ! \"${_relative_path}\" =~ .bookmark\\.md$       ]] &&\n             [[ ! \"${_relative_path}\" =~ .bookmark\\.md\\.enc$  ]]\n        then\n          if [[ \"${_subcommand}\" == \"open\"    ]]\n          then\n            if [[ -d \"${_target_path:-}\"      ]] &&\n               _open_in_gui_app \"${_target_path:-}\"\n            then\n              return 0\n            elif [[ -n \"${_password}\"         ]]\n            then\n              _edit \"${_selector}\" --password \"${_password}\"\n            else\n              _edit \"${_selector}\"\n            fi\n          elif [[ \"${_subcommand}\" == \"peek\"  ]]\n          then\n            if [[ -n \"${_password}\"           ]]\n            then\n              _show \"${_selector}\" --password \"${_password}\"\n            else\n              _show \"${_selector}\"\n            fi\n          fi\n\n          return 0\n        fi\n      fi\n\n      local _target_url=\n      _target_url=\"$(_show \"${_target_path}\" --url \"${_arguments[@]:-}\")\"\n\n      if [[ \"${_subcommand}\" == \"url\"           ]]\n      then\n        printf \"%s\\\\n\" \"${_target_url}\"\n\n        return 0\n      fi\n\n      if [[ \"${_subcommand}\" =~ (^open$|^peek$) ]]\n      then\n        local _check_wayback=0\n        local _http_error_codes=(\n          404 408 410 451 500 502 503 504 509 520 521 523 524 525 526\n        )\n        local _http_status=\n        _http_status=\"$(_get_http_status \"${_target_url}\")\"\n\n        if _contains \"${_http_status}\" \"${_http_error_codes[@]}\"\n        then\n          printf \"Page no longer available: %s\\\\n\" \\\n            \"$(_color_primary \"${_target_url}\")\"\n\n          while true\n          do\n            local __yn=\n            IFS='' read -r -e -d $'\\n' -p \\\n\"Check the Wayback Machine for an archived version instead? $(_color_brackets \"y/N\") \" __yn\n\n            case \"${__yn}\" in\n              [Yy]*)\n                _check_wayback=1\n\n                break\n                ;;\n              *)\n                break\n                ;;\n            esac\n          done\n        fi\n\n        if ((_check_wayback))\n        then\n          local _wayback_response=\n          _wayback_response=\"$(\n            _download_from --no-chrome                                    \\\n              \"https://archive.org/wayback/available?url=${_target_url}\"  \\\n              | grep 'closest'                                            \\\n              | LC_ALL=C sed -E \"s/.*\\\"closest\\\": {([^}]+)}.*/\\1/g\"       \\\n              | LC_ALL=C sed -E \"s/.*\\\"url\\\": \\\"([^\\\"]+)\\\".*/\\1/g\" || printf \"\"\n          )\"\n\n          if [[ -n \"${_wayback_response:-}\" ]]\n          then\n            _target_url=\"${_wayback_response}\"\n          else\n            _exit_1 printf                  \\\n              \"No archived version available from the Wayback Machine.\\\\n\"\n          fi\n        fi\n      fi\n\n      # `bookmark peek`\n      if [[   \"${_subcommand}\" == \"peek\"    ]]\n      then\n        _bookmark_view_in_terminal_browser \"${_target_url}\"\n\n        return 0\n      # `bookmark open`\n      elif [[ \"${_subcommand}\" == \"open\"    ]]\n      then\n        if _open_in_gui_app \"${_target_url:-}\"\n        then\n          return 0\n        else\n          _exit_1 printf                                          \\\n            \"%s doesn't know how to open URLs on this system.\\\\n\" \\\n            \"$(_color_primary \"${_ME}\")\"\n        fi\n      fi\n    fi\n  }\n\n  # `bookmark`\n\n  if [[   -z \"${_url:-}\"          ]]\n  then\n    if [[ -z \"${_arguments[*]:-}\" ]]\n    then\n      local _line_length=36\n      local _maybe_header_selector=\n\n      if _notebooks current --selected\n      then\n        _maybe_header_selector=\"$(\n          _notebooks show \"$(_notebooks current)\" --no-color --escaped\n        ): \"\n\n        local _padded_header_selector_length=\n        _padded_header_selector_length=\"$(\n          _get_visible_length \"${_maybe_header_selector}\"\n        )\"\n\n        _line_length=\"$((_line_length + _padded_header_selector_length))\"\n      fi\n\n      local _header=\n      _header=\"Add: $(_color_primary \"${_ME} ${_maybe_header_selector}<url>\")\"\n      _header=\"${_header} Help: $(_color_primary \"${_ME} help bookmark\")\"\n\n      printf \"%s\\\\n\" \"${_header}\"\n      _print_line \"$(printf \"%-${_line_length}s\" '.')\"\n    fi\n\n    _bookmark list \"${_arguments[@]:-}\"\n\n    return 0\n  fi\n\n  # `bookmark <url>`\n\n  if ((${#_secondary_urls[@]}))\n  then\n    local __url=\n    for   __url in \"${_url}\" \"${_secondary_urls[@]}\"\n    do\n      # shellcheck disable=SC2046\n      _bookmark \"${__url}\" $(printf \"%s\\\\n\" \"${_non_url_arguments[@]}\")\n    done\n\n    return 0\n  fi\n\n  local _temp_file=\n  _temp_file=\"$(_temp file)\"\n\n  local _download_url=\"${_url}\"\n  _download_url=\"$(\n    printf \"%s\\\\n\" \"${_download_url}\"       \\\n      | LC_ALL=C sed 's/https:\\/\\/twitter.com/https:\\/\\/mobile.twitter.com/g'\n  )\"\n\n  if [[ \"${_selector}\" =~ (:|^/)  ]]\n  then\n    _notebooks select \"${_selector}\"\n  fi\n\n  local _relative_folder_path=\n  local _relative_path=\n\n  _relative_folder_path=\"$(\n    _selector_resolve_folders \"${_arguments[0]:-}\" --build || :\n  )\"\n\n  if [[ -n \"${_relative_folder_path:-}\"     ]]\n  then\n    _relative_folder_path=\"${_relative_folder_path}/\"\n  fi\n\n  if [[ -z \"${_target_filename:-}\"          ]]\n  then\n    _relative_path=\"$(\n      _notebooks current --filename         \\\n        \"${_relative_folder_path}$(date '+%Y%m%d%H%M%S').bookmark.md\"\n    )\"\n  else\n    if [[ \"${_target_filename}\" =~ \\.       ]]\n    then\n      _relative_path=\"$(\n        _notebooks current --filename       \\\n          \"${_relative_folder_path}${_target_filename}\")\"\n    else\n      _relative_path=\"$(\n        _notebooks current --filename       \\\n          \"${_relative_folder_path}${_target_filename}.bookmark.md\"\n      )\"\n    fi\n  fi\n\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  local _duplicate_search_path=\"${_notebook_path}\"\n\n  if [[ -n \"${_relative_folder_path:-}\"     ]]\n  then\n    _duplicate_search_path=\"${_notebook_path}/${_relative_folder_path}\"\n  fi\n\n  if [[ -d \"${_duplicate_search_path:-}\"    ]]\n  then\n    local _grep_command=(\n      grep -s                         \\\n        -e \"^<${_download_url}>\"      \\\n        -e \"^##\"\n    )\n\n    if ((_GIT_ENABLED))\n    then\n      _grep_command=(\n        git -C \"${_notebook_path:-}\"  \\\n          grep                        \\\n          -e \"^<${_download_url}>\"    \\\n          -e \"^##\"                    \\\n          --no-heading                \\\n          --color=never\n      )\n    elif _command_exists \"rg\"\n    then\n      _grep_command=(\n        rg                            \\\n          --color never               \\\n          --no-heading                \\\n          --with-filename             \\\n          -e \"^##\"                    \\\n          -e \"^<${_download_url}>\"\n      )\n    fi\n\n    local _candidate_matches=()\n    _candidate_matches=($(\n      set +o noglob\n\n      \"${_grep_command[@]:-}\"                     \\\n        \"${_duplicate_search_path}/\"*.bookmark.md \\\n        2>/dev/null || :\n\n      set -o noglob\n    ))\n\n    local _duplicate_matches=()\n\n    if ((${#_candidate_matches[@]}))\n    then\n      local _current_filename=\n      local _include_match=1\n\n      local __candidate_match=\n      for   __candidate_match in \"${_candidate_matches[@]:-}\"\n      do\n        if [[ \"${_current_filename:-}\" != \"${__candidate_match%%:*}\"  ]]\n        then\n          _current_filename=\"${__candidate_match%%:*}\"\n          _include_match=1\n        fi\n\n        if [[ \"${__candidate_match#*:}\" =~ ^##                        ]]\n        then\n          _include_match=0\n        fi\n\n        if ((_include_match))\n        then\n          _duplicate_matches+=(\"${_current_filename:-}\")\n\n          _include_match=0\n        fi\n      done\n    fi\n\n    if ((${#_duplicate_matches[@]}))\n    then\n      if [[ \"${#_duplicate_matches[@]}\" == \"1\" ]]\n      then\n        printf      \\\n\"1 bookmark for this URL exists in this folder:\\\\n\"\n      _print_line   \\\n\"----------------------------------------------\"\n      else\n        printf      \\\n\"%s bookmarks for this URL exist in this folder:\\\\n\" \"${#_duplicate_matches[@]}\"\n        _print_line \\\n\"${#_duplicate_matches[@]}----------------------------------------------\"\n      fi\n\n      local __duplicate_match=\n      for   __duplicate_match in \"${_duplicate_matches[@]:-}\"\n      do\n        _show --info-line \"${__duplicate_match%%:*}\"\n      done\n\n      _print_line \"------------------------------\"\n\n      while true\n      do\n        local __yn=\n        IFS='' read -r -e -d $'\\n' -p \\\n\"$(_color_primary \"Create another bookmark?\") $(_color_brackets \"y/N\") \" __yn\n\n        case \"${__yn}\" in\n          [Yy]*)\n            break\n            ;;\n          *)\n            printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n            exit 0\n            ;;\n        esac\n      done\n    fi\n  fi 1>&2\n\n  if ((_request_page))\n  then\n    if ! _download_from \"${_download_url}\" \"${_temp_file}\" ||\n       [[ ! -e \"${_temp_file}\"                          ]] ||\n       [[ \"$(wc -c <\"${_temp_file}\")\" == 0              ]]\n    then\n      _warn printf                            \\\n        \"Unable to download page at %s\\\\n\"    \\\n        \"$(_color_primary \"${_url}\")\"\n    fi\n  fi\n\n  if _file_is_text \"${_temp_file}\"\n  then\n    if [[ -z \"${_title:-}\"  ]] &&\n       [[ \"${_url:-}\" =~ ^https://www.reddit.com ]]\n    then\n      _title=\"$(\n        cat \"${_temp_file}\"                   \\\n          | grep '<shreddit-title title=\"'    \\\n          | sed -n 's/.*<shreddit-title title=\"\\([^\"]*\\)\".*/\\1/p'\n      )\"\n    fi\n\n    if [[ -z \"${_title:-}\"  ]]\n    then\n      _title=\"$(\n        cat \"${_temp_file}\"                   \\\n          | if _command_exists 'iconv'\n            then\n              iconv -c -t utf-8\n            else\n              cat\n            fi                                \\\n          | awk '/<title[^>]*>/,/<\\/title>/'  \\\n          | LC_ALL=C sed -e '/<\\/title>/ q'   \\\n          | LC_ALL=C sed -e 's/<\\/title>.*//' \\\n          | LC_ALL=C sed                      \\\n            -e 's/.*<title[^>]*>//'           \\\n            -e 's/.*<TITLE[^>]*>//'           \\\n            -e 's/<\\/title>.*//'              \\\n            -e 's/<\\/TITLE>.*//'              \\\n          | awk '$1=$1'     ||  :\n      )\"\n    fi\n\n    if [[ -z \"${_title:-}\"  ]]\n    then\n      _title=\"$(\n        cat \"${_temp_file}\"     \\\n          | LC_ALL=C sed -E -n  \\\n            \"s/.*<meta .*property=.og:title[^>]*content=\\\"([^\\\"]+)\\\".*/\\1/p\" \\\n            2>/dev/null     ||  :\n      )\"\n    fi\n  fi\n\n  local _domain=\n  _domain=\"$(printf \"%s\\\\n\" \"${_url}\" | awk -F[/:] '{print $4}')\"\n\n  if [[ -n \"${_domain:-}\"   ]]\n  then\n    [[ -n \"${_title:-}\"     ]]  && _title+=\" \"\n    _title+=\"(${_domain})\"\n  fi\n\n  if [[ -n \"${_title:-}\"    ]]\n  then\n    _title=\"$(_bookmark_cleanup_tag_content \"${_title}\")\"\n\n    _bookmark_content=\"# ${_title}${_NEWLINE}${_NEWLINE}\"\n  fi\n\n  _bookmark_content+=\"<${_url}>${_NEWLINE}\"\n\n  if _file_is_text \"${_temp_file}\"\n  then\n    local _description=\n    _description=\"$(\n      cat \"${_temp_file}\"       \\\n        | LC_ALL=C sed -E -n    \\\n            \"s/.*<meta .*name=.description.[^>]*content=\\\"([^\\\"]+)\\\".*/\\1/p\" \\\n            2>/dev/null     ||  :\n    )\"\n\n    if [[ -z \"${_description:-}\"    ]]\n    then\n      _description=\"$(\n        cat \"${_temp_file}\"     \\\n          | LC_ALL=C sed -E -n  \\\n              \"s/.*<meta .*property=.og:description[^>]*content=\\\"([^\\\"]+)\\\".*/\\1/p\" \\\n              2>/dev/null   ||  :\n      )\"\n    fi\n\n    if [[ -n \"${_description:-}\"    ]]\n    then\n      _description=\"$(_bookmark_cleanup_tag_content \"${_description}\")\"\n\n      _bookmark_content+=\"${_NEWLINE}## Description${_NEWLINE}\"\n      _bookmark_content+=\"${_NEWLINE}${_description}${_NEWLINE}\"\n    fi\n  fi\n\n  if [[ -n \"${_quote:-}\"            ]]\n  then\n    _bookmark_content+=\"${_NEWLINE}## Quote${_NEWLINE}\"\n\n    local _counter=0\n\n    local               __line=\n    while IFS= read -r  __line\n    do\n      if ! ((_counter))\n      then\n        _bookmark_content+=\"${_NEWLINE}> ${__line}${_NEWLINE}\"\n      elif [[ -z \"${__line:-}\"      ]]\n      then\n        _bookmark_content+=\">${_NEWLINE}\"\n      else\n        _bookmark_content+=\"> ${__line}${_NEWLINE}\"\n      fi\n\n      _counter=\"$((_counter+1))\"\n    done <<< \"${_quote}\"\n  fi\n\n  if [[ -n \"${_comment:-}\"          ]]\n  then\n    _bookmark_content+=\"${_NEWLINE}## Comment${_NEWLINE}\"\n    _bookmark_content+=\"${_NEWLINE}${_comment}${_NEWLINE}\"\n  fi\n\n  if [[ -n \"${_related_identifiers[*]:-}\" ]]\n  then\n    _bookmark_content+=\"${_NEWLINE}## Related${_NEWLINE}${_NEWLINE}\"\n    _bookmark_content+=\"$(_build_related_list \"${_related_identifiers[@]:-}\")\"\n    _bookmark_content+=\"${_NEWLINE}\"\n  fi\n\n  if [[ -n \"${_tag_list:-}\"         ]]\n  then\n    _bookmark_content+=\"${_NEWLINE}## Tags${_NEWLINE}\"\n    _bookmark_content+=\"${_NEWLINE}${_tag_list}${_NEWLINE}\"\n  fi\n\n  if _file_is_text \"${_temp_file}\"\n  then\n    if ! ((_skip_content))\n    then\n      local _processed_content=\n\n      if  {\n            [[ \"${_content_conversion_tool:-}\"  == \"pandoc\"   ]] &&\n            _command_exists \"pandoc\"\n          } || {\n            [[ \"${_content_cleanup_tool:-}\"     =~ readab     ]] &&\n            _command_exists \"readable\"\n          } || {\n            [[ \"${_content_cleanup_tool}\"       == \"rdrview\"  ]] ||\n            _contains \"${_content_conversion_tool}\" \\\n                      \"html2markdown\"               \\\n                      \"html-to-markdown\"            \\\n                      \"markitdown\"\n          }\n      then\n        _processed_content=\"$(\n          {\n            cat \"${_temp_file}\"\n          } | {\n            if [[ \"${_content_cleanup_tool:-}\"  =~ readab     ]] &&\n               _command_exists \"readable\"\n            then # https://www.npmjs.com/package/readability-cli\n              readable            \\\n                --base \"${_url}\"  \\\n                --quiet           \\\n                2>/dev/null || cat\n            else\n              cat\n            fi\n          } | {\n            if [[ \"${_content_cleanup_tool}\"    == \"rdrview\"  ]] &&\n               _command_exists \"rdrview\"\n            then # https://github.com/eafer/rdrview\n              rdrview -H -u \"${_url}\"\n            else\n              cat\n            fi\n          } | {\n            if [[ \"${_content_conversion_tool:-}\"  == \"markitdown\"  ]] &&\n               _command_exists \"markitdown\"\n            then # https://github.com/microsoft/markitdown\n              markitdown\n            else\n              cat\n            fi\n          } | {\n            if [[ \"${_content_conversion_tool:-}\"  == \"pandoc\"      ]]\n               _command_exists \"pandoc\"\n            then # https://pandoc.org\n              {\n                _pandoc                                 \\\n                  --standard-input                      \\\n                  --from  html-native_divs-native_spans \\\n                  --to    markdown-grid_tables          \\\n                  --wrap=none                           \\\n                  2>/dev/null || cat\n              } | {\n                # strip empty list items\n                LC_ALL=C sed -E -e 's/^-[[:space:]]*$//g'\n              }\n            else\n              cat\n            fi\n          } | {\n            if _contains  \"${_content_conversion_tool}\" \\\n                          \"html2markdown\"               \\\n                          \"html-to-markdown\"            &&\n               _command_exists \"html2markdown\"\n            then # https://github.com/JohannesKaufmann/html-to-markdown\n              html2markdown\n            else\n              cat\n            fi\n          }\n        )\"\n\n        if [[ -n \"${_processed_content}\"  ]]\n        then\n          _bookmark_content+=\"${_NEWLINE}## Content${_NEWLINE}\"\n          _bookmark_content+=\"${_NEWLINE}${_processed_content}${_NEWLINE}\"\n        fi\n      else\n        _save_source=1\n      fi\n    fi\n\n    if ((_save_source))\n    then\n      _bookmark_content+=\"${_NEWLINE}## Source${_NEWLINE}\"\n      _bookmark_content+=\"${_NEWLINE}${_BT}${_BT}${_BT}html${_NEWLINE}\"\n      _bookmark_content+=\"$(cat \"${_temp_file}\")\"\n      _bookmark_content+=\"${_NEWLINE}${_BT}${_BT}${_BT}${_NEWLINE}\"\n    fi\n  fi\n\n  if [[ -n \"${_bookmark_content}\"         ]]\n  then\n\n    local _add_options=(\n      \"${_relative_path}\"\n      --content \"${_bookmark_content}\"\n      --skip-standard-input\n      --no-template\n    )\n\n    ((_encrypt))                &&  _add_options+=(\"--encrypt\")\n    ((_edit_before_commit))     &&  _add_options+=(\"--edit\")\n    [[ -n \"${_password:-}\"  ]]  &&  _add_options+=(\"--password\" \"${_password}\")\n\n    if ! ((_skip_folder_prompt))\n    then\n      _add_options+=(\"--folder-prompt\")\n    fi\n\n    _add \"${_add_options[@]}\"\n\n    [[ -f \"${_temp_file:-}\" ]]  &&  rm -f \"${_temp_file:?}\"\n\n    return 0\n  fi\n}\n_alias_subcommand \"bookmark\" \"bk\"\n_alias_subcommand \"bookmark\" \"bm\"\n_alias_subcommand \"bookmark\" \"bookmarks\"\n\n# completions ##################################################### completions\n\n_describe_completions() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} completions (check | install [-d | --download] | uninstall)\n\n$(_color_primary \"Options\"):\n  -d, --download  Download the completion scripts and install.\n\n$(_color_primary \"Description\"):\n  Manage completion scripts.\n\n$(_color_primary \"Read More\"):\n  https://github.com/${_REPO}/blob/${_REPO_MAIN_BRANCH}/etc/README.md\n\n$(_color_primary \"See Also\"):\n  ${_ME} help env\nHEREDOC\n}\n_completions() {\n  local _BASH_COMP_NAME=\"${_ME}\"\n  local _FISH_COMP_NAME=\"${_ME}.fish\"\n  local _ZSH_COMP_NAME=\"_${_ME}\"\n\n  # Usage: _completions_check\n  _completions_check() {\n    local _exists=0\n\n    local __shell=\n    for   __shell in bash fish zsh\n    do\n      local _completion_path=\n      local _completion_target=\n\n      case \"${__shell}\" in\n        bash)\n          _completion_path=\"$(_get_bash_completion_path)\"\n          _completion_target=\"${_completion_path}/${_BASH_COMP_NAME}\"\n          ;;\n        fish)\n          _completion_path=\"$(_get_fish_completion_path)\"\n          _completion_target=\"${_completion_path}/${_FISH_COMP_NAME}\"\n          ;;\n        zsh)\n          _completion_path=\"/usr/local/share/zsh/site-functions\"\n          _completion_target=\"${_completion_path}/${_ZSH_COMP_NAME}\"\n          ;;\n      esac\n\n      if [[ -d \"${_completion_path}\"        ]]\n      then\n        if [[ -w \"${_completion_path}\"      ]]\n        then\n          if [[ -e \"${_completion_target}\"  ]]\n          then\n            _exists=1\n\n            printf \"Exists: %s\\\\n\" \"${_completion_target}\"\n          fi\n        else\n          _warn printf \"Permission denied: %s\\\\n\" \"${_completion_path}\"\n        fi\n      fi\n    done\n\n    if ! ((_exists))\n    then\n      _exit_1 printf \"Completion scripts not found.\\\\n\"\n    fi\n  }\n\n  # Usage: _get_bash_completion_path\n  _get_bash_completion_path() {\n    local _bash_completion_path=\n\n    if [[ -n \"${BASH_COMPLETION_COMPAT_DIR:-}\"  ]]\n    then\n      _bash_completion_path=\"${BASH_COMPLETION_COMPAT_DIR}\"\n    fi\n\n    if [[ -z \"${_bash_completion_path:-}\"       ]]\n    then\n      local _maybe_path=\n      _maybe_path=\"$(\n        pkg-config --variable=completionsdir bash-completion 2>/dev/null || :\n      )\"\n\n      if [[ -n \"${_maybe_path:-}\"               ]]\n      then\n        _bash_completion_path=\"${_maybe_path}\"\n      fi\n    fi\n\n    if [[ -z \"${_bash_completion_path:-}\"       ]] &&\n       [[ -d \"/usr/local/etc/bash_completion.d\" ]]\n    then\n      _bash_completion_path=\"/usr/local/etc/bash_completion.d\"\n    fi\n\n    if [[ -z \"${_bash_completion_path:-}\"       ]] &&\n       [[ -d \"/etc/bash_completion.d\"           ]]\n    then\n      _bash_completion_path=\"/etc/bash_completion.d\"\n    fi\n\n    printf \"%s\\\\n\" \"${_bash_completion_path:-}\"\n  }\n\n  # Usage: _get_fish_completion_path\n  _get_fish_completion_path() {\n    local _fish_completion_path=\n\n    if [[ -z \"${_fish_completion_path:-}\"                 ]] &&\n       [[ -d \"/usr/local/share/fish/vendor_completions.d\" ]]\n    then\n      _fish_completion_path=\"/usr/local/share/fish/vendor_completions.d\"\n    fi\n\n    if [[ -z \"${_fish_completion_path:-}\"       ]]\n    then\n      local _maybe_path=\n      _maybe_path=\"$(\n        pkg-config --variable=completionsdir fish 2>/dev/null || :\n      )\"\n\n      if [[ -n \"${_maybe_path:-}\"               ]]\n      then\n        _fish_completion_path=\"${_maybe_path}\"\n      fi\n    fi\n\n    if [[ -z \"${_fish_completion_path:-}\"                 ]] &&\n       [[ -d \"/usr/share/fish/vendor_completions.d\"       ]]\n    then\n      _fish_completion_path=\"/usr/share/fish/vendor_completions.d\"\n    fi\n\n    printf \"%s\\\\n\" \"${_fish_completion_path:-}\"\n  }\n\n  _get_zsh_completion_path() {\n      local _zsh_completion_path=\n\n      if [[ -z \"${_zsh_completion_path:-}\"                 ]] &&\n         [[ -d \"/usr/local/share/zsh/site-functions\" ]]\n      then\n        _zsh_completion_path=\"/usr/local/share/zsh/site-functions\"\n      fi\n\n      if [[ -z \"${_zsh_completion_path:-}\"                 ]] &&\n         [[ -d \"/usr/share/zsh/site-functions\"       ]]\n      then\n        _zsh_completion_path=\"/usr/share/zsh/site-functions\"\n      fi\n\n      printf \"%s\\\\n\" \"${_zsh_completion_path:-}\"\n  }\n\n  # Usage: _completions_install [--download]\n  _completions_install() {\n    local _download=0\n    if [[ \"${1:-}\" == \"--download\"  ]]\n    then\n      _download=1\n    fi\n\n    local _my_path=\"${0}\"\n\n    if [[ -L \"${_my_path}\"          ]]\n    then\n      _my_path=\"$(_resolve_symlink \"${_my_path}\")\"\n    fi\n\n    local _my_dir=\n    _my_dir=\"$(cd \"$(dirname \"${_my_path}\")\"; pwd)\"\n    if [[ -z \"${_my_dir}\"   ]]  ||  [[ ! -d \"${_my_dir}\"        ]]\n    then\n      exit 1\n    fi\n\n    if [[ -z \"${_REPO:-}\"   ]]  ||  [[ -z \"${_REPO_RAW_URL:-}\"  ]]\n    then\n      _exit_1 printf \"Source Git repository not configured.\\\\n\"\n    fi\n\n    local __shell=\n    for   __shell in bash fish zsh\n    do\n      local _completion_source=\"${_my_dir}/etc/${_ME}-completion.${__shell}\"\n\n      if ((_download))\n      then\n        if [[ ! -f \"${_completion_source}\"  ]]\n        then\n          _completion_source=\"$(_temp file)\"\n          local _completion_url=\"${_REPO_RAW_URL}/etc/${_ME}-completion.${__shell}\"\n\n          if ! _download_from \"${_completion_url}\" \"${_completion_source}\" --no-chrome\n          then\n            _exit_1 printf \"Unable to download completion script from %s\\\\n\" \\\n              \"${_completion_source}\"\n          fi\n        fi\n      fi\n\n      if [[ ! -f \"${_completion_source}\"    ]]\n      then\n        cat <<HEREDOC\nUnable to find source ${__shell} completion script. You can try downloading\nand installing the latest version with the following command (\\`sudo\\` might\nbe necessary):\n  ${_ME} completions install --download\n\nMore Information: ${__shell}\n  https://github.com/${_REPO}/blob/${_REPO_MAIN_BRANCH}/etc/README.md\nHEREDOC\n      else\n        local _completion_path=\n        local _completion_target=\n\n        case \"${__shell}\" in\n          bash)\n            _completion_path=\"$(_get_bash_completion_path)\"\n            _completion_target=\"${_completion_path}/${_BASH_COMP_NAME}\"\n            ;;\n          fish)\n            _completion_path=\"$(_get_fish_completion_path)\"\n            _completion_target=\"${_completion_path}/${_FISH_COMP_NAME}\"\n            ;;\n          zsh)\n            _completion_path=\"$(_get_zsh_completion_path)\"\n            _completion_target=\"${_completion_path}/${_ZSH_COMP_NAME}\"\n            ;;\n        esac\n\n        if [[ -n \"${_completion_path:-}\"        ]] &&\n           [[ -d \"${_completion_path}\"          ]]\n        then\n          if [[ -w \"${_completion_path}\"        ]]\n          then\n            if [[ ! -e \"${_completion_target}\"  ]]\n            then\n              cp                                \\\n                \"${_completion_source}\"         \\\n                \"${_completion_target}\"\n\n              chmod +r \"${_completion_target}\"\n\n              printf \"Completion script installed: %s\\\\n\" \\\n                \"${_completion_target}\"\n            else\n              _warn printf \"Exists: %s\\\\n\" \"${_completion_target}\"\n            fi\n          else\n            _warn printf \"Permission denied: %s\\\\n\" \"${_completion_path}\"\n          fi\n        fi\n      fi\n    done\n  }\n\n  # Usage: _completions_uninstall\n  _completions_uninstall() {\n    local _completion_path=\n    local _completion_target=\n\n    local __shell=\n    for   __shell in bash fish zsh\n    do\n      case \"${__shell}\" in\n        bash)\n          _completion_path=\"$(_get_bash_completion_path)\"\n          _completion_target=\"${_completion_path}/${_BASH_COMP_NAME}\"\n          ;;\n        fish)\n          _completion_path=\"$(_get_fish_completion_path)\"\n          _completion_target=\"${_completion_path}/${_FISH_COMP_NAME}\"\n          ;;\n        zsh)\n          _completion_path=\"/usr/local/share/zsh/site-functions\"\n          _completion_target=\"${_completion_path}/${_ZSH_COMP_NAME}\"\n          ;;\n      esac\n\n      if [[ -n \"${_completion_path:-}\"  ]] &&\n         [[ -d \"${_completion_path}\"    ]]\n      then\n        if [[ -w \"${_completion_path}\"    ]] &&\n           [[ -w \"${_completion_target}\"  ]]\n        then\n          if [[ -f \"${_completion_target}\"  ]]\n          then\n            rm \"${_completion_target:?}\"\n\n            printf \"Completion script removed: %s\\\\n\" \\\n              \"${_completion_target}\"\n          fi\n        else\n          _warn printf \"Permission denied: %s\\\\n\" \"${_completion_path}\"\n        fi\n      fi\n    done\n  }\n\n  local _subcommand=\"${1:-}\"\n\n  case \"${_subcommand}\" in\n    check)\n      _completions_check\n      ;;\n    install)\n      if [[ \"${2:-}\" =~ (^-d|--download$)   ]]\n      then\n        _completions_install --download\n      else\n        _completions_install\n      fi\n      ;;\n    uninstall)\n      _completions_uninstall\n      ;;\n    *)\n      _help \"completions\"\n\n      return 0\n      ;;\n  esac\n}\n\n# delete ############################################################### delete\n\n_describe_delete() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])...\n            [-f | --force]\n\n$(_color_primary \"Options\"):\n  -f, --force   Skip the confirmation prompt.\n\n$(_color_primary \"Description\"):\n  Delete one or more items.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#deleting\n\n$(_color_primary \"See Also\"):\n  ${_ME} help add\n  ${_ME} help browse\n  ${_ME} help edit\n  ${_ME} help move\n  ${_ME} help show\n\n$(_color_primary \"Examples\"):\n  ${_ME} delete 3\n  ${_ME} delete example.md\n  ${_ME} delete \"A Document Title\"\n  ${_ME} 3 delete --force\n  ${_ME} example:delete 12\n  ${_ME} delete example:12\n  ${_ME} example:12 delete\n  ${_ME} d 3\n  ${_ME} 3 d\n  ${_ME} d example:12\n  ${_ME} example:12 d\n\n$(_color_primary \"Aliases\"):\n  ${_ME} rm\n  ${_ME} trash\n\n$(_color_primary \"Shortcut Aliases\"):\n  ${_ME} d\n  ${_ME} -\nHEREDOC\n}\n_delete() {\n  local _force=0\n  local _print_prompt_list=0\n  local _selectors=()\n  local _title=\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      -f|--force|--skip*|-y|--yes)\n        _force=1\n        ;;\n      --prompt-list)\n        _print_prompt_list=1\n        ;;\n      --quiet)\n        _QUIET=1\n        ;;\n      *)\n        [[ -n \"${__arg:-}\"  ]]  && _selectors+=(\"${__arg:-}\")\n        ;;\n    esac\n  done\n\n  if ! ((${#_selectors[@]}))\n  then\n    _exit_1 _help \"delete\"\n  fi\n\n  local _notebook_paths=()\n  local _notebook_selectors=()\n  local _target_paths=()\n  local _target_selectors=()\n\n  local __selector=\n  for   __selector in \"${_selectors[@]:-}\"\n  do\n    [[ -z \"${__selector:-}\"       ]]  && continue\n\n    local _selector_path=\n    _selector_path=\"$(_show \"${__selector:-}\" --path 2>/dev/null || :)\"\n\n    local _selector_notebook_path=\n    _selector_notebook_path=\"$(_notebooks show \"${__selector:-}\" --path 2>/dev/null || :)\"\n\n    if [[ -n \"${_selector_path}\" ]]\n    then\n      if [[ \"${_selector_path:-}\" == \"${_selector_notebook_path:-}\" ]]\n      then\n        _notebook_paths+=(\"${_selector_notebook_path}\")\n        _notebook_selectors+=(\"${__selector}\")\n      else\n        _target_paths+=(\"${_selector_path}\")\n        _target_selectors+=(\"${__selector}\")\n      fi\n    elif [[ -n \"${_selector_notebook_path:-}\" ]] &&\n         {\n           [[ -z  \"${__selector##*:}\"         ]] ||\n           [[ !   \"${__selector:-}\" =~ :      ]]\n         }\n    then\n      _notebook_paths+=(\"${_selector_notebook_path}\")\n      _notebook_selectors+=(\"${__selector}\")\n    else\n      _exit_1 printf \"Not found: %s\\\\n\" \"$(_color_primary \"${__selector}\")\"\n    fi\n  done\n\n  local __notebook_selector=\n  for   __notebook_selector in \"${_notebook_selectors[@]:-}\"\n  do\n    [[ -z \"${__notebook_selector:-}\" ]]  && continue\n\n    if ((_force))\n    then\n      _notebooks delete \"${__notebook_selector}\" --force\n    else\n      _notebooks delete \"${__notebook_selector}\"\n    fi\n  done\n\n  if ! ((${#_target_paths[@]}))\n  then\n    return\n  fi\n\n  if ((_print_prompt_list))     || ! ((_force))\n  then\n    if [[ \"${#_target_paths[@]}\"   == 1  ]]\n    then\n      printf \"Deleting: %s\\\\n\" \"$(_show \"${_target_selectors[0]:-}\" --info-line)\"\n    else\n      printf \"Deleting:\\\\n\"\n\n      local __prompt_selector=\n      for   __prompt_selector in \"${_target_paths[@]:-}\"\n      do\n        [[ -z \"${__prompt_selector:-}\" ]] && continue\n\n        printf \"%s\\\\n\" \"$(_show \"${__prompt_selector:-}\" --info-line)\"\n      done\n\n    fi\n  fi\n\n  if ! ((_force))\n  then\n    while true\n    do\n      local __yn=\n      IFS='' read -r -e -d $'\\n' -p \\\n\"$(_color_primary \"Proceed?\")  $(_color_brackets \"y/N\") \" __yn\n\n      case \"${__yn}\" in\n        [Yy]*)\n          break\n          ;;\n        *)\n          printf \"Exiting...\\\\n\"\n\n          exit 0\n          ;;\n      esac\n    done\n  fi\n\n  local __delete_selector=\n  for   __delete_selector in \"${_target_paths[@]:-}\"\n  do\n    local _info_line=\n    _info_line=\"$(_show \"${__delete_selector:-}\" --info-line)\"\n\n    local _relative_path=\n    _relative_path=\"$(_show \"${__delete_selector}\" --relative-path)\"\n\n    local _notebook_path=\n    _notebook_path=\"$(\n      _notebooks show \"${__delete_selector:-}\" --path ||\n        _notebooks current --path\n    )\"\n\n    local _basename=\"${_relative_path##*\\/}\"\n    local _folder_path=\"${_notebook_path}\"\n\n    if [[ \"${_relative_path:-}\" =~ / ]]\n    then\n      _folder_path=\"${_notebook_path}/${_relative_path%\\/*}\"\n    fi\n\n    if [[ -n \"${_basename}\" ]] && [[ -e \"${_notebook_path}/${_relative_path}\" ]]\n    then\n      _pin unpin \"${_notebook_path}/${_relative_path}\" &> /dev/null || :\n\n      if [[ -d \"${_notebook_path}/${_relative_path}\"            ]]  &&\n         [[ -z \"$(ls -A \"${_notebook_path}/${_relative_path}\")\" ]]\n      then\n        rm -r \"${_notebook_path:?}/${_relative_path:?}\"\n      else\n        if git -C \"${_notebook_path:?}\" check-ignore    \\\n             \"${_notebook_path:?}/${_relative_path:?}\" 1>/dev/null\n        then\n          rm -r \"${_notebook_path:?}/${_relative_path:?}\"\n        else\n          git -C \"${_notebook_path:?}\" rm -r            \\\n            \"${_notebook_path:?}/${_relative_path:?}\" 1>/dev/null\n        fi\n      fi\n\n      if [[ ! -e \"${_notebook_path}/${_relative_path}\"  ]]\n      then\n        _index delete \"${_basename}\" \"${_folder_path}\"\n\n        _git checkpoint \"${_notebook_path}\" \"[${_ME}] Delete: ${_relative_path}\"\n\n        if ! ((_QUIET))\n        then\n          printf \"Deleted:  %s\\\\n\" \"${_info_line}\"\n        fi\n      fi\n    else\n      _exit_1 printf \"Selection not found.\\\\n\"\n    fi\n  done\n}\n_alias_subcommand \"delete\" \"-\"\n_alias_subcommand \"delete\" \"d\"\n_alias_subcommand \"delete\" \"rm\"\n_alias_subcommand \"delete\" \"trash\"\n\n# edit ################################################################### edit\n\n_describe_edit() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [-c <content> | --content <content>] [--edit]\n          [-e <editor> | --editor <editor>] [-l | --last] [--overwrite]\n          [--prepend]\n\n$(_color_primary \"Options\"):\n  -c, --content <content>  Content to add to the item.\n  --edit                   Open the note in the editor before saving when\n                           content is piped or passed as an argument.\n  -e, --editor <editor>    Edit the note with <editor>, overriding the editor\n                           specified in the \\`\\$EDITOR\\` environment variable.\n  -l, --last               Edit the last modified item.\n  --overwrite              Overwrite existing content with <content> and\n                           standard input.\n  --prepend                Prepend <content> and standard input before\n                           existing content.\n\n$(_color_primary \"Description\"):\n  Open the specified note in \\`\\$EDITOR\\`, currently set to: ${NB_EDITOR}\n\n  Content piped to \\`${_ME} edit\\` or passed using the \\`--content\\` option\n  is appended to the file without opening it in the editor, unless the\n  \\`--edit\\` flag is specified.\n\n  Non-text files are opened in your system's preferred app or program for\n  that file type.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#editing\n\n$(_color_primary \"See Also\"):\n  ${_ME} help add\n  ${_ME} help browse\n  ${_ME} help delete\n  ${_ME} help move\n  ${_ME} help show\n\n$(_color_primary \"Examples\"):\n  ${_ME} edit 3\n  ${_ME} edit example.md\n  ${_ME} edit \"A Document Title\"\n  echo \"Content to append.\" | ${_ME} edit 1\n  ${_ME} 3 edit\n  ${_ME} example:edit 12\n  ${_ME} edit example:12\n  ${_ME} example:12 edit\n  ${_ME} e 12\n  ${_ME} 12 e\n  ${_ME} e example:12\n  ${_ME} example:12 e\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} e\nHEREDOC\n}\n_edit() {\n  local _content=\n  local _content_option_present=0\n  local _edit_before_commit=0\n  local _edit_type=\"append\"\n  local _edit_last_item=0\n  local _local_editor=\n  local _password=\n  local _selector=\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      -c|--content)\n        _content_option_present=1\n\n        if [[ -z \"${2:-}\"                   ]]\n        then\n          _exit_1 printf                          \\\n            \"%s requires a valid argument.\\\\n\"    \\\n            \"$(_color_primary \"${1:-}\")\"\n        else\n          if [[ -n \"${_content:-}\"          ]]\n          then\n            _content+=\"${_NEWLINE}${_NEWLINE}\"\n          fi\n\n          _content+=\"$(printf \"%s\\\\n\" \"${2:-}\")\"\n\n          shift\n        fi\n        ;;\n      --edit)\n        _edit_before_commit=1\n        ;;\n      -e|--editor)\n        _local_editor=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --append|--overwrite|--prepend)\n        _edit_type=\"${1#--}\"\n\n        if [[ -n  \"${2:-}\"                    ]] &&\n           [[ !   \"${2:-}\" =~ ^--[A-Za-z0-9]+ ]] &&\n           ! _contains \"${2:-}\" \"-c\" \"-e\"\n        then\n          if [[ -n \"${_content:-}\"            ]]\n          then\n            _content+=\"${_NEWLINE}\"\n          fi\n\n          _content+=\"$(printf \"%s\\\\n\" \"${2:-}\")\"\n\n          shift\n        fi\n        ;;\n      -l|--last*)\n        if [[ \"${2:-}\" =~ ^[0-9]+$  ]]\n        then\n          _edit_last_item=\"${2:-}\"\n\n          shift\n        else\n          _edit_last_item=1\n        fi\n        ;;\n      --password)\n        _password=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --quiet)\n        _QUIET=1\n        ;;\n      *)\n        if [[ -z \"${_selector:-}\"   ]]\n        then\n          _selector=\"${1:-}\"\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  if ((_edit_last_item)) && [[ -z \"${_selector:-}\" ]]\n  then\n    _selector=\"$(\n      if [[ -n \"$(ls \"${_notebook_path}\")\" ]]\n      then\n        if stat -f '%m %N' . >/dev/null 2>&1\n        then # macOS (BSD stat)\n          find \"${_notebook_path}\"                        \\\n            -type d -name '.*' -prune -o -type f -print0  \\\n            | xargs -0 stat -f '%m %N' 2>/dev/null        \\\n            | sort -rn                                    \\\n            | head -n 1                                   \\\n            | cut -d' ' -f2-\n        else # Linux (GNU stat)\n          find \"${_notebook_path}\"                        \\\n            -type d -name '.*' -prune -o -type f -print0  \\\n            | xargs -0 stat -c '%Y %n' 2>/dev/null        \\\n            | sort -rn                                    \\\n            | head -n 1                                   \\\n            | cut -d' ' -f2-\n        fi\n      fi\n    )\"\n  fi\n\n  if [[ -z \"${_selector:-}\" ]]\n  then\n    _exit_1 _help \"edit\"\n  fi\n\n  local _relative_path=\n  _relative_path=\"$(_show \"${_selector:-}\" --relative-path)\"\n\n  local _basename=\"${_relative_path##*\\/}\"\n  local _folder_path=\"${_relative_path%\\/*}\"\n\n  if [[ -z \"${_relative_path:-}\"  ]]\n  then\n    _exit_1 printf \"Not found: %s\\\\n\" \"$(_color_primary \"${_relative_path}\")\"\n  fi\n\n  if [[ -n \"${_relative_path}\"                    ]] &&\n     [[ -e \"${_notebook_path}/${_relative_path}\"  ]]\n  then\n    local _before=\n    _before=\"$(_get_hash \"${_notebook_path}/${_relative_path}\")\"\n\n    local _decrypted_path=\n    local _encrypted_path=\n    local _encryption_tool=\n    local _target_file=\"${_notebook_path}/${_relative_path}\"\n\n    if _file_is_encrypted \"${_target_file}\"\n    then\n      _encrypted_path=\"${_target_file}\"\n      _encryption_tool=\"$(_get_decryption_tool \"${_encrypted_path:-}\")\"\n\n      if [[    \"${_encryption_tool:-}\" != \"age\"   ]] &&\n         [[ -z \"${_password}\"                     ]]\n      then\n        # request password without displaying it\n        printf \"%s: \" \"$(_color_primary \"Password\")\"\n\n        IFS='' read -r -e -d $'\\n' -s _password </dev/tty\n\n        if [[ -z \"${_password}\"                   ]]\n        then\n          _exit_1 printf \"Password required.\\\\n\"\n        fi\n      fi\n\n      _decrypted_path=\"$(_decrypt_file \"${_target_file}\" \"${_password:-}\")\"\n\n      _target_file=\"${_decrypted_path}\"\n\n      _before=\"$(_get_hash \"${_decrypted_path}\")\"\n    fi\n\n    if [[ -n \"${_content:-}\"      ]] || _piped_input\n    then\n      {\n        if [[ -n \"${_content}\"    ]]\n        then\n          printf \"%s\\\\n\" \"${_content}\"\n        fi\n\n        if _piped_input\n        then\n          cat\n        fi\n      } | {\n        if [[   \"${_edit_type:-}\" == \"overwrite\"  ]]\n        then\n          cat > \"${_target_file}\"\n        elif [[ \"${_edit_type:-}\" == \"prepend\"    ]]\n        then\n          local _prepend_temp=\n          _prepend_temp=\"$(_temp file)\"\n\n          cat                       >   \"${_prepend_temp:?}\"\n\n          if ((_content_option_present))\n          then\n            printf \"\\\\n\"            >>  \"${_prepend_temp:?}\"\n          fi\n\n          cat \"${_target_file}\"     >>  \"${_prepend_temp:?}\"\n\n          cat \"${_prepend_temp:?}\"  >   \"${_target_file}\"\n\n          if [[ -f \"${_prepend_temp:?}\" ]]\n          then\n            rm  \"${_prepend_temp:?}\"\n          fi\n        else\n          if ((_content_option_present))\n          then\n            printf \"\\\\n\"  >>  \"${_target_file}\"\n          fi\n\n          cat             >>  \"${_target_file}\"\n        fi\n      }\n    fi\n\n    if ((_edit_before_commit)) || {\n       ! _piped_input && [[ -z \"${_content:-}\"    ]]\n    }\n    then\n      if [[ -n \"${_local_editor}\"   ]]\n      then\n        NB_EDITOR=\"${_local_editor}\" _edit_file \"${_target_file}\"\n      else\n        _edit_file \"${_target_file}\"\n      fi\n    fi\n\n    local _after=\n    _after=\"$(_get_hash \"${_notebook_path}/${_relative_path}\")\"\n\n    if [[ -n \"${_encrypted_path:-}\" ]]  &&  [[ -e \"${_decrypted_path:-}\" ]]\n    then\n      _after=\"$(_get_hash \"${_decrypted_path}\")\"\n\n      if [[ \"${_before}\" != \"${_after}\" ]]\n      then\n        local _temp_encrypted_path=\n        _temp_encrypted_path=\"$(_temp file \"${_relative_path}\").tmp\"\n\n        mv \"${_encrypted_path}\" \"${_temp_encrypted_path}\"\n\n        _encrypt_file                   \\\n          \"${_decrypted_path}\"          \\\n          \"${_encrypted_path}\"          \\\n          --password \"${_password:-}\"   \\\n          --tool \"${_encryption_tool:-}\"\n\n        if [[ -e \"${_temp_encrypted_path:-}\"  ]]\n        then\n          if [[ -e \"${_encrypted_path:?}\"     ]]\n          then\n            rm \"${_temp_encrypted_path:?}\"\n          else\n            mv \"${_temp_encrypted_path}\" \"${_encrypted_path}\"\n          fi\n        fi\n      fi\n\n      rm \"${_decrypted_path:?}\"\n    fi\n\n    _git checkpoint \"${_notebook_path}\" \"[${_ME}] Edit: ${_relative_path}\"\n\n    if [[ \"${_before}\" != \"${_after}\"   ]]\n    then\n      local _info=\n      _info=\"$(_show \"${_relative_path}\" --info-line)\"\n\n      if ! ((_QUIET))\n      then\n        printf \"Updated: %s\\\\n\" \"${_info}\"\n      fi\n    fi\n  else\n    _exit_1 printf \"Selection not found.\\\\n\"\n  fi\n}\n_alias_subcommand \"edit\" \"e\"\n\n# env ##################################################################### env\n\n_describe_env() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} env [-l | --long]\n  ${_ME} env [install | update] [--ace | --mathjax]\n\n$(_color_primary \"Subcommands\"):\n  (default) Print environment and configuration information.\n  install   Install dependencies on supported systems.\n  update    Update dependencies.\n\n$(_color_primary \"Options\"):\n  --ace       Install or update Ace editor [1][2].\n  -l, --long  Print additional environmental information.\n  --mathjax   Install or update MathJax [3].\n\n    1. https://github.com/ajaxorg/ace\n    2. https://github.com/ajaxorg/ace-builds\n    3. https://github.com/mathjax/MathJax\n\n$(_color_primary \"Description\"):\n  Print program environment and configuration information, or install\n  dependencies.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#installation\n\n$(_color_primary \"See Also\"):\n  ${_ME} help completions\n  ${_ME} help init\n  ${_ME} help update\n  ${_ME} help version\nHEREDOC\n}\n_env() {\n  # Usage: _env_install_deb <name> <version> <repo>\n  _env_install_deb() {\n    local _deb_filename=\n    local _name=\"${1:?}\"\n    local _repo=\"${3:?}\"\n    local _version=\"${2:?}\"\n    local _x86_64_bit=1\n\n    local _arch=\n    _arch=\"$(uname -m)\"\n\n    case \"${_arch:-}\" in\n      x86_64)\n        _deb_filename=\"${_name}_${_version}_amd64.deb\"\n        ;;\n      aarch64)\n        _x86_64_bit=0\n        _deb_filename=\"${_name}_${_version}_arm64.deb\"\n        ;;\n      arm*)\n        _x86_64_bit=0\n        _deb_filename=\"${_name}_${_version}_armhf.deb\"\n        ;;\n    esac\n\n    if [[ -z \"${_deb_filename:-}\"   ]]  || {\n         [[ \"${_name}\" == \"ripgrep\" ]]  && ! ((_x86_64_bit))\n       }\n    then\n      _warn printf                                                      \\\n        \"Please install %s manually. No .deb package available for %s.\" \\\n        \"$(_color_primary \"${_name}\")\"                                  \\\n        \"$(_color_primary \"${_arch}\")\"\n      return 0\n    fi\n\n    local _deb_path=\"${HOME}/${_deb_filename}\"\n\n    # handle bat version prefix in URL\n    [[ \"${_name}\" == \"bat\"  ]] && _version=\"v${_version}\"\n\n    wget                    \\\n      -O \"${_deb_path}\"     \\\n      \"https://github.com/${_repo}/releases/download/${_version}/${_deb_filename}\"\n\n    if [[ -e \"${_deb_path}\" ]]\n    then\n      dpkg -i \"${_deb_path}\"\n      rm \"${_deb_path:?}\"\n    fi\n  }\n\n  # Usage: _env_max_version <version> <version>\n  _env_max_version() {\n    printf \"%s\\\\n\" \"${@:?}\"                           \\\n      | sort -r -t '.' -k 1,1 -k 2,2 -k 3,3 -k 4,4 -g \\\n      | head -n 1\n  }\n\n  local _subcommand=\"${1:-}\"\n\n  case \"${_subcommand}\" in\n    install|update)\n      if ! _contains \"${2:-}\" \"--ace\" \"--mathjax\"\n      then # skip to next section if `_env install --ace`\n        # packages: curl pandoc pygments w3m ripgrep tig\n        if [[ -x \"$(command -v apk)\"  ]]\n        then\n          _completions install --download\n\n          apk add --no-cache  \\\n            bash-completion   \\\n            curl              \\\n            pandoc            \\\n            py3-pygments      \\\n            ripgrep           \\\n            tig               \\\n            w3m\n        elif [[ -x \"$(command -v apt-get)\" ]]\n        then\n          _completions install --download\n\n          local _apt_packages=()\n          local _deb_packages=()\n          local _dependencies=(\n            bash-completion\n            bat\n            curl\n            ncat\n            pandoc\n            python3-pygments\n            ripgrep\n            socat\n            tig\n            w3m\n          )\n\n          [[ \"$(cat /etc/os-release)\" =~ (ubuntu|debian) ]] || return 1\n\n          apt-get update\n\n          local __package=\n          for   __package in \"${_dependencies[@]}\"\n          do\n            if ! _command_exists \"${__package}\" &&\n               apt-cache show \"${__package}\" | grep -q \"Package: ${__package}\"\n            then\n              _apt_packages+=(\"${__package}\")\n            fi\n          done\n\n          apt-get install -y \"${_apt_packages[@]:-}\"\n\n          # force install of bat\n          apt-get install -y bat -o Dpkg::Options::=\"--force-overwrite\"\n\n          if ! _command_exists \"rg\"\n          then\n            _deb_packages+=(\"ripgrep 12.1.1 BurntSushi/ripgrep\")\n          fi\n\n          if ! _command_exists \"bat\" || ! _command_exists \"batcat\"\n          then\n            _deb_packages+=(\"bat 0.22.1 sharkdp/bat\")\n          fi\n\n          local __package=\n          for   __package in \"${_deb_packages[@]}\"\n          do\n            local _arguments=()\n            IFS=' ' read -ra _arguments <<< \"${__package:-}\"\n\n            _env_install_deb \"${_arguments[@]:-}\"\n          done\n        elif [[ -x \"$(command -v dnf)\"    ]]\n        then\n          : # TODO: dnf install\n          _completions install --download\n        elif [[ -x \"$(command -v zypper)\" ]]\n        then\n          : # TODO: zypper install\n          _completions install --download\n        else\n          _completions install --download\n        fi\n      fi\n\n      # install assets\n\n      case \"${2:-}\" in\n        --ace)\n          if [[ ! -e \"${NB_DIR}/.assets/ace-builds\" ]]\n          then\n            if [[ ! -e \"${NB_DIR}/.assets\"          ]]\n            then\n              mkdir \"${NB_DIR}/.assets\"\n            fi\n\n            cd \"${NB_DIR}/.assets\" ||\n              _exit_1 printf \"Unable to \\`cd\\` to %s\\\\n\" \"${NB_DIR}/.assets\"\n\n            git clone https://github.com/ajaxorg/ace-builds.git || return 0\n          else\n            cd \"${NB_DIR}/.assets/ace-builds\" ||\n              _exit_1 printf \"Unable to \\`cd\\` to %s\\\\n\" \"${NB_DIR}/.assets/ace-builds\"\n\n            git -C \"${NB_DIR}/.assets/ace-builds\" pull origin   || return 0\n\n            local _git_status_output=\n            _git_status_output=\"$(git -C \"${NB_DIR}/.assets/ace-builds\" status --porcelain)\"\n\n            if [[ -n \"${_git_status_output:-}\"      ]] &&\n               ! grep -qv '^ D demo/' <<< \"$_git_status_output\"\n            then # reset repository if there are stray deleted demo files.\n              git -C \"${NB_DIR}/.assets/ace-builds\" reset --hard HEAD\n            fi\n          fi\n          ;;\n        --mathjax)\n          if [[ ! -e \"${NB_DIR}/.assets/MathJax\"    ]]\n          then\n            if [[ ! -e \"${NB_DIR}/.assets\"          ]]\n            then\n              mkdir \"${NB_DIR}/.assets\"\n            fi\n\n            cd \"${NB_DIR}/.assets\" ||\n              _exit_1 printf \"Unable to \\`cd\\` to %s\\\\n\" \"${NB_DIR}/.assets\"\n\n            git clone https://github.com/mathjax/MathJax.git  || return 0\n          else\n            cd \"${NB_DIR}/.assets/MathJax\" ||\n              _exit_1 printf \"Unable to \\`cd\\` to %s\\\\n\" \"${NB_DIR}/.assets/MathJax\"\n\n            git -C \"${NB_DIR}/.assets/MathJax\" pull origin    || return 0\n          fi\n          ;;\n      esac\n      ;;\n    uninstall)\n      _completions uninstall\n      ;;\n    *)\n      printf \"_ME=%s\\\\n\"                                  \"${_ME:-}\"\n      printf \"_MY_PATH=%s\\\\n\"                             \"${_MY_PATH:-}\"\n      printf \"EDITOR=%s\\\\n\"                               \"${EDITOR:-}\"\n      printf \"NB_ACE_ENABLED=%s\\\\n\"                       \"${NB_ACE_ENABLED:-}\"\n      printf \"NB_ACE_MD_GUTTER=%s\\\\n\"                     \"${NB_ACE_MD_GUTTER:-}\"\n      printf \"NB_ACE_RELATIVE_LINE_NUMBERS=%s\\\\n\"         \"${NB_ACE_RELATIVE_LINE_NUMBERS:-}\"\n      printf \"NB_ACE_SOFT_TABS=%s\\\\n\"                     \"${NB_ACE_SOFT_TABS:-}\"\n      printf \"NB_ACE_KEYBOARD=%s\\\\n\"                      \"${NB_ACE_KEYBOARD:-}\"\n      printf \"NB_AUDIO_TOOL=%s\\\\n\"                        \"${NB_AUDIO_TOOL:-}\"\n      printf \"NB_AUTO_SYNC=%s\\\\n\"                         \"${NB_AUTO_SYNC:-}\"\n      printf \"NB_AUTO_SYNC_SECONDS=%s\\\\n\"                 \"${NB_AUTO_SYNC_SECONDS:-}\"\n      printf \"NB_BOOKMARK_CONTENT_CLEANUP_TOOL=%s\\\\n\"     \"${NB_BOOKMARK_CONTENT_CLEANUP_TOOL:-}\"\n      printf \"NB_BOOKMARK_CONTENT_CONVERSION_TOOL=%s\\\\n\"  \"${NB_BOOKMARK_CONTENT_CONVERSION_TOOL:-}\"\n      printf \"NB_BROWSE_MARKDOWN_READER=%s\\\\n\"            \"${NB_BROWSE_MARKDOWN_READER:-}\"\n      printf \"NB_BROWSE_SERVER_TOOL=%s\\\\n\"                \"${NB_BROWSE_SERVER_TOOL:-}\"\n      printf \"NB_BROWSE_SUPPORT_LINKS=%s\\\\n\"              \"${NB_BROWSE_SUPPORT_LINKS:-}\"\n      printf \"NB_BROWSER=%s\\\\n\"                           \"${NB_BROWSER:-}\"\n      printf \"NB_COLOR_PRIMARY=%s\\\\n\"                     \"${NB_COLOR_PRIMARY:-}\"\n      printf \"NB_COLOR_SECONDARY=%s\\\\n\"                   \"${NB_COLOR_SECONDARY:-}\"\n      printf \"NB_COLOR_THEME=%s\\\\n\"                       \"${NB_COLOR_THEME:-}\"\n      printf \"NB_CUSTOM_CSS=%s\\\\n\"                        \"${NB_CUSTOM_CSS:-}\"\n      printf \"NB_CUSTOM_CSS_URL=%s\\\\n\"                    \"${NB_CUSTOM_CSS_URL:-}\"\n      printf \"NB_CUSTOM_JAVASCRIPT=%s\\\\n\"                 \"${NB_CUSTOM_JAVASCRIPT:-}\"\n      printf \"NB_CUSTOM_JAVASCRIPT_URL=%s\\\\n\"             \"${NB_CUSTOM_JAVASCRIPT_URL:-}\"\n      printf \"NB_DATA_TOOL=%s\\\\n\"                         \"${NB_DATA_TOOL:-}\"\n      printf \"NB_DEFAULT_EXTENSION=%s\\\\n\"                 \"${NB_DEFAULT_EXTENSION:-}\"\n      printf \"NB_DEFAULT_TEMPLATE=%s\\\\n\"                  \"${NB_DEFAULT_TEMPLATE:-}\"\n      printf \"NB_DIR=%s\\\\n\"                               \"${NB_DIR:-}\"\n      printf \"NB_DIRECTORY_TOOL=%s\\\\n\"                    \"${NB_DIRECTORY_TOOL:-}\"\n      printf \"NB_DOWNLOAD_TOOL=%s\\\\n\"                     \"${NB_DOWNLOAD_TOOL:-}\"\n      printf \"NB_EDITOR=%s\\\\n\"                            \"${NB_EDITOR:-}\"\n      printf \"NB_ENCRYPTION_TOOL=%s\\\\n\"                   \"${NB_ENCRYPTION_TOOL:-}\"\n      printf \"NB_FOLDERS_FIRST=%s\\\\n\"                     \"${NB_FOLDERS_FIRST:-}\"\n      printf \"NB_FOOTER=%s\\\\n\"                            \"${NB_FOOTER:-}\"\n      printf \"NB_GUI_BROWSER=%s\\\\n\"                       \"${NB_GUI_BROWSER:-}\"\n      printf \"NB_HEADER=%s\\\\n\"                            \"${NB_HEADER:-}\"\n      printf \"NB_IMAGE_TOOL=%s\\\\n\"                        \"${NB_IMAGE_TOOL:-}\"\n      printf \"NB_INDICATOR_AUDIO=%s\\\\n\"                   \"${NB_INDICATOR_AUDIO:-}\"\n      printf \"NB_INDICATOR_BOOKMARK=%s\\\\n\"                \"${NB_INDICATOR_BOOKMARK:-}\"\n      printf \"NB_INDICATOR_DOCUMENT=%s\\\\n\"                \"${NB_INDICATOR_DOCUMENT:-}\"\n      printf \"NB_INDICATOR_EBOOK=%s\\\\n\"                   \"${NB_INDICATOR_EBOOK:-}\"\n      printf \"NB_INDICATOR_ENCRYPTED=%s\\\\n\"               \"${NB_INDICATOR_ENCRYPTED:-}\"\n      printf \"NB_INDICATOR_FOLDER=%s\\\\n\"                  \"${NB_INDICATOR_FOLDER:-}\"\n      printf \"NB_INDICATOR_IMAGE=%s\\\\n\"                   \"${NB_INDICATOR_IMAGE:-}\"\n      printf \"NB_INDICATOR_PINNED=%s\\\\n\"                  \"${NB_INDICATOR_PINNED:-}\"\n      printf \"NB_INDICATOR_TODO=%s\\\\n\"                    \"${NB_INDICATOR_TODO:-}\"\n      printf \"NB_INDICATOR_TODO_DONE=%s\\\\n\"               \"${NB_INDICATOR_TODO_DONE:-}\"\n      printf \"NB_INDICATOR_VIDEO=%s\\\\n\"                   \"${NB_INDICATOR_VIDEO:-}\"\n      printf \"NB_LIMIT=%s\\\\n\"                             \"${NB_LIMIT:-}\"\n      printf \"NB_MATHJAX_ENABLED=%s\\\\n\"                   \"${NB_MATHJAX_ENABLED:-}\"\n      printf \"NB_MARKDOWN_TOOL=%s\\\\n\"                     \"${NB_MARKDOWN_TOOL:-}\"\n      printf \"NB_NOTEBOOK_PATH=%s\\\\n\"                     \"${NB_NOTEBOOK_PATH:-}\"\n      printf \"NB_PINNED_PATTERN=%s\\\\n\"                    \"${NB_PINNED_PATTERN:-}\"\n      printf \"NB_SERVER_HOST=%s\\\\n\"                       \"${NB_SERVER_HOST:-}\"\n      printf \"NB_SERVER_PORT=%s\\\\n\"                       \"${NB_SERVER_PORT:-}\"\n      printf \"NB_USER_AGENT=%s\\\\n\"                        \"${NB_USER_AGENT:-}\"\n      printf \"NB_SYNTAX_THEME=%s\\\\n\"                      \"${NB_SYNTAX_THEME:-}\"\n      printf \"NBRC_PATH=%s\\\\n\"                            \"${NBRC_PATH:-}\"\n      printf \"PAGER=%s\\\\n\"                                \"${PAGER:-}\"\n      printf \"_LOCAL_NOTEBOOK_PATH=%s\\\\n\"                 \"${_LOCAL_NOTEBOOK_PATH:-}\"\n      printf \"_GLOBAL_NOTEBOOK_PATH=%s\\\\n\"                \"${_GLOBAL_NOTEBOOK_PATH:-}\"\n      printf \"_CURRENT_WORKING_DIR=%s\\\\n\"                 \"${_CURRENT_WORKING_DIR:-}\"\n\n      if _contains \"${1:-}\" \"--long\" \"-l\"\n      then\n        printf \"\\\\n\"\n        printf \"ack:        %s\\\\n\" \"$(command -v ack)\"\n        printf \"ag:         %s\\\\n\" \"$(command -v ag)\"\n        printf \"bat:        %s\\\\n\" \"$(command -v bat)\"\n        printf \"code:       %s\\\\n\" \"$(command -v code)\"\n        printf \"curl:       %s\\\\n\" \"$(command -v curl)\"\n        printf \"emacs:      %s\\\\n\" \"$(command -v emacs)\"\n        printf \"git:        %s\\\\n\" \"$(command -v git)\"\n        printf \"gvim:       %s\\\\n\" \"$(command -v gvim)\"\n        printf \"gpg:        %s\\\\n\" \"$(command -v gpg)\"\n        printf \"highlight:  %s\\\\n\" \"$(command -v highlight)\"\n        printf \"less:       %s\\\\n\" \"$(command -v less)\"\n        printf \"lynx:       %s\\\\n\" \"$(command -v lynx)\"\n        printf \"macdown:    %s\\\\n\" \"$(command -v macdown)\"\n        printf \"mate:       %s\\\\n\" \"$(command -v mate)\"\n        printf \"mvim:       %s\\\\n\" \"$(command -v mvim)\"\n        printf \"nano:       %s\\\\n\" \"$(command -v nano)\"\n        printf \"nc:         %s\\\\n\" \"$(command -v ncat)\"\n        printf \"ncat:       %s\\\\n\" \"$(command -v nc)\"\n        printf \"nvim:       %s\\\\n\" \"$(command -v nvim)\"\n        printf \"openssl:    %s\\\\n\" \"$(command -v openssl)\"\n        printf \"pandoc:     %s\\\\n\" \"$(command -v pandoc)\"\n        printf \"pygments:   %s\\\\n\" \"$(command -v pygmentize)\"\n        printf \"readable:   %s\\\\n\" \"$(command -v readable)\"\n        printf \"rg:         %s\\\\n\" \"$(command -v rg)\"\n        printf \"subl:       %s\\\\n\" \"$(command -v subl)\"\n        printf \"tig:        %s\\\\n\" \"$(command -v tig)\"\n        printf \"w3m:        %s\\\\n\" \"$(command -v w3m)\"\n        printf \"wget:       %s\\\\n\" \"$(command -v wget)\"\n        printf \"vim:        %s\\\\n\" \"$(command -v vim)\"\n\n        printf \"\\\\n\"\n        printf \"bash --version\\\\n\"\n        printf -- \"--------------\\\\n\"\n        printf \"%s\\\\n\" \"$(bash --version | head -1)\"\n\n        printf \"\\\\n\"\n        printf \"git --version\\\\n\"\n        printf -- \"-------------\\\\n\"\n        printf \"%s\\\\n\" \"$(git --version | head -1)\"\n\n        printf \"\\\\n\"\n        printf \"uname -a\\\\n\"\n        printf -- \"--------\\\\n\"\n        printf \"%s\\\\n\" \"$(uname -a)\"\n\n        printf \"\\\\n\"\n        printf \"locale\\\\n\"\n        printf -- \"------\\\\n\"\n        printf \"%s\\\\n\" \"$(locale)\"\n\n        if _command_exists \"google-chrome\"\n        then\n          printf \"\\\\n\"\n          printf \"google-chrome --version\\\\n\"\n          printf -- \"-----------------------\\\\n\"\n          printf \"%s\\\\n\"  \"$(google-chrome --version 2>&1)\"\n        fi\n\n        if _command_exists \"chromium\"\n        then\n          printf \"\\\\n\"\n          printf \"chromium --version\\\\n\"\n          printf -- \"------------------\\\\n\"\n          printf \"%s\\\\n\"  \"$(chromium --version 2>&1)\"\n        fi\n\n        if _command_exists \"chromium-browser\"\n        then\n          printf \"\\\\n\"\n          printf \"chromium-browser --version\\\\n\"\n          printf -- \"--------------------------\\\\n\"\n          printf \"%s\\\\n\"  \"$(chromium-browser --version 2>&1)\"\n        fi\n\n        if [[ -x \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\" ]]\n        then\n          printf \"\\\\n\"\n          printf \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome --version\\\\n\"\n          printf -- \"----------------------------------------------------------------------\\\\n\"\n          printf \"%s\\\\n\"  \"$('/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' --version 2>&1)\"\n        fi\n\n        if [[ -x \"/Applications/Chromium.app/Contents/MacOS/Chromium\"           ]]\n        then\n          printf \"\\\\n\"\n          printf \"/Applications/Chromium.app/Contents/MacOS/Chromium --version\\\\n\"\n          printf -- \"------------------------------------------------------------\\\\n\"\n          printf \"%s\\\\n\"  \"$('/Applications/Chromium.app/Contents/MacOS/Chromium' --version 2>&1)\"\n        fi\n\n        if _command_exists \"awk\"\n        then\n          printf \"\\\\n\"\n          printf \"awk --version\\\\n\"\n          printf -- \"-------------\\\\n\"\n          printf \"%s\\\\n\" \"$(awk --version 2>&1)\"\n        fi\n\n        if _command_exists \"grep\"\n        then\n          printf \"\\\\n\"\n          printf \"grep --version\\\\n\"\n          printf -- \"--------------\\\\n\"\n          printf \"%s\\\\n\" \"$(grep --version 2>&1)\"\n        fi\n\n        if _command_exists \"sed\"\n        then\n          printf \"\\\\n\"\n          printf \"sed --version\\\\n\"\n          printf -- \"-------------\\\\n\"\n          printf \"%s\\\\n\" \"$(sed --version 2>&1)\"\n        fi\n\n        if _command_exists \"nc\"\n        then\n          printf \"\\\\n\"\n          printf \"nc --version\\\\n\"\n          printf -- \"------------\\\\n\"\n          printf \"%s\\\\n\"  \"$(nc --version 2>&1)\"\n        fi\n\n        if _command_exists \"ncat\"\n        then\n          printf \"\\\\n\"\n          printf \"ncat --version\\\\n\"\n          printf -- \"--------------\\\\n\"\n          printf \"%s\\\\n\"  \"$(ncat --version 2>&1)\"\n        fi\n\n        if _command_exists \"pandoc\"\n        then\n          printf \"\\\\n\"\n          printf \"pandoc --version\\\\n\"\n          printf -- \"----------------\\\\n\"\n          printf \"%s\\\\n\" \"$(pandoc --version 2>&1)\"\n        fi\n\n        if _command_exists \"socat\"\n        then\n          printf \"\\\\n\"\n          printf \"socat -V\\\\n\"\n          printf -- \"--------\\\\n\"\n          printf \"%s\\\\n\" \"$(socat -V 2>&1)\"\n        fi\n\n        if _command_exists \"w3m\"\n        then\n          printf \"\\\\n\"\n          printf \"w3m -version\\\\n\"\n          printf -- \"------------\\\\n\"\n          printf \"%s\\\\n\" \"$(w3m -version 2>&1)\"\n        fi\n      fi\n      ;;\n  esac\n}\n\n# export ############################################################### export\n\n_describe_export() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} export ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <path> [-f | --force] [<pandoc options>...]\n  ${_ME} export notebook <name> [<path>]\n  ${_ME} export pandoc ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            [<pandoc options>...]\n\n$(_color_primary \"Options\"):\n  -f, --force   Skip the confirmation prompt when overwriting an existing file.\n\n$(_color_primary \"Subcommands\"):\n  (default)     Export a file to <path>. If <path> has a different extension\n                than the source note, convert the note using \\`pandoc\\`.\n  notebook      Export the notebook <name> to the current directory or <path>.\n                Alias for \\`${_ME} notebooks export\\`.\n  pandoc        Export the file to standard output or a file using \\`pandoc\\`.\n                \\`export pandoc\\` prints to standard output by default.\n\n$(_color_primary \"Description\"):\n  Export a file or notebook.\n\n  If Pandoc [1] is available, convert the note from its current format\n  to the format of the output file as indicated by the file extension\n  in <path>. Any additional arguments are passed directly to Pandoc.\n  See the Pandoc help information for available options.\n\n    1. https://pandoc.org/\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#%EF%B8%8F-import--export\n\n$(_color_primary \"See Also\"):\n  ${_ME} help browse\n  ${_ME} help import\n\n$(_color_primary \"Examples\"):\n  # Export an Emacs Org mode note\n  ${_ME} export example.org /path/to/example.org\n\n  # Export a Markdown note to HTML and print to standard output\n  ${_ME} export pandoc example.md --from=markdown_strict --to=html\n\n  # Export a Markdown note to a .docx Microsoft Office Word document\n  ${_ME} export example.md /path/to/example.docx\n\n  # Export note 12 in the \"sample\" notebook to HTML\n  ${_ME} export sample:12 /path/to/example.html\nHEREDOC\n}\n_export() {\n  local _args=()\n  local _force=0\n  local _notebook_export=0\n  local _pandoc_only=0\n  local _selector=\n  local _target_path=\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      -f|--force|--skip*|-y|--yes)\n        _force=1\n        ;;\n      notebook*)\n        _notebook_export=1\n        ;;\n      pandoc)\n        _pandoc_only=1\n        ;;\n      *)\n        if [[ -z \"${_selector:-}\"   ]]\n        then\n          _selector=\"${__arg}\"\n        elif ! ((_pandoc_only)) &&  [[ -z \"${_target_path:-}\" ]]\n        then\n          _target_path=\"${__arg}\"\n        else\n          _args+=(\"${__arg}\")\n        fi\n        ;;\n    esac\n  done\n\n  if [[ -z \"${_selector:-}\" ]]\n  then\n    _exit_1 _help \"export\"\n  fi\n\n  if ((_notebook_export))\n  then\n    _notebooks export \"${_selector:-}\" \"${_target_path:-}\"\n\n    return 0\n  fi\n\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  local _relative_path=\n  _relative_path=\"$(_show \"${_selector}\" --relative-path)\"\n\n  local _basename=\"${_relative_path##*\\/}\"\n\n  if [[ -z \"${_relative_path:-}\"                      ]] ||\n     [[ ! -e \"${_notebook_path}/${_relative_path:-}\"  ]]\n  then\n    _exit_1 printf \"Not found: %s\\\\n\" \"$(_color_primary \"${_selector}\")\"\n  fi\n\n  if ((_pandoc_only))\n  then\n    if _command_exists \"pandoc\"\n    then\n      if [[ -n \"${_args[*]:-}\"    ]]\n      then\n        _pandoc \"${_notebook_path}/${_relative_path}\" \"${_args[@]:-}\"\n      else\n        _pandoc \"${_notebook_path}/${_relative_path}\"\n      fi\n    else\n      _exit_1 printf \"Pandoc required. https://pandoc.org/\\\\n\"\n    fi\n  else\n    if [[ -z \"${_target_path:-}\"  ]]\n    then\n      _exit_1 _help \"export\"\n    fi\n\n    if [[ -d \"${_target_path:-}\"  ]]\n    then\n      _target_path=\"${_target_path%/}/${_basename}\"\n    fi\n\n    if [[ -e \"${_target_path:-}\"  ]]\n    then\n      if ! ((_force))\n      then\n        printf \"File exists at %s\\\\n\" \"$(_color_primary \"${_target_path}\")\"\n\n        while true\n        do\n          local __yn=\n          IFS='' read -r -e -d $'\\n' -p \\\n\"$(_color_primary \"Overwrite existing file?\") $(_color_brackets \"y/N\") \" __yn\n\n          case \"${__yn}\" in\n            [Yy]*)\n              break\n              ;;\n            *)\n              printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n              exit 0\n              ;;\n          esac\n        done\n      fi\n    fi\n\n    local _source_file_type=\"${_basename##*.}\"\n    local _target_file_type=\"${_target_path##*.}\"\n\n    if _command_exists \"pandoc\"   &&\n       [[ \"${_source_file_type}\"  != \"${_target_file_type}\" ]]\n    then\n      if [[ -n \"${_args[*]:-}\"    ]]\n      then\n        _pandoc                                   \\\n          \"${_notebook_path}/${_relative_path}\"   \\\n          -o \"${_target_path}\"                    \\\n          --standalone                            \\\n          \"${_args[@]:-}\"\n      else\n        _pandoc                                   \\\n          \"${_notebook_path}/${_relative_path}\"   \\\n          -o \"${_target_path}\"                    \\\n          --standalone\n      fi\n    else\n      cp \"${_notebook_path}/${_relative_path}\" \"${_target_path}\"\n    fi &&\n      printf \"Exported: %s\\\\n\"  \"$(_show \"${_relative_path}\" --info-line)\"\n      printf \"To:        %s\\\\n\" \"$(_color_primary \"${_target_path}\")\"\n  fi\n}\n\n# history ############################################################# history\n\n_describe_history() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} history [<notebook>:][<folder-path>/][<id> | <filename> | <title>]\n\n$(_color_primary \"Description\"):\n  Display notebook history using \\`tig\\` [1] (if available) or \\`git log\\`.\n  When a note is specified, the history for that note is displayed.\n\n    1. https://github.com/jonas/tig\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-revision-history\n  ${_README_URL}#-git-sync\n\n$(_color_primary \"See Also\"):\n  ${_ME} help git\n  ${_ME} help remote\n  ${_ME} help status\n  ${_ME} help sync\n\n$(_color_primary \"Examples\"):\n  ${_ME} history\n  ${_ME} history example.md\n  ${_ME} 3 history\n  ${_ME} example:history\n  ${_ME} history example:\n  ${_ME} example:history 12\n  ${_ME} history example:12\n  ${_ME} example:12 history\nHEREDOC\n}\n_history() {\n  local _basename=\n  local _force_git_log=0\n  local _notebook_path=\n  local _selector=\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      --*log*|--*git*)\n        _force_git_log=1\n        ;;\n      *)\n        if [[ -z \"${_selector:-}\" ]]\n        then\n          _selector=\"${__arg}\"\n        fi\n        ;;\n    esac\n  done\n\n  if [[ -n \"${_selector:-}\"       ]]\n  then\n    if [[  \"${_selector}\" =~ :$   ]] ||\n       ! _relative_path=\"$(_show \"${_selector}\" --relative-path 2>/dev/null)\"\n    then\n      if ! _notebook_path=\"$(_notebooks show \"${_selector}\" --path 2>/dev/null)\"\n      then\n        _exit_1 printf \"Not found: %s\\\\n\" \"$(_color_primary \"${_selector:-}\")\"\n      fi\n    fi\n  fi\n\n  if [[ -z \"${_notebook_path:-}\"  ]]\n  then\n    _notebook_path=\"$(_notebooks current --path)\"\n  fi\n\n  cd \"${_notebook_path}\" || _exit_1 printf \"_history() \\`cd\\` failed.\\\\n\"\n\n  local _log_command=\"git log\"\n\n  if _command_exists \"tig\" && ! ((_force_git_log))\n  then\n    _log_command=\"tig --all\"\n  fi\n\n  if [[ -n \"${_relative_path:-}\"  ]] && [[ -e \"${_notebook_path}/${_relative_path}\" ]]\n  then\n    eval \"${_log_command} -- \\\"${_relative_path}\\\"\"\n  else\n    eval \"${_log_command}\"\n  fi\n}\n\n# import ############################################################### import\n\n_describe_import() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} import [bookmarks | copy | download | move] (<path>... | <url>)\n            [--convert] [<notebook>:][<folder-path>/][<filename>]\n  ${_ME} import notebook <path> [<name>]\n\n$(_color_primary \"Options\"):\n  --convert  Convert HTML content to Markdown.\n\n$(_color_primary \"Subcommands\"):\n  (default)  Copy or download the file(s) at <path> or <url>.\n  bookmarks  Import bookmarks from a Chrome, Firefox, or Edge export file.\n  copy       Copy the file(s) at <path> into the current notebook.\n  download   Download the file at <url> into the current notebook.\n  move       Move the file(s) at <path> into the current notebook.\n  notebook   Import the local notebook at <path> to make it global.\n\n$(_color_primary \"Description\"):\n  Copy, move, or download files into \\`nb\\`, import bookmarks, or import\n  a local notebook to make it global.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#%EF%B8%8F-import--export\n\n$(_color_primary \"See Also\"):\n  ${_ME} help add\n  ${_ME} help export\n\n$(_color_primary \"Examples\"):\n  ${_ME} import ~/Pictures/example.png\n  ${_ME} import ~/Documents/example.docx\n  ${_ME} import https://example.com/example.pdf\n  ${_ME} example:import https://example.com/example.jpg\n  ${_ME} import ./*\n  ${_ME} import ./*.md\n  ${_ME} import ~/Pictures/example.png example-notebook:\n  ${_ME} import ~/Documents/example.docx example-folder/\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} i\nHEREDOC\n}\n_import() {\n  # _import_create_bookmark()\n  #\n  # Usage:\n  #   _import_create_bookmark <target-selector> <line>\n  _import_create_bookmark() {\n    local _line=\"${2:?}\"\n    local _target_selector=\"${1:-}\"\n\n    local _bookmark_options=(--skip-folder-prompt)\n\n    local _add_timestamp=\n    _add_timestamp=\"$(\n      LC_ALL=C sed -E -e 's/.*ADD_DATE=\\\"([[:digit:]]+)\\\".*/\\1/g' <<< \"${_line}\"\n    )\"\n\n    local _target_filename=\n    _target_filename=\"$(\n      if hash \"gdate\" 2>/dev/null\n      then # GNU prefixed\n        gdate -u -d \"@${_add_timestamp}\"  \"+%Y%m%d%H%M%S\"\n      elif date --version >/dev/null 2>&1\n      then # GNU\n        date  -u -d \"@${_add_timestamp}\"  \"+%Y%m%d%H%M%S\"\n      else # BSD\n        date  -u -r \"${_add_timestamp}\"   \"+%Y%m%d%H%M%S\"\n      fi\n    )\"\n\n    if [[ -n \"${_target_filename:-}\"  ]]\n    then\n      _bookmark_options+=(--filename \"${_target_filename}\")\n    fi\n\n    local _tag_list=\n    _tag_list=\"$(\n      grep -q 'TAGS=\\\"'                                       <<< \"${_line}\" &&\n        LC_ALL=C sed -E -e 's/.*TAGS=\\\"([^\\\"]+)\\\".*/\\1/g'     <<< \"${_line}\" || :\n    )\"\n\n    if [[ -n \"${_tag_list:-}\"         ]]\n    then\n      _bookmark_options+=(--tags \"${_tag_list}\")\n    fi\n\n    local _title=\n    _title=\"$(\n      LC_ALL=C sed -E -e 's/.*>(.*)<\\/A>/\\1/g'                <<< \"${_line}\"\n    )\"\n\n    if [[ -n \"${_title:-}\"            ]]\n    then\n      _bookmark_options+=(--title \"${_title}\")\n    fi\n\n    local _url=\n    _url=\"$(\n      LC_ALL=C sed -E -e 's/.*HREF=\\\"(.*)\\\" ADD_DATE.*/\\1/g'  <<< \"${_line}\"\n    )\"\n\n    _notebooks select \"${_target_selector%%:*}\"\n\n    _bookmark                         \\\n      \"${_target_selector}\"           \\\n      \"${_url}\"                       \\\n      \"${_bookmark_options[@]}\"\n  }\n\n  # _import_init_target_relative_path()\n  #\n  # Usage:\n  #   _import_init_target_relative_path <notebook-path> <source-basename> <selector-path>\n  _import_init_target_relative_path() {\n    local _notebook_path=\"${1:?}\"\n    local _source_basename=\"${2:?}\"\n    local _selector_path=\"${3:-}\"\n    local _target_folder_relative_path=\n    local _target_relative_path=\n\n    if [[ -n \"${_selector_path:-}\"          ]]\n    then\n      if [[ \"${_selector_path}\" =~ /$                 ]] ||\n         [[ -d \"${_notebook_path}/${_selector_path}\"  ]]\n      then\n        if [[ ! \"${_selector_path}\" =~ /$   ]]\n        then\n          _selector_path=\"${_selector_path}/\"\n        fi\n\n        _target_folder_relative_path=\"$(\n          _selector_resolve_folders \"${_selector_path}\" --build || :\n        )\"\n\n        _target_relative_path=\"${_target_folder_relative_path}/${_source_basename}\"\n      elif [[ \"${_selector_path}\" =~ /      ]]\n      then\n        _target_folder_relative_path=\"$(\n          _selector_resolve_folders \"${_selector_path}\" --build || :\n        )\"\n\n        _target_relative_path=\"${_target_folder_relative_path}/${_selector_path##*\\/}\"\n      else\n        _target_relative_path=\"${_selector_path}\"\n      fi\n    else\n      _target_relative_path=\"${_source_basename}\"\n    fi\n\n    if [[ \"${_target_relative_path:-}\" =~ / ]]\n    then\n      _target_folder_relative_path=\"${_target_relative_path%\\/*}\"\n\n      if [[ ! -e \"${_notebook_path}/${_target_folder_relative_path}\" ]]\n      then\n        mkdir -p \"${_notebook_path}/${_target_folder_relative_path}\"\n      fi\n    fi\n\n    printf \"%s\\\\n\" \"$(\n      _notebooks show \"${_notebook_path}\" --filename \"${_target_relative_path}\"\n    )\"\n  }\n\n  # _import_validate_path()\n  #\n  # Usage:\n  #   _import_validate_path <path>\n  _import_validate_path() {\n    if [[     -z \"${1:-}\" ]]\n    then\n      _exit_1 _help \"import\"\n    elif [[ ! -e \"${1:-}\" ]]\n    then\n      _exit_1 printf \"File not found: %s\\\\n\" \"$(_color_primary \"${1:-}\")\"\n    fi\n  }\n\n  local _convert=0\n  local _paths=()\n  local _selector=\n  local _source_and_target_identifiers=()\n  local _subcommand=\n  local _target_notebook_name=\n  local _url=\n\n  local _local_notebook_path=\n  _local_notebook_path=\"$(_notebooks --local --path || :)\"\n\n  if _piped_input\n  then\n    IFS=$' \\n' _paths+=($(cat))\n  fi\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      bookmark|bookmarks)\n        _subcommand=\"bookmarks\"\n        ;;\n      copy|download|move)\n        _subcommand=\"${__arg}\"\n        ;;\n      notebook*)\n        _subcommand=\"notebook\"\n        ;;\n      --convert)\n        _convert=1\n        ;;\n      *)\n        if _string_is_url \"${__arg:-}\"\n        then\n          _url=\"${__arg:-}\"\n          _subcommand=\"download\"\n        else\n          _source_and_target_identifiers+=(\"${__arg:-}\")\n        fi\n        ;;\n    esac\n  done\n\n  [[ -n \"${_subcommand:-}\" ]] || _subcommand=\"copy\"\n\n  local __source_and_target_identifier=\n  for   __source_and_target_identifier in \"${_source_and_target_identifiers[@]:-}\"\n  do\n    if [[    \"${_subcommand:-}\" == \"download\" ]] &&\n       [[ -n \"${_url:-}\"                      ]]\n    then\n      _selector=\"${__source_and_target_identifier:-}\"\n    elif [[ \"${_subcommand}\" == bookmarks                     ]] &&\n         [[ ! \"${__source_and_target_identifier}\" =~ (^/|^~/) ]] &&\n         [[ \"${__source_and_target_identifier}\"   =~ (:$|/$)  ]]\n    then\n      _selector=\"${__source_and_target_identifier}\"\n    elif [[ \"${_subcommand}\" =~ (^copy$|^move$)               ]] &&\n         [[ ! \"${__source_and_target_identifier}\" =~ (^/|^~/) ]] &&\n         {\n           [[ -n \"${_local_notebook_path}\"                    ]] ||\n           [[ ! -e \"${PWD}/${__source_and_target_identifier}\" ]]\n         }\n    then\n      _selector=\"${__source_and_target_identifier}\"\n    elif [[ \"${_subcommand}\" == \"notebook\"    ]] &&\n         [[ -n \"${_paths[*]:-}\"               ]]\n    then\n      _target_notebook_name=\"${__source_and_target_identifier:-}\"\n    else\n      if [[ \"${__source_and_target_identifier:-}\" =~ ^~/ ]]\n      then\n        _paths+=\"$(\n          printf \"%s\\\\n\" \"${__source_and_target_identifier:-}\" | sed \"s,^~,${HOME},g\"\n        )\"\n      else\n        _paths+=(\"${__source_and_target_identifier:-}\")\n      fi\n    fi\n  done\n\n  local _notebook_name=\n  local _notebook_path=\n  local _selector_path=\n\n  if [[ \"${_selector:-}\" =~ :     ]]\n  then\n    _notebook_name=\"$(\n      _notebooks show \"${_selector%%:*}\" --name 2>/dev/null \\\n        || _notebooks current --name\n    )\"\n    _notebook_path=\"$(\n      _notebooks show \"${_selector%%:*}\" --path 2>/dev/null \\\n        || _notebooks current --path\n      )\"\n    _selector_path=\"${_selector#*:}\"\n  else\n    _notebook_name=\"$(_notebooks current --name)\"\n    _notebook_path=\"$(_notebooks current --path)\"\n    _selector_path=\"${_selector:-}\"\n  fi\n\n  local _source_basename=\n  local _target_basename=\n  local _target_folder_relative_path=\n  local _target_relative_path=\n\n  case \"${_subcommand}\" in\n    bookmarks)\n      local _target_folder_relative_path=\n      _target_folder_relative_path=\"$(\n        _selector_resolve_folders \"${_selector_path}\" --build || :\n      )\"\n\n      if [[ -n  \"${_target_folder_relative_path:-}\"     ]] &&\n         [[ !   \"${_target_folder_relative_path}\" =~ /$ ]]\n      then\n        _target_folder_relative_path=\"${_target_folder_relative_path}/\"\n      fi\n\n      local __path=\n      for   __path in \"${_paths[@]:-}\"\n      do\n        _import_validate_path \"${__path:-}\"\n\n        local               __line=\n        while IFS= read -r  __line || [[ -n \"${__line:-}\"           ]]\n        do\n          if [[ \"${__line}\" =~ ^[[:space:]]*\\<DT\\>                  ]]\n          then\n            if [[ \"${__line}\" =~ PERSONAL_TOOLBAR_FOLDER=\\\"true\\\"   ]]\n            then\n              _target_folder_relative_path=\"${_target_folder_relative_path}toolbar/\"\n            elif [[ \"${__line}\" =~ \\<DT\\>\\<A.*\\>.*\\</A\\>            ]]\n            then\n              _import_create_bookmark                               \\\n                \"${_notebook_name}:${_target_folder_relative_path}\" \\\n                \"${__line}\" || :\n            elif [[ \"${__line}\" =~ \\<DT\\>\\<H3.*\\>.*\\</H3\\>          ]]\n            then\n              local _parent_folder_name=\n              _parent_folder_name=\"$(\n                LC_ALL=C sed -E -e 's/.*>(.*)<\\/H3>.*/\\1/g' <<< \"${__line}\"\n              )\"\n\n              _target_folder_relative_path=\"${_target_folder_relative_path}${_parent_folder_name}/\"\n            fi\n          elif [[ \"${__line}\" =~ \\</DL\\>\\<p\\>                       ]]\n          then\n            _target_folder_relative_path=\"${_target_folder_relative_path%/}\"\n\n            if [[ \"${_target_folder_relative_path:-}\" =~ \\/         ]]\n            then\n              _target_folder_relative_path=\"${_target_folder_relative_path%/*}/\"\n            else\n              _target_folder_relative_path=\n            fi\n          fi\n        done < \"${__path}\"\n      done\n      ;;\n    copy)\n      local __path=\n      for   __path in \"${_paths[@]:-}\"\n      do\n        _import_validate_path \"${__path:-}\"\n\n        _source_basename=\"$(basename -- \"${__path}\")\"\n\n        _target_relative_path=\"$(\n          _import_init_target_relative_path \\\n            \"${_notebook_path}\"             \\\n            \"${_source_basename}\"           \\\n            \"${_selector_path}\"\n        )\"\n\n        if [[ \"${_target_relative_path}\" =~ / ]]\n        then\n          _target_folder_relative_path=\"${_target_relative_path%\\/*}\"\n        fi\n\n        _target_basename=\"${_target_relative_path##*\\/}\"\n\n        if [[ -d \"${__path}\"      ]]\n        then\n          cp -R \"${__path}\" \"${_notebook_path}/${_target_relative_path}\"\n        else\n          cp \"${__path}\" \"${_notebook_path}/${_target_relative_path}\"\n        fi &&\n          _index add              \\\n            \"${_target_basename}\" \\\n            \"${_notebook_path}/${_target_folder_relative_path}\" &&\n              _git checkpoint \"${_notebook_path}\" \"[${_ME}] Import: ${_target_relative_path}\"\n\n        printf \"Imported %s from %s\\\\n\"                                       \\\n          \"$(_show \"${_notebook_path}/${_target_relative_path}\" --info-line)\" \\\n          \"$(_color_primary \"${__path}\")\"\n      done\n      ;;\n    download)\n      _source_basename=\"$(basename -- \"${_url}\" | tr -d '[:space:]')\"\n\n      if [[ \"${_url}\" =~ \\/$ ]]\n      then\n        _source_basename=\"${_source_basename}.html\"\n      fi\n\n      _target_relative_path=\"$(\n        _import_init_target_relative_path \\\n          \"${_notebook_path}\"             \\\n          \"${_source_basename}\"           \\\n          \"${_selector_path}\"\n      )\"\n\n      if [[ \"${_target_relative_path}\" =~ / ]]\n      then\n        _target_folder_relative_path=\"${_target_relative_path%\\/*}\"\n      fi\n\n      _target_basename=\"${_target_relative_path##*\\/}\"\n\n      if ((_convert))\n      then\n        if ! _download_from \"${_url}\" \\\n            | _pandoc                 \\\n              --standard-input        \\\n              --from html             \\\n              --to markdown           \\\n              -o \"${_notebook_path}/${_target_relative_path}\"\n        then\n          _exit_1 printf \"Unable to download and convert: %s\\\\n\" \"${_url}\"\n        fi\n      else\n        if ! _download_from \"${_url}\" \"${_notebook_path}/${_target_relative_path}\"\n        then\n          _exit_1 printf \"Unable to download: %s\\\\n\" \"${_url}\"\n        fi\n      fi &&\n        _index add              \\\n          \"${_target_basename}\" \\\n          \"${_notebook_path}/${_target_folder_relative_path:-}\" &&\n            _git checkpoint \"${_notebook_path}\" \"\\\n[${_ME}] Import: ${_target_relative_path}\n\nSource:\n${_url}\n\"\n      printf \"Imported %s from %s\\\\n\"                     \\\n        \"$(_show \"${_target_relative_path}\" --info-line)\" \\\n        \"$(_color_primary \"${_url}\")\"\n      ;;\n    move)\n      local __path=\n      for   __path in \"${_paths[@]:-}\"\n      do\n        _import_validate_path \"${__path:-}\"\n\n        _source_basename=\"$(basename -- \"${__path}\")\"\n\n        _target_relative_path=\"$(\n          _import_init_target_relative_path   \\\n            \"${_notebook_path}\"               \\\n            \"${_source_basename}\"             \\\n            \"${_selector_path}\"\n        )\"\n\n        if [[ \"${_target_relative_path}\" =~ / ]]\n        then\n          _target_folder_relative_path=\"${_target_relative_path%\\/*}\"\n        fi\n\n        _target_basename=\"${_target_relative_path##*\\/}\"\n\n        mv \"${__path}\" \"${_notebook_path}/${_target_relative_path}\" &&\n          _index add              \\\n            \"${_target_basename}\" \\\n            \"${_notebook_path}/${_target_folder_relative_path:-}\"   &&\n              _git checkpoint \"${_notebook_path}\" \"[${_ME}] Import: ${_target_relative_path}\"\n\n        printf \"Imported %s from %s\\\\n\"                     \\\n          \"$(_show \"${_target_relative_path}\" --info-line)\" \\\n          \"$(_color_primary \"${__path}\")\"\n      done\n      ;;\n    notebook)\n      _notebooks import \"${_paths[0]:-}\" \"${_target_notebook_name:-}\"\n\n      return 0\n      ;;\n    *)\n      _exit_1 _help \"import\"\n      ;;\n  esac\n}\n_alias_subcommand \"import\" \"i\"\n\n# move ################################################################### move\n\n_describe_move() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} move ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          ([<notebook>:][<path>] | --reset | --to-bookmark | --to-note |\n          --to-title | --to-todo) [-f | --force]\n\n$(_color_primary \"Options\"):\n  -f, --force     Skip the confirmation prompt.\n  --reset         Reset the filename to the last modified timestamp.\n  --to-bookmark   Preserve the existing filename and replace the extension\n                  with \".bookmark.md\" to convert the note to a bookmark.\n  --to-note       Preserve the existing filename and replace the bookmark's\n                  \".bookmark.md\" extension with \".md\" to convert the bookmark\n                  to a Markdown note.\n  --to-title      Set the filename to the note title, lowercased with spaces\n                  and disallowed filename characters replaced with underscores.\n  --to-todo       Preserve the existing filename and replace the extension\n                  with \".todo.md\" to convert the note to a todo.\n\n$(_color_primary \"Description\"):\n  Move or rename a note. Move the note to <path> or change the file type.\n  When the file extension is omitted, the existing extension is used.\n  When only a file extension is specified, only the extension will be updated.\n\n  \\`move\\` and \\`rename\\` are aliases and can be used interchangeably.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-moving--renaming\n\n$(_color_primary \"See Also\"):\n  ${_ME} help copy\n  ${_ME} help delete\n  ${_ME} help edit\n\n$(_color_primary \"Examples\"):\n  # move \"example.md\" to \"sample.org\"\n  ${_ME} move example.md sample.org\n\n  # rename note 3 (\"example.md\") to \"New Name.md\"\n  ${_ME} rename 3 \"New Name\"\n\n  # rename \"example.bookmark.md\" to \"New Name.bookmark.md\"\n  ${_ME} move example.bookmark.md \"New Name\"\n\n  # rename note 3 (\"example.md\") to a bookmark named \"example.bookmark.md\"\n  ${_ME} rename 3 --to-bookmark\n\n  # move note 12 into \"Sample Folder\" in the \"demo\" notebook\n  ${_ME} move example:12 demo:Sample\\ Folder/\n\n  # rename note 12 in the \"example\" notebook to \"sample.md\"\n  ${_ME} rename example:12 \"sample.md\"\n\n  # change the file extension of note 5 to .org\n  ${_ME} rename 5 .org\n\n$(_color_primary \"Alias\"):\n  ${_ME} rename\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} mv\nHEREDOC\n}\n_move() {\n  local _force=0\n  local _reset=0\n  local _selectors=()\n  local _to_target_type=\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      -f|--force|--skip*|-y|--yes)\n        _force=1\n        ;;\n      --reset)\n        _reset=1\n        ;;\n      --to*bookmark)\n        _to_target_type=\"bookmark\"\n        ;;\n      --to*note)\n        _to_target_type=\"note\"\n        ;;\n      --to*title)\n        _to_target_type=\"title\"\n        ;;\n      --to*todo)\n        _to_target_type=\"todo\"\n        ;;\n      --to)\n        _to_target_type=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      -*)\n        :\n        ;;\n      *)\n        if [[ -n \"${1:-}\" ]]\n        then\n          _selectors+=(\"${1:-}\")\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  local _source_selectors=()\n  local _target_selector=\n\n  if ((${#_selectors[@]}))\n  then\n    if ((${#_selectors[@]} - 1))\n    then\n      local i=\n      for ((i=0; i < ${#_selectors[@]} - 1; i++))\n      do\n        _source_selectors+=(\"${_selectors[i]}\")\n      done\n\n      _target_selector=\"${_selectors[${#_selectors[@]}-1]}\"\n    else\n      _source_selectors+=(\"${_selectors[@]}\")\n    fi\n  elif [[ -z \"${_to_target_type:-}\" ]] &&\n       [[ -z \"${_reset:-}\"          ]]\n  then\n    _exit_1 _help \"move\"\n  fi\n\n  if ! ((${#_source_selectors[@]}))\n  then\n    _exit_1 _help \"move\"\n  fi\n\n  local _source_selector=\n  for   _source_selector in \"${_source_selectors[@]:-}\"\n  do\n    local _source_relative_path=\n    _source_relative_path=\"$(_show \"${_source_selector}\" --relative-path)\"\n\n    if [[ -z \"${_source_relative_path:-}\"     ]]\n    then\n      _exit_1 _help \"move\"\n    fi\n\n    local _source_notebook_path=\n    if [[ \"${_source_selector:-}\" =~ :    ]]\n    then\n      _source_notebook_path=\"$(\n        _notebooks show \"${_source_selector}\" --path 2>/dev/null || :\n      )\"\n    fi\n\n    if [[ -z \"${_source_notebook_path:-}\"     ]]\n    then\n      _source_notebook_path=\"$(_notebooks current --path)\"\n    fi\n\n    local _source_basename=\"${_source_relative_path##*\\/}\"\n    local _source_folder_path=\"${_source_notebook_path}\"\n    local _source_path=\"${_source_notebook_path}/${_source_relative_path}\"\n\n    if [[ \"${_source_relative_path:-}\" =~ /   ]]\n    then\n      _source_folder_path=\"${_source_notebook_path}/${_source_relative_path%\\/*}\"\n    fi\n\n    local _source_file_name=\"${_source_basename%%.*}\"\n    local _source_file_type=\"${_source_basename#*.}\"\n\n    if [[ -z \"${_source_file_type:-}\"                     ]] ||\n       [[ \"${_source_file_type}\" == \"${_source_basename}\" ]]\n    then\n      _source_file_type=\n    fi\n\n    local _target_selector_relative_path=\n\n    if ((_reset))\n    then\n      local _target_file_name=\n      _target_file_name=\"$(\n        date -r \"${_source_notebook_path}/${_source_relative_path}\" \"+%Y%m%d%H%M%S\"\n      )\"\n\n      local _target_file_type=\"${_source_file_type:-\"${NB_DEFAULT_EXTENSION}\"}\"\n\n      _target_basename=\"${_target_file_name}.${_target_file_type}\"\n    elif [[ \"${_to_target_type:-}\" == \"title\" ]]\n    then\n      if ! _file_is_text \"${_source_path:-}\"\n      then\n        _exit_1 printf \"Must be a text file.\\\\n\"\n      fi\n\n      local _source_title=\n      _source_title=\"$(_get_content \"${_source_path:-}\" --title)\"\n\n      if [[ -z \"${_source_title:-}\"           ]]\n      then\n        _exit_1 printf \"Title not found.\\\\n\"\n      fi\n\n      local _sanitized_filename=\n      _sanitized_filename=\"$(_get_sanitized_filename \"${_source_title:-}\")\"\n\n      local _target_file_type=\"${_source_file_type:-\"${NB_DEFAULT_EXTENSION}\"}\"\n\n      _target_basename=\"${_sanitized_filename}.${_target_file_type}\"\n    elif [[ -n \"${_target_selector:-}\"        ]] ||\n         [[ -n \"${_to_target_type:-}\"         ]]\n    then\n      _target_selector_relative_path=\"${_target_selector#*:}\"\n\n      local _target_basename=\"${_target_selector_relative_path##*\\/}\"\n      local _target_file_name=\"${_target_basename%%.*}\"\n      local _target_file_type=\"${_target_basename#*.}\"\n\n      if [[   -n \"${_target_file_type:-}\"                         ]] &&\n         [[   -z \"${_target_file_name:-}\"                         ]]\n      then # only file extension in target\n        _target_selector_relative_path=\"\"\n      elif [[ -z \"${_target_file_type:-}\"                         ]] ||\n           [[    \"${_target_file_type}\" == \"${_target_basename}\"  ]]\n      then # no file extension in target\n        if [[ -n \"${_source_file_type}\"                           ]]\n        then\n          _target_file_type=\"${_source_file_type}\"\n        else\n          _target_file_type=\n        fi\n      fi\n\n      case \"${_to_target_type:-}\" in\n        '')       :                                               ;;\n        bookmark) _target_file_type=\"bookmark.md\"                 ;;\n        note)     _target_file_type=\"${NB_DEFAULT_EXTENSION:-md}\" ;;\n        todo)     _target_file_type=\"todo.md\"                     ;;\n        *)        _target_file_type=\"${_to_target_type#.}\"        ;;\n      esac\n\n      if [[ -z \"${_target_file_name:-}\" ]]\n      then\n        _target_file_name=\"${_source_file_name}\"\n      fi\n\n      if [[ -n \"${_target_file_type:-}\" ]]\n      then\n        _target_basename=\"${_target_file_name}.${_target_file_type}\"\n      else\n        _target_basename=\"${_target_file_name}\"\n      fi\n    else\n      _exit_1 _help \"move\"\n    fi\n\n    _target_basename=\"$(_normalize_encoding \"${_target_basename}\")\"\n\n    if [[ -z  \"${_target_selector_relative_path:-}\" ]]\n    then\n      if [[   \"${_source_relative_path}\" =~ /       ]]\n      then\n        _target_selector_relative_path=\"${_source_relative_path%/*}/${_target_basename}\"\n      else\n        _target_selector_relative_path=\"${_target_basename}\"\n      fi\n    fi\n\n    local _target_info=\n    local _target_notebook_path=\n\n    if [[       \"${_target_selector:-}\" =~ :  ]]\n    then\n      _target_notebook_path=\"$(\n        _notebooks show \"${_target_selector:-}\" --path 2>/dev/null || :\n      )\"\n\n      if [[ -z  \"${_target_notebook_path:-}\"  ]]\n      then\n        _exit_1 printf \"Target notebook not found: %s\\\\n\" \"${_target_selector%%:*}\"\n      fi\n    else\n      _target_notebook_path=\"$(_notebooks current --path)\"\n    fi\n\n    if _notebooks current --selected ||\n       [[ \"${_target_notebook_path}\" != \"$(_notebooks current --path)\" ]]\n    then\n      _target_info=\"$(_notebooks show \"${_target_notebook_path}\" --name --no-color):\"\n    fi\n\n    local _target_folder_relative_path=\n\n    if [[ -n \"${_target_selector_relative_path:-}\"  ]]\n    then\n      _target_folder_relative_path=\"$(\n        _selector_resolve_folders \"${_target_selector_relative_path}\" --build || :\n      )\"\n\n      if [[ -z \"${_target_folder_relative_path:-}\"  ]]\n      then\n        _target_folder_relative_path=\"${_target_selector_relative_path%\\/*}\"\n      fi\n    fi\n\n    local _target_folder_path=\n    local _target_relative_path=\n\n    if [[   \"${_target_selector_relative_path:-}\" =~ /            ]]\n    then\n      _target_folder_path=\"${_target_notebook_path}/${_target_folder_relative_path}\"\n      _target_relative_path=\"${_target_folder_relative_path}/${_target_basename}\"\n    else\n      _target_folder_path=\"${_target_notebook_path}\"\n      _target_relative_path=\"${_target_basename}\"\n    fi\n\n    _target_info+=\"${_target_relative_path}\"\n\n    if [[ -e  \"${_target_notebook_path}/${_target_relative_path}\" ]]\n    then\n      _exit_1 printf \"File already exists: %s\\\\n\"         \\\n        \"$(_color_primary \"${_target_info}\")\"\n    fi\n\n    if ! ((_force))\n    then\n      printf \"Moving:   %s\\\\n\" \"$(_show \"${_source_path}\" --info-line)\"\n      printf \"To:       %s\\\\n\" \"$(_color_primary \"${_target_info}\")\"\n\n      while true\n      do\n        local __yn=\n        IFS='' read -r -e -d $'\\n' -p                     \\\n\"$(_color_primary \"Proceed?\")  $(_color_brackets \"y/N\") \" __yn\n\n        case \"${__yn}\" in\n          [Yy]*)\n            break\n            ;;\n          *)\n            printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n            exit 0\n            ;;\n        esac\n      done\n    fi\n\n    if [[ ! -e \"${_target_folder_path}\" ]]\n    then\n      mkdir -p \"${_target_folder_path}\" ||\n        _exit_1 printf \"Unable to create folder: %s\\\\n\"   \\\n          \"$(_color_primary \"${_target_folder_path}\")\"\n    fi\n\n    mv \"${_source_path}\" \"${_target_notebook_path}/${_target_relative_path}\" ||\n      _exit_1 printf \"Move failed.\\\\n\"\n\n    if [[ -e \"${_source_folder_path:-}/.pindex\"           ]]  &&\n       grep -q  \"^${_source_basename}$\"     \"${_source_folder_path:-}/.pindex\"\n    then\n      if [[ \"${_source_folder_path}\" == \"${_target_folder_path}\"    ]]\n      then\n        _sed_i -e                                         \\\n          \"s/^${_source_basename}$/${_target_basename}/\"  \\\n          \"${_source_folder_path:-}/.pindex\"\n      else\n        _sed_i -e                                         \\\n          \"/^${_source_basename}$/d\"                      \\\n          \"${_source_folder_path:-}/.pindex\"\n\n        if [[ ! -e \"${_target_folder_path:-}/.pindex\"     ]]\n        then\n          touch \"${_target_folder_path:-}/.pindex\"\n        fi\n\n        printf \"%s\\\\n\" \"${_target_basename}\" >> \"${_target_folder_path:-}/.pindex\"\n      fi\n    fi\n\n    if [[ \"${_source_notebook_path}\" == \"${_target_notebook_path}\"  ]]\n    then\n      if [[ \"${_source_folder_path}\" == \"${_target_folder_path}\"    ]]\n      then\n        _index update               \\\n          \"${_source_basename}\"     \\\n          \"${_target_basename}\"     \\\n          \"${_source_folder_path}\"\n      else\n        _index delete \"${_source_basename}\" \"${_source_folder_path}\"  &&\n          _index add  \"${_target_basename}\" \"${_target_folder_path}\"\n      fi || _exit_1 printf \"Move index update failed.\\\\n\"\n\n      _git checkpoint \"${_target_notebook_path}\"  \\\n        \"[${_ME}] Move: ${_source_relative_path} to ${_target_relative_path}\"\n    else\n      _index delete \"${_source_basename}\" \"${_source_folder_path}\"\n\n      _git checkpoint \"${_source_notebook_path}\"  \\\n        \"[${_ME}] Delete: ${_source_relative_path}\"\n\n      _index add \"${_target_basename}\" \"${_target_folder_path}\"\n\n      _git checkpoint \"${_target_notebook_path}\"  \\\n        \"[${_ME}] Add: ${_target_relative_path}\"\n    fi\n\n    printf \"Moved to: %s\\\\n\" \"$(\n      _show \"${_target_notebook_path}/${_target_relative_path}\" --info-line\n    )\"\n  done\n}\n_alias_subcommand \"move\" \"mv\"\n_alias_subcommand \"move\" \"rename\"\n\n# open ################################################################### open\n\n_describe_open() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} open ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\n$(_color_primary \"Description\"):\n  Open an item or notebook. When the item is a bookmark, open the bookmarked\n  page in your system's primary web browser. When the item is in a text format\n  or any other file type, \\`open\\` is the equivalent of \\`edit\\`. \\`open\\`\n  with a notebook opens the notebook folder in the system's file browser.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#viewing-bookmarks\n\n$(_color_primary \"See also\"):\n  ${_ME} help bookmark\n  ${_ME} help browse\n  ${_ME} help peek\n  ${_ME} help show\n\n$(_color_primary \"Examples\"):\n  ${_ME} open 3\n  ${_ME} open example.bookmark.md\n  ${_ME} 3 open\n  ${_ME} example:open 12\n  ${_ME} open example:12\n  ${_ME} example:12 open\n  ${_ME} o 3\n  ${_ME} 3 o\n  ${_ME} o example:12\n  ${_ME} example:12 o\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} o\nHEREDOC\n}\n_open() {\n  if [[ -z \"${1:-}\" ]]\n  then\n    _exit_1 _help \"open\"\n  fi\n\n  _bookmark open \"${@:-}\"\n}\n_alias_subcommand \"open\" \"o\"\n\n# peek ################################################################### peek\n\n_describe_peek() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} peek ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\n$(_color_primary \"Description\"):\n  View an item or notebook in the terminal. When the item is a bookmark, view\n  the bookmarked page in your terminal web browser. When the note is in a text\n  format or any other file type, \\`peek\\` is the equivalent of \\`show\\`. When\n  used with a notebook, \\`peek\\` opens the notebook folder first tool found in\n  the following list: \\`ranger\\` [1], \\`mc\\` [2], \\`vifm\\` [3], \\`joshuto\\` [4],\n  \\`lsd\\` [5] \\`eza\\` [6], or \\`ls\\`.\n\n    1. https://ranger.github.io/\n    2. https://en.wikipedia.org/wiki/Midnight_Commander\n    3. https://vifm.info/\n    4. https://github.com/kamiyaa/joshuto\n    5. https://github.com/lsd-rs/lsd\n    6. https://github.com/eza-community/eza\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#viewing-bookmarks\n\n$(_color_primary \"See also\"):\n  ${_ME} help bookmark\n  ${_ME} help browse\n  ${_ME} help open\n  ${_ME} help show\n\n$(_color_primary \"Examples\"):\n  ${_ME} peek 3\n  ${_ME} peek example.bookmark.md\n  ${_ME} 3 peek\n  ${_ME} example:peek 12\n  ${_ME} peek example:12\n  ${_ME} example:12 peek\n  ${_ME} p 3\n  ${_ME} 3 p\n  ${_ME} p example:12\n  ${_ME} example:12 p\n\n$(_color_primary \"Alias\"):\n  ${_ME} preview\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} p\nHEREDOC\n}\n_peek() {\n  if [[ -z \"${1:-}\" ]]\n  then\n    _exit_1 _help \"peek\"\n  fi\n\n  _bookmark peek \"${@}\"\n}\n_alias_subcommand \"peek\" \"p\"\n_alias_subcommand \"peek\" \"preview\"\n\n# pin ##################################################################### pin\n\n_describe_pin() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} pin ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\n$(_color_primary \"Description\"):\n  Pin an item so it appears first in lists.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-pinning\n\n$(_color_primary \"See Also\"):\n  ${_ME} help browse\n  ${_ME} help list\n  ${_ME} help ls\n  ${_ME} help unpin\n\n$(_color_primary \"Examples\"):\n  ${_ME} pin 123\n  ${_ME} pin example:sample/321\nHEREDOC\n}\n_pin() {\n  local _selector=\n  local _subcommand=\"pin\"\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg:-}\" in\n      unpin)  _subcommand=\"unpin\"     ;;\n      *)      _selector=\"${__arg:-}\"  ;;\n    esac\n  done\n\n  if [[ -z \"${_selector:-}\" ]]\n  then\n    _warn _help \"${_subcommand}\"\n\n    return 1\n  fi\n\n  local _item_path=\n  _item_path=\"$(_show \"${_selector}\" --path)\" || return 1\n\n  local _basename=\"${_item_path##*\\/}\"\n  local _folder_path=\"${_item_path%\\/*}\"\n  local _pindex_path=\"${_folder_path}/.pindex\"\n\n  local _notebook_path=\n  _notebook_path=\"$(\n    _notebooks show \"${_selector}\" --path 2>/dev/null ||\n      _notebooks current --path\n  )\"\n\n  local _relative_path=\n  _relative_path=\"$(_show \"${_selector}\" --relative-path)\"\n\n  if [[ ! -e \"${_item_path:-}\"        ]] ||\n     [[ ! -d \"${_folder_path:-}\"      ]] ||\n     [[   -z \"${_basename:-}\"         ]] ||\n     [[   -z \"${_notebook_path:-}\"    ]] ||\n     [[   -z \"${_relative_path:-}\"    ]]\n  then\n    _warn printf \"Not found: %s\\\\n\" \"${_selector}\"\n\n    return 1\n  fi\n\n  case \"${_subcommand:-}\" in\n    unpin)\n      if [[ ! -e \"${_pindex_path}\"    ]] ||\n         ! grep -q \"^${_basename}$\" \"${_pindex_path}\"\n      then\n        _warn printf                  \\\n          \"Not pinned: %s\\\\n\"         \\\n          \"$(_color_primary \"${_selector}\")\"\n\n        return 1\n      fi\n\n      _sed_i -e \"s/^${_basename}$//g\"   \"${_pindex_path}\"\n      _sed_i -e '/^[[:space:]]*$/d'     \"${_pindex_path}\" # remove blank line\n\n      if [[ ! -s \"${_pindex_path:?}\"  ]]\n      then\n        rm -f \"${_pindex_path:?}\"\n      fi\n\n      _git checkpoint \"${_notebook_path}\" \"[${_ME}] Unpinned: ${_relative_path}\"\n\n      printf \"Unpinned: %s\\\\n\" \"$(_show \"${_selector}\" --info-line)\"\n      ;;\n    *)\n      if [[ ! -e \"${_pindex_path}\"    ]]\n      then\n        touch \"${_pindex_path}\"\n      fi\n\n      if grep -q \"^${_basename}$\" \"${_pindex_path}\"\n      then\n        _warn printf                  \\\n          \"Already pinned: %s\\\\n\"     \\\n          \"$(_color_primary \"${_selector}\")\"\n\n        return 1\n      else\n        printf \"%s\\\\n\" \"${_basename}\" >> \"${_pindex_path}\"\n        _sed_i -e '/^[[:space:]]*$/d'    \"${_pindex_path}\" # remove blank lines\n\n        _git checkpoint \"${_notebook_path}\" \"[${_ME}] Pinned: ${_relative_path}\"\n\n        printf \"Pinned: %s\\\\n\" \"$(_show \"${_selector}\" --info-line)\"\n      fi\n      ;;\n  esac\n}\n\n# run ##################################################################### run\n\n_describe_run() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} run <command> [<arguments>...]\n\n$(_color_primary \"Description\"):\n  Run shell commands within the current notebook directory.\n\n$(_color_primary \"See Also\"):\n  ${_ME} help git\n  ${_ME} help shell\n\n$(_color_primary \"Examples\"):\n  ${_ME} run ls -la\n  ${_ME} run find . -name 'example*'\n  ${_ME} run rg example\nHEREDOC\n}\n_run() {\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  cd \"${_notebook_path}\"  || _exit_1 printf \"_run() \\`cd\\` failed.\\\\n\"\n  [[ -n \"${*}\" ]]         || _exit_1 printf \"Command required.\\\\n\"\n\n  if ! _command_exists \"${1:-}\"\n  then\n    _warn printf \"Command not found: %s\\\\n\" \"$(_color_primary \"${1:-}\")\"\n\n    exit 127\n  fi\n\n  (\"${@}\")\n}\n_alias_subcommand \"run\" \"r\"\n\n# search ############################################################### search\n\n_describe_search() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} search ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n            <query>... [-a | --all] [--and <query>] [--not <query>] [--or <query>]\n            [-l | --list] [--path] [-t <tag1>,<tag2>... | --tag <tag1>,<tag2>...]\n            [-t | --tags] [--type <type> | --<type>] [--utility <name>]\n\n$(_color_primary \"Options\"):\n  -a, --all                     Search all unarchived notebooks.\n  --and <query>                 Add a AND query.\n  -l, --list                    Print the id, filename, and title listing for\n                                each matching file, without the excerpt.\n  --not <query>                 Add a NOT query.\n  --or  <query>                 Add an OR query.\n  --path                        Print the full path for each matching file.\n  -t, --tag <tag1>,<tag2>...    A comma-separated list of tags.\n  -t, --tags                    List all tags found in the notebook.\n  --type <type>, --<type>       Search items of <type>. <type> can be a file\n                                extension or one of the following types:\n                                archive, audio, book, bookmark, document,\n                                folder, image, note, text, video\n  --utility <name>              The name of the search utility to search with.\n\n$(_color_primary \"Description\"):\n  Perform a full text search.\n\n  Multiple query arguments are treated as AND queries, returning items that\n  match all queries. AND queries can also be specified with the --and <query>\n  option. The --or <query> option can be used to specify an OR query,\n  returning items that match at least one of the queries. --not <query>\n  excludes items matching <query>.\n\n  \\`${_ME} search\\` is powered by Git's built-in \\`git grep\\` tool. \\`${_ME}\\` also\n  supports performing searches with alternative search tools using the\n  --utility <name> option.\n\n  Supported alternative search tools:\n    1. \\`rga\\`   https://github.com/phiresky/ripgrep-all\n    2. \\`rg\\`    https://github.com/BurntSushi/ripgrep\n    3. \\`ag\\`    https://github.com/ggreer/the_silver_searcher\n    4. \\`ack\\`   https://beyondgrep.com/\n    5. \\`grep\\`  https://en.wikipedia.org/wiki/Grep\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-search\n\n$(_color_primary \"See Also\"):\n  ${_ME} help browse\n  ${_ME} help list\n  ${_ME} help ls\n\n$(_color_primary \"Examples\"):\n  # search current notebook for \"example query\"\n  ${_ME} search \"example query\"\n\n  # search the notebook \"example\" for \"example query\"\n  ${_ME} search example: \"example query\"\n\n  # search all notebooks for \"example query\" and list matching items\n  ${_ME} search \"example query\" --all --list\n\n  # search for items matching \"Example\" AND \"Demo\"\n  ${_ME} search \"Example\" \"Demo\"\n  ${_ME} search \"Example\" --and \"Demo\"\n\n  # search for items matching \"Example\" OR \"Sample\"\n  ${_ME} search \"Example|Sample\"\n  ${_ME} search \"Example\" --or \"Sample\"\n\n  # search for items matching both \"Example\" AND \"Sample\", and NOT \"Demo\"\n  ${_ME} search \"Example\" --and \"Sample\" --not \"Demo\"\n\n  # search with a regular expression\n  ${_ME} search \"\\d\\d\\d-\\d\\d\\d\\d\"\n\n  # search for tags\n  ${_ME} search --tag tag1 -t tag2\n\n  # search the current notebook for \"example query\"\n  ${_ME} q \"example query\"\n\n  # search all notebooks for \"example query\" and list matching items\n  ${_ME} q -la \"example query\"\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} q\nHEREDOC\n}\n_search() {\n  # Usage: _search_with <command-name> <search-utility>\n  _search_with() {\n    _command_exists \"${1:?}\" && [[ \"${2:-}\" == \"${1:?}\" ]]\n  }\n\n  local _all=0\n  local _and_queries=()\n  local _not_queries=()\n  local _arguments=()\n  local _last_path=\n  local _limit=0\n  local _max_columns=\"2000\"\n  local _max_depth=0\n  local _only_list=0\n  local _option_tags=()\n  local _or_queries=()\n  local _page=1\n  local _print_notebook_selectors=0\n  local _print_paths=0\n  local _query=\n  local _replacement=\n  local _search_args=()\n  local _search_for_tags=0\n  local _search_utility=\n  local _selectors=()\n  local _sort=0\n  local _type=\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      -a|--all)\n        _all=1\n        ;;\n      --and|--not|--or)\n        local _operator=\"${1#--}\"\n\n        if [[ \"${2:-}\" == \"-e\" ]]\n        then\n          shift\n        fi\n\n        if [[ \"${2:-}\" =~ (^-t$|^--tag*|^--hashtag*) ]] &&\n           _option_value_is_present \"${3:-}\"\n        then\n          shift\n\n          IFS=' ' read -ra _option_tags <<< \"$(\n            _option_get_tags \"${1:-}\" \"${2:-}\"\n          )\"\n\n          if [[   \"${_operator:-}\" == \"and\" ]]\n          then\n            _and_queries+=(${_option_tags[@]:-})\n          elif [[ \"${_operator:-}\" == \"not\" ]]\n          then\n            _not_queries+=(${_option_tags[@]:-})\n          else\n            _or_queries+=(${_option_tags[@]:-})\n          fi\n\n          shift\n        else\n          if [[   \"${_operator:-}\" == \"and\" ]]\n          then\n            _and_queries+=(\"$(_option_get_value \"--and\" \"${2:-}\")\")\n          elif [[ \"${_operator:-}\" == \"not\" ]]\n          then\n            _not_queries+=(\"$(_option_get_value \"--not\" \"${2:-}\")\")\n          else\n            _or_queries+=(\"$(_option_get_value \"--or\" \"${2:-}\")\")\n          fi\n\n          shift\n        fi\n        ;;\n      --limit|-n|--num|--number|--per*)\n        _limit=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      -l|--list)\n        _only_list=1\n        ;;\n      --no*color)\n        _COLOR_ENABLED=0\n        ;;\n      --no*recur*)\n        _max_depth=1\n        ;;\n      --notebook-selectors)\n        _print_notebook_selectors=1\n        ;;\n      --page)\n        _page=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n        ((_page)) || _page=1\n\n        shift\n        ;;\n      --path*)\n        _print_paths=1\n        _COLOR_ENABLED=0\n        ;;\n      -q|--query|-e)\n        _and_queries+=(\"$(_option_get_value \"${1}\" \"${2:-}\")\")\n\n        shift\n        ;;\n      --replace*)\n        # TODO\n        _replacement=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      -s|--sort)\n        _sort=1\n        ;;\n      -t|--tag*|--hashtag*)\n        if _option_value_is_present \"${2:-}\"\n        then\n          IFS=' ' read -ra _option_tags <<< \"$(\n            _option_get_tags \"${1:-}\" \"${2:-}\"\n          )\"\n\n          _and_queries+=(${_option_tags[@]:-})\n\n          shift\n        else\n          _search_for_tags=1\n        fi\n        ;;\n      --*tool|--*utility)\n        _search_utility=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --type)\n        _type=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --use*grep)\n        # TODO: Remove. Replaced with the --tool / --utility option.\n        _search_utility=\"grep\"\n        ;;\n      *)\n        if [[ \"${1:-}\" =~ ^-- ]]\n        then\n          _type=\"${1:2}\"\n        else\n          _arguments+=(\"${1}\")\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  if [[ -z \"${_search_utility:-}\"                       ]] &&\n     [[ -n \"${NB_SEARCH_TOOL:-${NB_SEARCH_UTILITY:-}}\"  ]]\n  then\n    _search_utility=${NB_SEARCH_TOOL:-${NB_SEARCH_UTILITY:-}}\n  fi\n\n  local _current_notebook_path=\n  _current_notebook_path=\"$(_notebooks current --path)\"\n\n  local _local_notebook_path=\n  _local_notebook_path=\"$(_notebooks --local --path || :)\"\n\n  local _target_paths=()\n\n  if ((_all))\n  then\n    _target_paths=($(_notebooks --paths --unarchived))\n  fi\n\n  local i=\n  for ((i=0; i < ${#_arguments[@]}; i++))\n  do\n    local _maybe_path=\n\n    if [[ -z \"${_arguments[i]:-}\"     ]]\n    then\n      continue\n    elif [[ \"${_arguments[i]}\" =~ :$  ]]\n    then\n      _maybe_path=\"$(\n        _notebooks show \"${_arguments[i]}\" --path 2>/dev/null || :\n      )\"\n\n      if [[ -n \"${_maybe_path:-}\"     ]]\n      then\n        _notebooks select \"${_arguments[i]}\"\n      fi\n    else\n      if [[ \"${_arguments[i]}\" =~ ^/  ]]\n      then\n        _maybe_path=\"${_arguments[i]%/}\"\n      else\n        _maybe_path=\"$(\n          _selector_resolve_path \"${_arguments[i]:-}\" \\\n            --full                                    \\\n            --skip-titles                             \\\n            2>/dev/null || :\n        )\"\n      fi\n    fi\n\n    if [[ -z \"${_maybe_path:-}\"                     ]] ||\n       {\n         [[ \"${i}\" -eq \"$((${#_arguments[@]} - 1))\" ]] &&\n         [[ -z \"${_and_queries[*]:-}\"               ]]\n       }\n    then\n      local _query_argument=\"${_arguments[i]:-}\"\n\n      if [[ \"${_query_argument:-}\"    =~ ^[^/]*/$   ]]\n      then\n        if [[ -d \"${_maybe_path:-}\"   ]]\n        then\n          _query_argument=\n        else\n          _query_argument=\"${_query_argument%\\/}\"\n        fi\n      fi\n\n      if _notebooks current --selected\n      then\n        _and_queries+=(\"${_query_argument#*:}\")\n      else\n        _and_queries+=(\"${_query_argument}\")\n      fi\n    fi\n\n    if [[ -n \"${_maybe_path:-}\"       ]] &&\n       [[ -z \"${_target_paths[*]:-}\"  ]] &&\n       {\n         _notebooks current --selected   ||\n         [[ \"${#_arguments[@]}\" -gt 1 ]] ||\n         ((_search_for_tags))\n       }\n    then\n      _target_paths+=(\"${_maybe_path}\")\n      _selectors+=(\"${_arguments[i]}\")\n    fi\n  done\n\n  if [[ -z \"${_target_paths[*]:-}\"    ]]\n  then\n    _target_paths=(\"${_current_notebook_path}\")\n  fi\n\n  local _xargs=(\"-0\")\n\n  if xargs --help &> /dev/null\n  then # GNU (BSD does this by default)\n    _xargs+=(\"--no-run-if-empty\")\n  fi\n\n  if ((_search_for_tags))\n  then\n    local _git_major_version=\n    _git_major_version=\"$(git --version | cut -d \" \"  -f 3 | cut -d \".\" -f 1)\"\n\n    local _git_minor_version=\n    _git_minor_version=\"$(git --version | cut -d \" \"  -f 3 | cut -d \".\" -f 2)\"\n\n    local _use_git_grep=0\n\n    if ((_GIT_ENABLED))                           &&\n       [[ \"${_git_major_version:-}\"   -gt 2   ]]  ||  {\n         [[ \"${_git_major_version:-}\" ==  2   ]]  &&\n         [[ \"${_git_minor_version:-}\" -ge 19  ]]\n    }\n    then # git 2.19+ has --only-matching option\n      _use_git_grep=1\n    fi\n\n    if ((_use_git_grep))\n    then\n      local _grep_arguments=(\n        \"--extended-regexp\"\n        \"-I\"\n        \"--ignore-case\"\n        \"--only-matching\"\n        -e '(^|[[:space:]])#[[:alnum:]/_-]+'\n      )\n    else\n      local _grep_arguments=(\n        \"--extended-regexp\"\n        \"-I\"\n        \"--ignore-case\"\n        \"--only-matching\"\n        -e '[[:space:]]#[[:alnum:]/_-]+'\n        -e '^#[A-Za-z0-9/_-]+'\n      )\n    fi\n\n    {\n      local __target_path=\n      for   __target_path in \"${_target_paths[@]:-}\"\n      do\n        [[ -n \"${__target_path:-}\"    ]] || continue\n\n        if [[ -d \"${__target_path:-}\" ]]\n        then\n          local _target_folder_path=\"${__target_path:-}\"\n        else\n          local _target_folder_path=\"${__target_path%/*}\"\n        fi\n\n        {\n          if ((_use_git_grep))\n          then\n            GIT_PAGER=''                      \\\n              git -C \"${_target_folder_path}\" \\\n              grep                            \\\n              \"${_grep_arguments[@]:-}\"       \\\n              --files-with-matches            \\\n              --null                          \\\n              \"${__target_path}\"              \\\n              2>/dev/null || true\n          else\n            {\n              find \"${__target_path}\"         \\\n                ! -path '*/.git*'             \\\n                -path '*/[^.]*'               \\\n                -type f                       \\\n                -print0\n            } | {\n              xargs \"${_xargs[@]}\"            \\\n                grep                          \\\n                \"${_grep_arguments[@]:-}\"     \\\n                --files-with-matches          \\\n                --null\n            }\n          fi\n        } | {\n          if ((_use_git_grep))\n          then\n            GIT_PAGER=''                      \\\n              xargs \"${_xargs[@]}\"            \\\n              git -C \"${_target_folder_path}\" \\\n              grep                            \\\n              \"${_grep_arguments[@]:-}\"       \\\n              -e \"## Comment\"                 \\\n              -e \"## Tags\"                    \\\n              -e \"## Content\"                 \\\n              -e \"## Page Content\"            \\\n              -e \"## Source\"                  \\\n              2>/dev/null || true\n          else\n            xargs \"${_xargs[@]}\"              \\\n              grep                            \\\n              \"${_grep_arguments[@]:-}\"       \\\n              -e \"## Comment\"                 \\\n              -e \"## Tags\"                    \\\n              -e \"## Content\"                 \\\n              -e \"## Page Content\"            \\\n              -e \"## Source\"                  \\\n              2>/dev/null || true\n          fi\n        }\n      done\n    } | {\n      local _last_match_path=\n      local _match_path=\n      local _seen_matches=()\n      local _skip=1\n\n      local         __match=\n      while read -r __match\n      do\n        if [[ \"${__match:-}\" =~ : ]]\n        then\n          _match_path=\"${__match%:*}\"\n        fi\n\n        local _normalized_match=\"${__match##*:}\"\n        _normalized_match=\"${_normalized_match#\"${_normalized_match%%[![:space:]]*}\"}\"\n        _normalized_match=\"${_normalized_match%\"${_normalized_match##*[![:space:]]}\"}\"\n\n        if [[ \"${_match_path:-}\"              =~ \\.bookmark\\.md$    ]]\n        then\n          if [[ \"${_last_match_path:-}\"       != \"${_match_path:-}\" ]]\n          then\n            _skip=1\n            _last_match_path=\"${_match_path}\"\n          fi\n\n          if [[ \"${_normalized_match:-}\"      =~ ^##                ]]\n          then\n            if [[ \"${_normalized_match:-}\"    =~ (Comment|Tags)     ]]\n            then\n              _skip=0\n            elif [[ \"${_normalized_match:-}\"  =~ (Content|Source)   ]]\n            then\n              _skip=1\n            fi\n\n            continue\n          fi\n\n          if ((_skip))\n          then\n            continue\n          fi\n        elif [[ \"${_normalized_match:-}\"      =~ ^##                ]]\n        then\n          continue\n        fi\n\n        if ! _contains \"${_normalized_match}\" \"${_seen_matches[@]:-}\"\n        then\n          printf \"%s\\\\n\" \"${_normalized_match:-}\"\n          _seen_matches+=(\"${_normalized_match:-}\")\n        fi\n      done\n\n      if ! ((${#_seen_matches[@]}))\n      then\n        printf \"No #hashtags found.\\\\n\"\n      fi\n    }\n\n    return 0\n  fi\n\n  if [[ -z \"${_and_queries[*]:-}\" ]] &&\n     [[ -z \"${_not_queries[*]:-}\" ]]\n  then\n    _exit_1 _help \"search\"\n  fi\n\n  local _queries=()\n\n  local __and_query=\n  for   __and_query in \"${_and_queries[@]:-}\"\n  do\n    [[ -n \"${__and_query:-}\"            ]] || continue\n\n    if [[ \"${_and_query:-}\" =~ ^\\#      ]]\n    then\n      _and_query=\"${_and_query}$\"\n    fi\n\n    if ((${#_or_queries[@]}))\n    then\n      local _or_query_string=\n\n      local __or_query=\n      for   __or_query in \"${_or_queries[@]:-}\"\n      do\n        [[ -n \"${__or_query:-}\"         ]] || continue\n\n        if [[ \"${__or_query:-}\" =~ ^\\#  ]]\n        then\n          __or_query=\"${__or_query}$\"\n        fi\n\n        _or_query_string=\"${_or_query_string}|${__or_query}\"\n      done\n\n      _queries+=(\"${__and_query}${_or_query_string}\")\n    else\n      _queries+=(\"${__and_query}\")\n    fi\n  done\n\n  local _query=\n  _query=\"$(_join \"|\" \"${_queries[@]:-}\")\"\n\n  if [[ -z \"${_query:-}\"          ]] &&\n     [[ -n \"${_not_queries[*]:-}\" ]]\n  then\n    _only_list=1\n  fi\n\n  {\n    local __target_path=\n    for   __target_path in \"${_target_paths[@]:-}\"\n    do\n      if [[ -d \"${__target_path}\" ]]\n      then\n        local _target_folder_path=\"${__target_path}\"\n      else\n        local _target_folder_path=\"${__target_path%\\/*}\"\n      fi\n\n      local _max_id=\n      _max_id=\"$(_index get_max_id \"${_target_folder_path}\")\"\n\n      {\n        if _search_with \"rg\" \"${_search_utility:-}\"\n        then\n          local _rg_command=\"rg\"\n\n          if _command_exists \"rga\"\n          then\n            _rg_command=\"rga\"\n          fi\n\n          if ((_max_depth))\n          then\n            _search_args+=(\"--max-depth\" \"${_max_depth}\")\n          fi\n\n          if ((_COLOR_ENABLED))\n          then\n            _search_args+=(\"--color\" \"always\")\n          else\n            _search_args+=(\"--color\" \"never\")\n          fi\n\n          if ((_sort))\n          then\n            _search_args+=(\"--sort-files\")\n          fi\n\n          local _search_paths=(\"${__target_path}\")\n\n          if [[ -f \"${__target_path}\"     ]] &&\n             [[ \"${#_arguments[@]}\" -le 1 ]]\n          then\n            _search_paths+=(\"${__target_path%\\/*}/.index\")\n          fi\n\n          \"${_rg_command}\"                  \\\n            --hidden                        \\\n            --iglob '!.git'                 \\\n            --ignore-case                   \\\n            --line-number                   \\\n            --max-columns \"${_max_columns}\" \\\n            --max-columns-preview           \\\n            --no-heading                    \\\n            --with-filename                 \\\n            \"${_search_args[@]}\"            \\\n            \"${_query}\"                     \\\n            \"${_search_paths[@]:-}\"         \\\n              || return 0 # Don't fail out within a single scope.\n        elif _search_with \"ag\" \"${_search_utility:-}\"\n        then\n          if ((_max_depth))\n          then\n            _search_args+=(\"--norecurse\")\n          fi\n\n          if ((_COLOR_ENABLED))\n          then\n            _search_args+=(\"--color\")\n            _search_args+=(\"--color-line-number\"  \"32\")\n            _search_args+=(\"--color-match\"        \"1;35\")\n          else\n            _search_args+=(\"--nocolor\")\n          fi\n\n          # TODO: ag doesn't support sorting directly.\n          # if ((_sort))\n          # then\n          #   _search_args+=(\"--workers\" \"1\")\n          # fi\n\n          local _search_paths=(\"${__target_path}\")\n\n          if [[ -f \"${__target_path}\"     ]] &&\n             [[ \"${#_arguments[@]}\" -le 1 ]]\n          then\n            _search_paths+=(\"${__target_path%\\/*}/.index\")\n          fi\n\n          ag                      \\\n            --filename            \\\n            --hidden              \\\n            --ignore \".git\"       \\\n            --ignore-case         \\\n            --noheading           \\\n            \"${_search_args[@]}\"  \\\n            \"${_query}\"           \\\n            \"${_search_paths[@]}\" \\\n              || return 0 # Don't fail out within a single scope.\n        elif _search_with \"ack\" \"${_search_utility:-}\"\n        then # ack is available.\n          if ((_max_depth))\n          then\n            _search_args+=(\"--no-recurse\")\n          fi\n\n          if ((_COLOR_ENABLED))\n          then\n            _search_args+=(\"--color\")\n            _search_args+=(\"--color-lineno=bold green\")\n            _search_args+=(\"--color-match=blue on_black\")\n          else\n            _search_args+=(\"--nocolor\")\n          fi\n\n          if ((_sort))\n          then\n            _search_args+=(\"--sort-files\")\n          fi\n\n          local _search_paths=(\"${__target_path}\")\n\n          if [[ -f \"${__target_path}\"     ]] &&\n             [[ \"${#_arguments[@]}\" -le 1 ]]\n          then\n            _search_paths+=(\"${__target_path%\\/*}/.index\")\n          fi\n\n          ack                     \\\n            --ignore-case         \\\n            --noheading           \\\n            --with-filename       \\\n            \"${_search_args[@]}\"  \\\n            \"${_query}\"           \\\n            \"${_search_paths[@]}\" \\\n              || return 0 # Don't fail out within a single scope.\n        elif _search_with \"grep\" \"${_search_utility:-}\"\n        then\n          if _grep_supports_color\n          then\n            if ((_COLOR_ENABLED))\n            then\n              _search_args+=(\"--color=always\")\n            else\n              _search_args+=(\"--color=never\")\n            fi\n          fi\n\n          set +f\n          {\n            if [[ -f \"${__target_path:-}\"     ]]\n            then\n              if [[ \"${#_arguments[@]}\" -le 1 ]]\n              then\n                # Print .index with null byte delimiter so it's included in\n                # the list of files to search.\n                printf \"%s/.index\\0%s\" \"${__target_path%\\/*}\" \"${__target_path}\"\n              else\n                printf \"%s\" \"${__target_path}\"\n              fi\n            elif [[ \"${_max_depth}\" == 1      ]]\n            then\n              # Print .index with null byte delimiter so it's included in\n              # the list of files to search.\n              printf \"%s/.index\\0\" \"${__target_path}\"\n              find \"${__target_path}\"/*   \\\n                \\( -name . -o -prune \\)   \\\n                -type f                   \\\n                -print0\n            else\n              find \"${__target_path}\"                     \\\n                ! -path '*/.git*'                         \\\n                \\( -path '*/.index' -o -path '*/[^.]*' \\) \\\n                -type f                                   \\\n                -print0\n            fi\n          } | {\n            # Add /dev/null so file path is printed even if there is only one\n            # matching file. Reference: https://stackoverflow.com/a/15432718\n            xargs -0 grep           \\\n              -E                    \\\n              --ignore-case         \\\n              \"${_search_args[@]}\"  \\\n              --text                \\\n              -n                    \\\n              \"${_query}\"           \\\n              /dev/null             \\\n                || return 0 # Don't fail out within a single scope.\n          }\n          set -f\n        else\n          local _notebook_path=\n          _notebook_path=\"$(_notebooks show \"${__target_path:-}\" --path)\"\n\n          local _escaped_notebook_path=\n          _escaped_notebook_path=\"$(\n            printf \"%s\\\\n\" \"${_notebook_path:-}\" | LC_ALL=C sed 's/\\//\\\\\\//g'\n          )\"\n\n          if ((_max_depth))\n          then\n            _search_args+=(\"--no-recursive\")\n          fi\n\n          local _search_args_no_color=(\"--color=never\")\n\n          if [[ -n \"${_search_args[*]:-}\" ]]\n          then\n            _search_args_no_color+=(\"${_search_args[@]:-}\")\n          fi\n\n          if ((_COLOR_ENABLED))\n          then\n            _search_args+=(\"--color=always\")\n          else\n            _search_args+=(\"--color=never\")\n          fi\n\n          local _search_paths=(\"${__target_path}\")\n\n          if [[ -f \"${__target_path}\"     ]] &&\n             [[ \"${#_arguments[@]}\" -le 1 ]]\n          then\n            _search_paths+=(\"${__target_path%\\/*}/.index\")\n          fi\n\n          if [[ \"${#_queries[@]}\" == 1 ]]\n          then\n            GIT_PAGER='' git -C \"${_notebook_path}\"               \\\n              grep                                                \\\n              --extended-regexp                                   \\\n              --ignore-case                                       \\\n              --line-number                                       \\\n              --text                                              \\\n              \"${_search_args[@]:-}\"                              \\\n              -e \"${_query:-}\"                                    \\\n              \"${_search_paths[@]:-}\"                             \\\n            | LC_ALL=C sed -e \"s/^/${_escaped_notebook_path}\\//\"  \\\n              || return 0  # Don't fail out within a single scope.\n          else\n            local __search_group=\n            for   __search_group in \"index\" \"files\"\n            do\n              {\n                if [[ \"${__search_group}\" == \"index\" ]]\n                then\n                  # list all .index files\n                  GIT_PAGER='' git -C \"${_notebook_path}\" \\\n                    ls-files -z '*.index'\n                else\n                  # list all non-.index files\n                  GIT_PAGER='' git -C \"${_notebook_path}\" \\\n                    ls-files -z -- . ':!:*.index'\n                fi\n              } | {\n                local _last_pipe=\n                local _this_pipe=\n\n                local __and_query=\n                for   __and_query in \"${_queries[@]:-}\"\n                do\n                  [[ -n \"${__and_query:-}\"    ]] || continue\n\n                  _this_pipe=$(_temp file --touch) && {\n                    rm -f   \"${_this_pipe}\"\n                    mkfifo  \"${_this_pipe}\"\n                  }\n\n                  if [[ -p \"${_last_pipe:-}\"  ]]\n                  then\n                    <\"${_last_pipe:-}\" cat\n                  else\n                    cat\n                  fi | {\n                    GIT_PAGER='' xargs \"${_xargs[@]}\" \\\n                      git -C \"${_notebook_path}\"      \\\n                      grep                            \\\n                      --extended-regexp               \\\n                      --files-with-matches            \\\n                      --ignore-case                   \\\n                      --null                          \\\n                      --text                          \\\n                      \"${_search_args_no_color[@]:-}\" \\\n                      -e \"${__and_query:-}\"           \\\n                        || return 0  # Don't fail out within a single scope.\n                  } > \"${_this_pipe:-}\" &\n\n                  _last_pipe=\"${_this_pipe:-}\"\n                done\n\n                if [[ -p \"${_last_pipe:-}\"    ]]\n                then\n                  <\"${_last_pipe:-}\" cat\n                else\n                  cat\n                fi\n              } | {\n                local _last_pipe=\n                local _this_pipe=\n\n                local __not_query=\n                for   __not_query in \"${_not_queries[@]:-}\"\n                do\n                  [[ -n \"${__not_query:-}\"    ]] || continue\n\n                  _this_pipe=$(_temp file --touch) && {\n                    rm -f   \"${_this_pipe}\"\n                    mkfifo  \"${_this_pipe}\"\n                  }\n\n                  if [[ -p \"${_last_pipe:-}\"  ]]\n                  then\n                    <\"${_last_pipe:-}\" cat\n                  else\n                    cat\n                  fi | {\n                    GIT_PAGER='' xargs \"${_xargs[@]}\" \\\n                      git -C \"${_notebook_path}\"      \\\n                      grep                            \\\n                      --extended-regexp               \\\n                      --files-without-match           \\\n                      --ignore-case                   \\\n                      --null                          \\\n                      --text                          \\\n                      \"${_search_args_no_color[@]:-}\" \\\n                      -e \"${__not_query:-}\"           \\\n                        || return 0  # Don't fail out within a single scope.\n                  } > \"${_this_pipe:-}\" &\n\n                  _last_pipe=\"${_this_pipe:-}\"\n                done\n\n                if [[ -p \"${_last_pipe:-}\"    ]]\n                then\n                  <\"${_last_pipe:-}\" cat\n                else\n                  cat\n                fi\n              } | {\n                if [[ \"${__search_group}\" == \"index\" ]]\n                then\n                  local i=\n                  for ((i=0; i < ${#_queries[@]}; i++))\n                  do\n                    [[ -n \"${_queries[i]:-}\"  ]] || continue\n\n                    if ! ((i))\n                    then\n                      _search_args+=(\"-e\" \"${_queries[i]:-}\")\n                    else\n                      _search_args+=(\"--and\" \"-e\" \"${_queries[i]:-}\")\n                    fi\n                  done\n\n                  GIT_PAGER='' xargs \"${_xargs[@]}\"                     \\\n                    git -C \"${_notebook_path}\"                          \\\n                    grep                                                \\\n                    --extended-regexp                                   \\\n                    --ignore-case                                       \\\n                    --line-number                                       \\\n                    --text                                              \\\n                    \"${_search_args[@]:-}\"                              \\\n                  | LC_ALL=C sed -e \"s/^/${_escaped_notebook_path}\\//\"  \\\n                    || return 0  # Don't fail out within a single scope.\n                else\n                  GIT_PAGER='' xargs \"${_xargs[@]}\"                     \\\n                    git -C \"${_notebook_path}\"                          \\\n                    grep                                                \\\n                    --extended-regexp                                   \\\n                    --ignore-case                                       \\\n                    --line-number                                       \\\n                    --text                                              \\\n                    \"${_search_args[@]:-}\"                              \\\n                    -e \"${_query:-}\"                                    \\\n                  | LC_ALL=C sed -e \"s/^/${_escaped_notebook_path}\\//\"  \\\n                    || return 0  # Don't fail out within a single scope.\n                fi\n              }\n            done\n          fi\n        fi\n      } | {\n        local _binary_match_message_printed=0\n        local _paginated_count=0\n        local _pagination_max=\"$((_page * _limit))\"\n        local _pagination_min=\"$(((_page * _limit) - _limit))\"\n\n        local         __line=\n        while read -r __line\n        do\n          local _content=\n          local _content_line_with_hit=\n          local _file_info=\n          local _file_info_color=\n          local _filename=\n          local _filename_color=\n          local _filename_hit=0\n          local _id=\n          local _line_path_segment=\"${__line%%:*}\"\n          local _path=\n          local _skip=0\n\n          if ((_print_paths))\n          then\n            _path=\"${_line_path_segment:-}\"\n          else\n            # Use `sed` to remove color and 'matches' suffix from output.\n            # https://unix.stackexchange.com/a/140255\n            _path=\"$(\n              printf \"%s\\\\n\" \"${_line_path_segment}\"              \\\n                | LC_ALL=C sed                                    \\\n                    -e \"s,$(printf '\\033')\\\\[[0-9;]*[a-zA-Z],,g\"  \\\n                    -e 's/ matches//g'\n            )\"\n          fi\n\n          if ((_only_list))                       &&\n             [[ \"${_last_path}\" == \"${_path}\" ]]  &&\n             [[ ! \"${_path}\"    =~ .index$    ]]\n          then\n            [[ -n \"${_path}\" ]] && _last_path=\"${_path}\"\n\n            continue\n          fi\n\n          if [[ \"${_path}\"      =~ \\.pindex$  ]]\n          then\n            [[ -n \"${_path}\" ]] && _last_path=\"${_path}\"\n\n            continue\n          fi\n\n          if [[ \"${_last_path}\" != \"${_path}\" ]]\n          then\n            if   [[ ! \"${_path}\" =~ .index    ]] &&\n                 [[ -z \"$(LC_ALL=C sed -E \"${_IGNORE_PATTERNS[@]:-}\" <<< \"${_path##*/}\")\" ]]\n            then\n              _skip=1\n            elif [[ -n \"${_type:-}\"           ]]\n            then\n              if [[  \"${_path}\" =~ ${_type}$  ]]\n              then\n                _skip=0\n              elif {\n                [[ \"${_type}\" =~ (^bookmark$|^bookmarks$)                   ]] &&\n                  _file_is_bookmark \"${_path}\"\n                } || {\n                  [[ \"${_type}\" =~ (^todo$|^todos$|^task$|^tasks$)          ]] &&\n                  _file_is_todo \"${_path}\"\n                } || {\n                  [[ \"${_type}\" =~ (^note$|^notes$)                         ]] &&\n                  _file_is_text \"${_path}\"                                     &&\n                  [[ ! \"${_path:-}\" =~ (.bookmark.md$|-bookmark.md$)        ]]\n                } || {\n                  [[ \"${_type}\" =~ (^folder$|^folders$)                     ]] &&\n                  [[ \"$(dirname \"${_path}\")\" != \"${__target_path}\"          ]]\n                } || {\n                  [[ \"${_type}\" =~ ^archive$                                ]] &&\n                  _file_is_archive \"${_path}\"\n                } || {\n                  [[ \"${_type}\" =~ (^audio$|^music$)                        ]] &&\n                  _file_is_audio \"${_path}\"\n                } || {\n                  [[ \"${_type}\" =~ (^document$|^documents$|^doc$|^docs$)    ]] &&\n                  _file_is_document \"${_path}\"\n                } || {\n                  [[ \"${_type}\" =~ ^encrypted$                              ]] &&\n                  _file_is_encrypted \"${_path}\"\n                } || {\n                  [[ \"${_type}\" =~ (^image$|^images$|^picture$|^pictures$)  ]] &&\n                  _file_is_image \"${_path}\"\n                } || {\n                  [[ \"${_type}\" =~ ^text$                                   ]] &&\n                  _file_is_text \"${_path}\"\n                } || {\n                  [[ \"${_type}\" =~ (^video$|^videos$)                       ]] &&\n                  _file_is_video \"${_path}\"\n                }\n              then\n                _skip=0\n              else\n                _skip=1\n              fi\n            fi\n          fi\n\n          if [[ -z \"${__line}\" ]]\n          then\n            # Print nothing, skipping the blank line in `ag` output with\n            # multiple matches.\n            :\n          elif ((_print_paths))\n          then\n            if [[ \"${_last_path}\" != \"${_path}\"   ]]\n            then # match is in a different file than the last match\n              printf \"%s\\\\n\" \"${_path}\"\n            fi\n          else\n            if ((_skip))\n            then\n              continue\n            fi\n\n            local _folder_path=\"${_path%\\/*}\"\n\n            if [[ ! -e \"${_folder_path}/.index\"   ]]\n            then # skip unindexed folders\n              continue\n            fi\n\n            if ((_limit)) &&\n               {\n                 [[ \"${_last_path}\" != \"${_path}\" ]] ||\n                 [[ \"${_path}\"      =~ \\.index$   ]]\n               }\n            then\n              _paginated_count=$((_paginated_count+1))\n\n              if [[ \"${_paginated_count}\"   -le \"${_pagination_min}\"  ]]\n              then\n                [[ -n \"${_path}\" ]] && _last_path=\"${_path}\"\n\n                continue\n              elif [[ \"${_paginated_count}\" -gt \"${_pagination_max}\"  ]]\n              then\n                break\n              fi\n            fi\n\n            if [[ -n \"${_local_notebook_path:-}\"                ]] &&\n               [[ \"${_folder_path}\" =~ ${_local_notebook_path}  ]]\n            then\n              local _notebook_path=\"${_local_notebook_path}\"\n            else\n              local _notebook_and_folder_path=\"${_folder_path#\"${NB_DIR}\"/}\"\n              local _notebook_path=\"${NB_DIR}/${_notebook_and_folder_path%%/*}\"\n            fi\n\n            local _relative_folder_path=\"${_folder_path#\"${_notebook_path}\"/}\"\n            _relative_folder_path=\"${_relative_folder_path#\"${_notebook_path}\"}\"\n\n            _filename=\"$(basename \"${_path}\")\"\n\n            # normalize filenames with octal escape sequences from git grep\n            _filename=\"$(printf \"%b\\\\n\" \"${_filename}\")\"\n            _filename=\"${_filename%\\\"}\"\n            _filename=\"${_filename#\\\"}\"\n\n            _filename_color=\"${_filename}\"\n\n            # Use \".index\" to match filenames.\n            if [[ -n \"${_filename:-}\" ]] && [[ \"${_filename:-}\" == \".index\" ]]\n            then\n              _filename_hit=1\n              _filename_color=\"$(printf \"%s\\\\n\" \"${__line}\" | cut -d: -f 3-)\"\n              _filename=\"$(\n                printf \"%s\\\\n\" \"${_filename_color}\" \\\n                  | LC_ALL=C sed \"s,$(printf '\\033')\\\\[[0-9;]*[a-zA-Z],,g\"\n              )\"\n            fi\n\n            local _maybe_id_path=\n            local _relative_path=\"${_filename}\"\n\n            if [[ -n \"${_relative_folder_path:-}\" ]]\n            then\n              _max_id=\"$(_index get_max_id \"${_folder_path}\")\"\n              _maybe_id_path=\"${_relative_folder_path}/\"\n              _relative_path=\"${_relative_folder_path}/${_filename}\"\n            fi\n\n            local _normalized_filename=\"${_filename:-}\"\n\n            if _command_exists \"iconv\"\n            then\n              _normalized_filename=\"$(\n                printf \"%s\\\\n\" \"${_filename:-}\" | iconv -c -t utf-8\n              )\"\n            fi\n\n            _id=\"$(_index get_id \"${_normalized_filename}\" \"${_folder_path}\" || :)\"\n\n            if ((_filename_hit))\n            then\n              _content=\"$(_get_content \"${_folder_path}/${_filename}\")\"\n\n              if [[ -n \"${_content}\"                  ]] &&\n                 [[ ! \"${_content}\" =~ ^__first_line: ]]\n              then\n                _file_info=\"${_filename} ${_MD} ${_content}\"\n                _file_info_color=\"${_filename_color} ${_MD} ${_content}\"\n              else\n                _file_info=\"${_filename}\"\n                _file_info_color=\"${_filename_color}\"\n              fi\n            else\n              _content=\"$(_get_content \"${_path}\")\"\n\n              if [[ \"${_content:-}\" =~ ^__first_line: ]]\n              then\n                _file_info=\"${_filename} ${_MD} \\\"${_content#__first_line:}\\\"\"\n                _file_info_color=\"${_filename_color} ${_MD} \\\"${_content#__first_line:}\\\"\"\n              elif [[ -n \"${_content:-}\" ]]\n              then\n                _file_info=\"${_content}\"\n                _file_info_color=\"${_content}\"\n              else\n                _file_info=\"${_filename}\"\n                _file_info_color=\"${_filename_color}\"\n              fi\n            fi\n\n            local _indicators=\n            _indicators=\"$(\n              NB_NOTEBOOK_PATH=\"${_notebook_path}\" \\\n                _show \"${_relative_path}\" --indicators\n            )\"\n\n            local _info_line=\n            local _info_line_color=\n            local _max_identifier=\n\n            if ((_all))                       ||\n               ((_print_notebook_selectors))  ||\n               _notebooks current --selected\n            then\n              local _notebook_name=\n              _notebook_name=\"$(\n                _notebooks show \"${_notebook_path}\" --name --no-color\n              )\"\n\n              _info_line=\"[${_notebook_name}:${_maybe_id_path}${_id}] \"\n              _info_line_color+=\"$(_color_brackets \"${_notebook_name}:${_maybe_id_path}${_id}\") \"\n              _max_identifier=\"[${_notebook_name}:${_maybe_id_path}${_max_id}] \"\n            else\n              _info_line=\"[${_maybe_id_path}${_id}] \"\n              _info_line_color+=\"$(_color_brackets \"${_maybe_id_path}${_id}\") \"\n              _max_identifier=\"[${_maybe_id_path}${_max_id}] \"\n            fi\n\n            # Use calculated number of spaces for nicer formatting.\n            local _spaces=''\n            local _spaces_length=0\n\n            if ((_only_list))\n            then\n              _spaces_length=$(( ${#_max_identifier} - ${#_info_line} ))\n            fi\n\n            if ((_spaces_length))\n            then\n              printf -v _spaces '%*s' \"${_spaces_length}\" \"\"\n\n              _info_line+=\"${_spaces}\"\n              _info_line_color+=\"${_spaces}\"\n            fi\n\n            if [[ -n \"${_indicators:-}\" ]]\n            then\n              _info_line+=\"${_indicators}\"\n              _info_line_color+=\"${_indicators}\"\n            fi\n\n            _info_line+=\"${_file_info}\"\n            _info_line_color+=\"${_file_info_color}\"\n\n            if [[ \"${_last_path}\" != \"${_path}\" ]] || ((_filename_hit))\n            then # match is in a different file than the last match\n              ((_COLOR_ENABLED)) && _wrap off\n\n              printf \"%s\" \"${_info_line_color}\"\n\n              ((_COLOR_ENABLED)) && _wrap on\n\n              printf \"\\\\n\"\n\n              _binary_match_message_printed=0\n            fi\n\n            if ((_only_list)) || ((_binary_match_message_printed))\n            then\n              [[ -n \"${_path}\" ]] && _last_path=\"${_path}\"\n\n              continue\n            fi\n\n            if [[ \"${_last_path}\" != \"${_path}\" ]] || ((_filename_hit))\n            then # match is in a different file than the last match\n              ((_COLOR_ENABLED)) && _wrap off\n\n              local _visible_line_length=\n              _visible_line_length=\"$(\n                _get_visible_length \"${_info_line:-}\"\n              )\"\n\n              _print_line \"$(printf \"%-${_visible_line_length}s\" '.')\"\n\n              ((_COLOR_ENABLED)) && _wrap on\n            fi\n\n            if ((_filename_hit))\n            then\n              local _filename_type_label=\"Filename\"\n\n              if [[ -d \"${_folder_path}/${_filename}\" ]]\n              then\n                _filename_type_label=\"Folder Name\"\n              fi\n\n              _content_line_with_hit=\"${_filename_type_label} Match: $(\n                printf \"%s\\\\n\" \"${__line}\" | cut -d: -f 3-\n              )\"\n            elif ! _file_is_text \"${_folder_path}/${_filename}\"\n            then\n              _content_line_with_hit=\"Binary file matches.\"\n              _binary_match_message_printed=1\n            else\n              _content_line_with_hit=\"$(\n                printf \"%s\\\\n\" \"${__line}\" | cut -d: -f 2-\n              )\"\n            fi\n\n            # Truncate long lines.\n            local _line_length=\n            _line_length=\"$(\n              printf \"%s\\\\n\" \"${_content_line_with_hit}\" | awk '{print length}'\n            )\"\n\n            local _line_length_diff=\n            _line_length_diff=$((_line_length-_max_columns-100))\n\n            if [[ \"${_line_length_diff}\" -gt 0      ]]\n            then\n              _content_line_with_hit=\"$(\n                printf \"%s\\\\n\" \"${_content_line_with_hit}\" \\\n                  | awk '{ print substr($0, 1, 2000) }'\n              )\"\n\n              _content_line_with_hit+=\"$(\n                _color_primary \"... [${_line_length_diff} characters omitted]\"\n              )\"\n            fi\n\n            printf \"%s\\\\n\\\\n\" \"${_content_line_with_hit}\"\n          fi\n\n          [[ -n \"${_path}\" ]] && _last_path=\"${_path}\"\n        done\n      }\n    done\n  } | {\n    local       __search_output_line=\n    if read -r  __search_output_line\n    then # output is present\n      # Print the test line then `cat` the rest.\n      printf \"%s\\\\n\" \"${__search_output_line:-}\"\n\n      cat\n\n      return 0\n    else\n      if ((_all))\n      then\n        printf \"Not found in any notebook: %s\\\\n\"   \\\n          \"$(_color_primary \"${_query:-}\")\"\n      else\n        local _search_selector=\n\n        if [[ -n \"${_selectors[0]:-}\"               ]]\n        then\n          _search_selector=\"${_selectors[0]}\"\n\n          if [[ -f \"${_target_paths[0]:-}\"          ]] &&\n             [[ \"${_search_selector:-}\" =~ /$       ]]\n          then # strip trailing slash from files\n            _search_selector=\"${_search_selector%/}\"\n          elif [[ \"${_search_selector:-}\" =~ :$     ]]\n          then\n            _search_selector=\"${_search_selector%:}\"\n          elif [[ -d \"${_target_paths[0]:-}\"        ]] &&\n               [[ !  \"${_search_selector:-}\" =~ /$  ]]\n          then # add trailing slash to folders\n            _search_selector=\"${_search_selector}/\"\n          fi\n        else\n          _search_selector=\"$(_notebooks current --name)\"\n        fi\n\n        local _query_message=\n\n        if [[ \"${#_queries[@]}\" -le 1 ]]\n        then\n          _query_message=\"${_query}\"\n        else\n          local i=\n          for ((i=0; i < ${#_queries[@]}; i++))\n          do\n            if ((i))\n            then\n              _query_message+=\" + ${_queries[i]:-}\"\n            else\n              _query_message=\"${_queries[i]:-}\"\n            fi\n          done\n        fi\n\n        if [[ \"${_page:-0}\" -gt 1     ]]\n        then\n          return 0\n        else\n          _warn printf \"Not found in %s: %s\\\\n\"               \\\n                  \"$(_color_primary \"${_search_selector:-}\")\" \\\n                  \"$(_color_primary \"${_query_message:-}\")\"\n        fi\n      fi\n\n      return 1\n    fi\n  }\n}\n_alias_subcommand \"search\" \"q\"\n_alias_subcommand \"search\" \"grep\"\n\n# show ################################################################### show\n\n_describe_show() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} show ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[-a | --added] | [--authors] | [-b | --browse] | --filename | --id |\n          --info-line | --path | [-p | --print] | --relative-path | [-r |\n          --render] | --title | --type [<type>] | [-u | --updated]] [--no-color]\n  ${_ME} show <notebook>\n\n$(_color_primary \"Options\"):\n  -a, --added      Print the date and time when the item was added.\n  --authors        List the git commit authors of an item.\n  -b, --browse     Open the item with \\`${_ME} browse\\`.\n  --filename       Print the filename of the item.\n  --id             Print the id number of the item.\n  --info-line      Print the id, filename, and title of the item.\n  --no-color       Show without syntax highlighting.\n  --path           Print the full path of the item.\n  -p, --print      Print to standard output / terminal.\n  --relative-path  Print the item's path relative within the notebook.\n  -r, --render     Use \\`pandoc\\` [1] to render the file to HTML and display\n                   in the terminal web browser. If either \\`pandoc\\` or a\n                   browser are unavailable, \\`-r\\` / \\`--render\\` is ignored.\n  --title          Print the title of the note.\n  --type [<type>]  Print the file extension or, when <type> is specified,\n                   return true if the item matches <type>. <type> can be a\n                   file extension or one of the following types:\n                   archive, audio, bookmark, document, folder, image,\n                   text, video\n  -u, --updated    Print the date and time of the last recorded change.\n\n$(_color_primary \"Description\"):\n  Show an item or notebook. Notes in text file formats can be rendered or\n  printed to standard output. Non-text files are opened in your system's\n  preferred app or program for that file type.\n\n  By default, the item is opened using \\`less\\` or the program configured\n  in the \\`\\$PAGER\\` environment variable. Use the following keys to navigate\n  in \\`less\\` (see \\`man less\\` for more information):\n\n    Key               Function\n    ---               --------\n    mouse scroll      Scroll up or down\n    arrow up or down  Scroll one line up or down\n    f                 Jump forward one window\n    b                 Jump back one window\n    d                 Jump down one half window\n    u                 Jump up one half window\n    /<query>          Search for <query>\n    n                 Jump to next <query> match\n    q                 Quit\n\n  To skip the pager and print to standard output, use the \\`-p\\` / \\`--print\\`\n  option.\n\n  \\`-r\\` / \\`--render\\` automatically uses either \\`w3m\\` [2] or \\`links\\` [3].\n  To specify a preferred browser, set the \\`\\$BROWSER\\` environment variable\n  in your .bashrc, .zshrc, or equivalent, e.g.: export BROWSER=\"links\"\n\n  If \\`bat\\` [5], \\`highlight\\` [6], or Pygments [7] is installed, notes are\n  printed with syntax highlighting.\n\n    1. https://pandoc.org/\n    2. https://en.wikipedia.org/wiki/W3m\n    3. https://en.wikipedia.org/wiki/Links_(web_browser)\n    5. https://github.com/sharkdp/bat\n    6. http://www.andre-simon.de/doku/highlight/en/highlight.php\n    7. https://pygments.org/\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#viewing\n\n$(_color_primary \"See Also\"):\n  ${_ME} help browse\n  ${_ME} help open\n  ${_ME} help peek\n\n$(_color_primary \"Examples\"):\n  ${_ME} show 1\n  ${_ME} show example.md --render\n  ${_ME} show \"A Document Title\" --print --no-color\n  ${_ME} 1 show\n  ${_ME} example:show 12\n  ${_ME} show example:12\n  ${_ME} example:12 show\n  ${_ME} s 1\n  ${_ME} 1 s\n  ${_ME} s example:12\n  ${_ME} example:12 s\n\n$(_color_primary \"Alias\"):\n  ${_ME} view\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} s\nHEREDOC\n}\n_show() {\n  # _show_indicators()\n  #\n  # Usage:\n  #   _show_indicators <path> [--done]\n  #\n  # Description:\n  #   Print a list of indicators based on the file type.\n  #\n  # NOTE: Indicator logic is also specified in `list` for performance.\n  _show_indicators() {\n    local _done=0\n    local _indicators=\n    local _path=\"${1:-}\"\n\n    case \"${2:-}\" in\n      --done) _done=1 ;;\n    esac\n\n    local _pindex_path=\"${_path%/*}/.pindex\"\n\n    if [[ -e \"${_pindex_path}\"  ]]\n    then\n      # shellcheck disable=SC2046\n      if _contains \"${_path##*/}\" $(cat \"${_pindex_path}\")\n      then\n        _indicators+=\"${_NB_INDICATOR_PINNED:-}\"\n      fi\n    fi\n\n    if [[ -d \"${_path}\"         ]]\n    then\n      _indicators+=\"${_NB_INDICATOR_FOLDER:-}\"\n    elif _file_is_bookmark \"${_path}\"\n    then\n      _indicators+=\"${_NB_INDICATOR_BOOKMARK:-}\"\n    elif _file_is_image \"${_path}\"\n    then\n      _indicators+=\"${_NB_INDICATOR_IMAGE:-}\"\n    elif _file_is_document \"${_path}\"\n    then\n      _indicators+=\"${_NB_INDICATOR_DOCUMENT:-}\"\n    elif _file_is_video \"${_path}\"\n    then\n      _indicators+=\"${_NB_INDICATOR_VIDEO:-}\"\n    elif _file_is_audio \"${_path}\"\n    then\n      _indicators+=\"${_NB_INDICATOR_AUDIO:-}\"\n    elif [[ \"${_path}\" =~ \\.epub$ ]]\n    then\n      _indicators+=\"${_NB_INDICATOR_EBOOK:-}\"\n    fi\n\n    if _file_is_encrypted \"${_path}\"\n    then\n      _indicators+=\"${_NB_INDICATOR_ENCRYPTED:-}\"\n    fi\n\n    if _file_is_todo \"${_path}\"\n    then\n      if ((_done))\n      then\n        _indicators+=\"${_NB_INDICATOR_TODO_DONE% } \"\n      else\n        _indicators+=\"${_NB_INDICATOR_TODO% } \"\n      fi\n    fi\n\n    printf \"%s\\\\n\" \"${_indicators:-}\"\n  }\n\n  local _browse=0\n  local _browse_gui=0\n  local _check_type=0\n  local _limit=\"${NB_BROWSE_LIMIT:-20}\"\n  local _list_page=1\n  local _password=\n  local _print_added=0\n  local _print_authors=0\n  local _print_bookmark_url=0\n  local _print_filename=0\n  local _print_folder_path=0\n  local _print_id=0\n  local _print_indicators=0\n  local _print_info=0\n  local _print_output=0\n  local _print_path=0\n  local _print_relative_path=0\n  local _print_selector_id=0\n  local _print_title=0\n  local _print_updated=0\n  local _render=0\n  local _selector=\n  local _skip_notebook_fallback=0\n  local _tool=\n  local _type=\n  local _unresolved_arguments=()\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      -a|--added*|--created*)\n        _print_added=1\n        _skip_notebook_fallback=1\n        ;;\n      --auth*)\n        _print_authors=1\n        ;;\n      -b|--br|--browse)\n        _browse=1\n        ;;\n      --filename|--basename)\n        _print_filename=1\n        _skip_notebook_fallback=1\n        ;;\n      --folder-path)\n        _print_folder_path=1\n        ;;\n      -g|--gui)\n        _browse_gui=1\n        ;;\n      --id|--index)\n        _print_id=1\n        _skip_notebook_fallback=1\n        ;;\n      --indicators)\n        _print_indicators=1\n        _skip_notebook_fallback=1\n        ;;\n      --info*line)\n        _print_info=1\n        _skip_notebook_fallback=1\n        ;;\n      --limit|-n|--num|--number|--per*)\n        _limit=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --no*color|--raw)\n        _COLOR_ENABLED=0\n        ;;\n      --notebook*|--include*notebook*|--with*notebook*)\n        _skip_notebook_fallback=0\n        ;;\n      --page)\n        _list_page=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n        ((_list_page)) || _list_page=1\n\n        shift\n        ;;\n      --password)\n        _password=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --path)\n        _print_path=1\n        _skip_notebook_fallback=1\n        ;;\n      -p|--print|--dump|--skip*pager|--no*pager)\n        _print_output=1\n        ;;\n      --relative-path)\n        _print_relative_path=1\n        _skip_notebook_fallback=1\n        ;;\n      -r|--render)\n        _render=1\n        ;;\n      --selector*id)\n        _print_selector_id=1\n        _skip_notebook_fallback=1\n        ;;\n      --title)\n        _print_title=1\n        _skip_notebook_fallback=1\n        ;;\n      --tool|--utility)\n        _tool=\"$(_option_get_value \"${1}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --type)\n        _check_type=1\n        _skip_notebook_fallback=1\n\n        if _option_value_is_present \"${2:-}\"\n        then\n          _type=\"${2}\"\n\n          shift\n        fi\n        ;;\n      -u|--updated*)\n        _print_updated=1\n        _skip_notebook_fallback=1\n        ;;\n      --url)\n        _print_bookmark_url=1\n        ;;\n      *)\n        if [[ -z \"${_selector:-}\" ]]\n        then\n          _selector=\"${1}\"\n        else\n          _unresolved_arguments+=(\"${1}\")\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  if [[ -z \"${_selector:-}\" ]]\n  then\n    _exit_1 _help \"show\"\n  fi\n\n  if ((_print_selector_id))\n  then\n    _selector_get_identifier \"${_selector:-}\"\n\n    return 0\n  fi\n\n  local _notebook_path=\n\n  if [[ \"${_selector:-}\" =~ : ]] && [[ ! \"${_selector:-}\" =~ /.*: ]]\n  then\n    _notebook_path=\"$(_notebooks show \"${_selector%%:*}\" --path)\" || return 1\n\n    if ((_print_path)) && [[ \"${_selector:-}\" =~ :$ ]]\n    then\n      printf \"%s\\\\n\" \"${_notebook_path}\"\n\n      return 0\n    fi\n  elif [[ \"${_selector:-}\" =~ ^${NB_DIR}  ]]\n  then\n    local _selector_relative_path=\"${_selector#\"${NB_DIR}\"/}\"\n\n    _notebook_path=\"$(_notebooks show \"${_selector_relative_path%%/*}\" --path)\"\n  elif [[ \"${_selector:-}\" =~ ^/          ]]\n  then\n    _notebook_path=\"$(_notebooks show \"${_selector}\" --path)\"\n  fi\n\n  if [[ -z \"${_notebook_path:-}\"          ]]\n  then\n    _notebook_path=\"$(_notebooks current --path)\"\n  fi\n\n  local _relative_path=\n  _relative_path=\"$(\n    _selector_resolve_path \"${_selector}\" \"${_notebook_path}\" --relative\n  )\"\n\n  local _folder_path=\"${_notebook_path:?}\"\n  local _relative_folder_path=\n\n  if [[ \"${_relative_path:-}\" =~ /        ]]\n  then\n    _folder_path=\"${_notebook_path}/${_relative_path%\\/*}\"\n    _relative_folder_path=\"${_relative_path%\\/*}\"\n  fi\n\n  local _basename=\n  _basename=\"$(basename \"${_relative_path}\")\"\n\n  local _target_path=\"${_notebook_path}/${_relative_path}\"\n\n  if [[ -z \"${_relative_path:-}\"    ]] && ! ((_skip_notebook_fallback))\n  then\n    local _maybe_notebook=\"${_selector:-}\"\n\n    if [[ \"${_maybe_notebook:-}\" =~ ^${NB_DIR}    ]]\n    then\n      _maybe_notebook=\"${_maybe_notebook##*\\/}\"\n    fi\n\n    _maybe_notebook=\"${_maybe_notebook%:}\"\n\n    if [[ -d \"${NB_DIR}/${_maybe_notebook}/.git\"  ]]\n    then\n      if ((_print_path))\n      then\n        printf \"%s\\\\n\" \"${NB_DIR}/${_maybe_notebook}\"\n      elif ((_print_relative_path)) || ((_print_folder_path))\n      then\n        printf \"\"\n      else\n        NB_NOTEBOOK_PATH=\"${NB_DIR}/${_maybe_notebook}\" \\\n          _ls \"${_unresolved_arguments[@]:-}\"\n      fi\n\n      return 0\n    else\n      _warn printf \"Not found: %s\\\\n\" \"$(_color_primary \"${_selector}\")\"\n\n      return 1\n    fi\n  fi\n\n  if [[ ! \"${_selector}\" =~ :$      ]] && {\n       [[ -z \"${_relative_path:-}\"  ]] ||\n       [[ ! -e \"${_target_path}\"    ]]\n     }\n  then\n    _warn printf \"Not found: %s\\\\n\" \"$(_color_primary \"${_selector:-}\")\"\n\n    return 1\n  fi\n\n  if ((_print_folder_path))\n  then\n    if [[ \"${_selector:-}\" =~ /$                      ]] &&\n       [[ -d \"${_notebook_path}/${_relative_path:-}\"  ]]\n    then\n      printf \"%s\\\\n\" \"${_relative_path}\"\n    elif [[ \"${_relative_path:-}\" =~ / ]]\n    then\n      printf \"%s\\\\n\" \"${_relative_path%\\/*}\"\n    else\n      printf \"\"\n    fi\n\n    return 0\n  fi\n\n  if ((_print_relative_path))\n  then\n    printf \"%s\\\\n\" \"${_relative_path}\"\n\n    return 0\n  fi\n\n  if ((_print_path))\n  then # `show --path`\n    printf \"%s/%s\\\\n\" \"${_notebook_path}\" \"${_relative_path}\"\n\n    return 0\n  fi\n\n  if ((_print_filename))\n  then\n    printf \"%s\\\\n\" \"${_basename}\"\n\n    return 0\n  fi\n\n  if ((_print_id))\n  then\n    printf \"%s\\\\n\" \"$(\n      _index get_id \"${_relative_path##*/}\" \"${_folder_path}\"\n    )\"\n\n    return 0\n  fi\n\n  if ((_print_title))\n  then\n    _get_content \"${_notebook_path}/${_relative_path}\" --title\n\n    return 0\n  fi\n\n  if ((_print_authors))\n  then\n    GIT_PAGER='' git -C \"${_notebook_path}\" shortlog              \\\n      --summary --email -- \"${_notebook_path}/${_relative_path}\"  \\\n      | LC_ALL=C sed \"s/^[[:space:]]\\{1,\\}[[:digit:]]\\{1,\\}[[:space:]]\\{1,\\}//g\"\n\n    return 0\n  fi\n\n  if ((_print_indicators))\n  then\n    local _indicator_arguments=(\"${_notebook_path}/${_relative_path}\")\n\n    if [[ \"${_relative_path:-}\" =~ todo\\.md ]]\n    then\n      local _todo_title=\n      _todo_title=\"$(\n        _get_content \"${_notebook_path}/${_relative_path}\" --title\n      )\"\n\n      if [[ \"${_todo_title}\" =~ ^\\[x\\]      ]]\n      then\n        _indicator_arguments+=(--done)\n      fi\n    fi\n\n    _show_indicators \"${_indicator_arguments[@]:-}\"\n\n    return 0\n  fi\n\n  if ((_check_type))\n  then\n    if [[ -z \"${_type}\"       ]]\n    then\n      if [[ -d \"${_notebook_path}/${_relative_path}\"  ]]\n      then\n        printf \"%s\\\\n\" \"folder\"\n      else\n        printf \"%s\\\\n\" \"${_relative_path#*.}\"\n      fi\n\n      return 0\n    else\n      if _contains \"${_type}\" \"${_FILE_TYPES[@]:-}\"\n      then\n        \"_file_is_${_type}\" \"${_notebook_path}/${_relative_path}\"\n\n        return $?\n      else\n        [[ \"${_type}\" == \"${_relative_path#*.}\"       ]]\n\n        return $?\n      fi\n    fi\n  fi\n\n  if ((_print_info))\n  then\n    local _id=\n\n    if [[ -n \"${_basename:-}\" ]]\n    then\n      _id=\"$(_index get_id \"${_basename}\" \"${_folder_path}\")\"\n    fi\n\n    local _maybe_scoped_relative_path=\"${_relative_path}\"\n\n    local _maybe_scoped_id=\n    _maybe_scoped_id=\"${_relative_folder_path:+\"${_relative_folder_path}/\"}${_id}\"\n\n    if _notebooks current --selected ||\n       [[ \"${_notebook_path}\" != \"$(_notebooks current --path)\" ]]\n    then\n      local _notebook_name=\n      _notebook_name=\"$(\n        _notebooks show \"${_notebook_path}\" --name --no-color\n      )\"\n\n      _maybe_scoped_id=\"${_notebook_name}:${_maybe_scoped_id}\"\n      _maybe_scoped_relative_path=\"${_notebook_name}:${_maybe_scoped_relative_path}\"\n    fi\n\n    local _info_line=\n    _info_line+=\"$(_color_brackets \"${_maybe_scoped_id}\") \"\n\n    local _indicators=\n    _indicators=\"$(_show \"${_notebook_path}/${_relative_path}\" --indicators)\"\n\n    if [[ -n \"${_indicators:-}\" ]]\n    then\n      _info_line+=\"${_indicators}\"\n    fi\n\n    _info_line+=\"$(_color_primary \"${_maybe_scoped_relative_path}\") \"\n\n    local _title=\n    _title=\"$(_get_content \"${_notebook_path}/${_relative_path}\" --title)\"\n\n    if [[ -n \"${_title:-}\"      ]]\n    then\n      if [[ \"${_relative_path}\"  =~ todo\\.md$ ]] && ((_COLOR_ENABLED))\n      then\n        _title=\"\\\n${_title/\\[x\\]/${_TPUT_SETAF_8}[${_TPUT_COLOR_PRIMARY}x${_TPUT_SETAF_8}]${_TPUT_SGR0}}\"\n        _title=\"\\\n${_title/\\[$' '\\]/${_TPUT_SETAF_8}[ ]${_TPUT_SGR0}}\"\n      fi\n\n      _info_line+=\"\\\"${_title}\\\"\"\n    fi\n\n    # trim leading and trailing whitepace\n    IFS=' ' read -r _info_line <<<\"${_info_line:-}\"\n\n    printf \"%s\\\\n\" \"${_info_line:-}\"\n\n    return 0\n  fi\n\n  if ((_print_added))\n  then\n    git -C \"${_notebook_path}\" --no-pager \\\n      log                                 \\\n      --follow                            \\\n      --diff-filter=A                     \\\n      --date=iso-local                    \\\n      --pretty='%ad'                      \\\n      \"${_relative_path}\"\n\n    return 0\n  fi\n\n  if ((_print_updated))\n  then\n    git -C \"${_notebook_path}\" --no-pager \\\n      log                                 \\\n      -1                                  \\\n      --follow                            \\\n      --date=iso-local                    \\\n      --pretty='%ad'                      \\\n      \"${_relative_path}\"\n\n    return 0\n  fi\n\n  if _file_is_encrypted \"${_target_path}\"\n  then\n    local _encrypted_path=\n    _encrypted_path=\"${_target_path}\"\n\n    local _decryption_tool=\n    _decryption_tool=\"$(_get_decryption_tool \"${_encrypted_path:-}\")\"\n\n    if [[    \"${_decryption_tool:-}\" != \"age\" ]] &&\n       [[ -z \"${_password}\"                   ]]\n    then\n      # request password without displaying it\n      printf \"%s: \" \"$(_color_primary \"Password\")\"\n\n      local _password=\n      IFS='' read -r -e -d $'\\n' -s _password </dev/tty\n\n      if [[ -z \"${_password}\"                 ]]\n      then\n        _exit_1 printf \"Password required.\\\\n\"\n      fi\n    fi\n\n    local _decrypted_path=\n    _decrypted_path=\"$(_decrypt_file \"${_target_path}\" \"${_password}\")\"\n\n    _target_path=\"${_decrypted_path}\"\n  fi\n\n  if ((_print_bookmark_url))\n  then\n    if ! _file_is_bookmark \"${_target_path:-}\"\n    then\n      _warn printf \"%s\\\\n\" \"Not a bookmark.\\\\n\"\n    fi\n\n    local _url_match_patterns=()\n\n    local __url_match_pattern=\n    for   __url_match_pattern in \"${_URL_PATTERNS[@]}\"\n    do\n      _url_match_patterns+=(-e \"<${__url_match_pattern}>\")\n    done\n\n    local _target_url=\n    _target_url=\"$(\n      grep -E                                 \\\n        \"${_url_match_patterns[@]:-}\"         \\\n        \"${_target_path}\"                     \\\n        | head -n 1                           \\\n        | LC_ALL=C sed \"s/^[[:space:]]*<//g\"  \\\n        | LC_ALL=C sed \"s/>[[:space:]]*$//g\"  || :\n    )\"\n\n    if [[ -z \"${_target_url:-}\"       ]]\n    then\n      _warn printf \"No URL found.\\\\n\"\n\n      return 1\n    fi\n\n    printf \"%s\\\\n\" \"${_target_url:-}\"\n\n    return 0\n  fi\n\n  if _file_is_archive \"${_target_path}\"     &&\n     [[ ! \"${_target_path}\" =~ docx$  ]]\n  then\n    _exit_1 printf \"\\\nCan't show archives. Export archive and expand to edit.\\\\n\"\n  fi\n\n  # change directory to folder path to enable relative paths\n  cd \"${_folder_path}\"\n\n  # turn on case-insensitive matching\n  shopt -s nocasematch\n\n  if [[ -z \"${_tool:-}\" ]]                  &&\n     _file_is_image \"${_target_path:-}\"     &&\n     _contains      \"${NB_IMAGE_TOOL:-}\"    \\\n        \"catimg\"                            \\\n        \"chafa\"                             \\\n        \"icat\"                              \\\n        \"imgcat\"                            \\\n        \"magick\"                            \\\n        \"termvisage\"                        \\\n        \"timg\"                              \\\n        \"viu\"\n  then\n    _tool=\"${NB_IMAGE_TOOL:-}\"\n  fi\n\n  if  _contains \"${_target_path##*.}\"        \\\n        \"csv\" \"json\" \"mysql\" \"postgres\"      \\\n        \"sqlite\" \"tab\" \"tar\" \"tsv\" \"usv\" \"vds\" \"xml\" \"xlsx\" \"zip\"     &&\n      _command_exists \"vd\"                                            &&\n      {\n        _contains \"${_tool:-${NB_DATA_TOOL:-vd}}\" \"vd\" \"visidata\"     ||\n        [[  \"${_tool:-${NB_DATA_TOOL:-vd}}\" =~ visidata|vd ]]\n      }\n  then\n    local _visidata_command=\n    IFS=' ' read -ra _visidata_command <<< \"${_tool:-${NB_DATA_TOOL:-vd}}\"\n\n    \"${_visidata_command[@]:-}\" \"${_target_path}\"\n  elif  _contains \"${_target_path##*.}\" \"csv\" \"sc\" \"tab\" \"tsv\" \"xlsx\" &&\n        _command_exists \"sc-im\"                                       &&\n        [[  \"${_tool:-${NB_DATA_TOOL:-sc-im}}\" =~ sc-im ]]\n  then\n    local _sc_im_command=\n    IFS=' ' read -ra _sc_im_command <<< \"${_tool:-${NB_DATA_TOOL:-sc-im}}\"\n\n    \"${_sc_im_command[@]:-}\" \"${_target_path}\"\n  elif  _contains \"${_target_path##*.}\" \"csv\" \"psv\" \"tsv\"             &&\n        _command_exists \"tidy-viewer\"                                 &&\n        {\n          _contains \"${_tool:-${NB_DATA_TOOL:-tidy-viewer}}\" \"tv\" \"tidy-viewer\" \"tidyviewer\" ||\n          [[  \"${_tool:-${NB_DATA_TOOL:-tidy-viewer}}\" =~ tidy-*viewer|tv ]]\n        }\n  then\n    local _tidy_viewer_command=\n    IFS=' ' read -ra _tidy_viewer_command <<< \"${_tool:-${NB_DATA_TOOL:-tidy-viewer}}\"\n\n    \"${_tidy_viewer_command[@]:-}\" \"${_target_path}\"\n  elif ! _file_is_text \"${_target_path}\"    &&\n     ! {\n       ((_render))                          &&\n       [[       \"${_target_path:-}\" =~ (\\.docx$|\\.epub$|\\.odt$) ]]\n     } || [[ -d \"${_target_path:-}\"                             ]]\n  then\n    if [[ -d \"${_target_path}\"  ]]\n    then\n      if [[ -z \"${_tool:-}\"     ]]          &&\n        _contains \"${NB_DIRECTORY_TOOL:-}\"  \\\n          \"joshuto\"                         \\\n          \"lsd\"                             \\\n          \"mc\"                              \\\n          \"exa\"                             \\\n          \"eza\"                             \\\n          \"ranger\"                          \\\n          \"vifm\"                            &&\n        _command_exists \"${NB_DIRECTORY_TOOL:-}\"\n      then\n        _tool=\"${NB_DIRECTORY_TOOL}\"\n      fi\n\n      if [[ -n \"${NB_BROWSE_SERVER_TOOL:-}\" ]]  &&\n         _command_exists \"pandoc\"               &&\n         _web_browser --check                   &&\n         [[ -z \"${_tool:-}\"     ]]\n      then\n        cd \"${_CURRENT_WORKING_DIR}\"\n\n        _defer \"_browse\" \"${_target_path}/\"\n\n        return 0\n      elif _command_exists \"ranger\"   && [[ \"${_tool:-ranger}\"  == \"ranger\"   ]]\n      then\n        ranger \"${_target_path}\"\n      elif _command_exists \"mc\"       && [[ \"${_tool:-mc}\"      == \"mc\"       ]]\n      then\n        mc \"${_target_path}\"\n      elif _command_exists \"vifm\"     && [[ \"${_tool:-vifm}\"    == \"vifm\"     ]]\n      then\n        vifm \"${_target_path}\"\n      elif _command_exists \"joshuto\"  && [[ \"${_tool:-joshuto}\" == \"joshuto\"  ]]\n      then\n        local _joshuto_version=\n        _joshuto_version=\"$(joshuto --version)\"\n        _joshuto_version=\"${_joshuto_version#*-}\"\n\n        local _joshuto_major_minor=\"${_joshuto_version%.*}\"\n\n        if  [[  \"${_joshuto_major_minor%.*}\"  -le \"0\" ]] &&\n            [[  \"${_joshuto_major_minor#*.}\"  -le \"9\" ]] &&\n            [[  \"${_joshuto_version##*.}\"     -lt \"5\" ]]\n        then\n          joshuto --path \"${_target_path}\"\n        else\n          joshuto \"${_target_path}\"\n        fi\n      elif _command_exists \"lsd\"      && [[ \"${_tool:-lsd}\"     == \"lsd\"      ]]\n      then\n        lsd                                       \\\n          -1Al                                    \\\n          --blocks=permission,size,date,git,name  \\\n          --color=always                          \\\n          --date '+%F %R'                         \\\n          --git                                   \\\n          --icon=always                           \\\n          --icon-theme=fancy                      \\\n          --ignore-config                         \\\n          --group-directories-first               \\\n          --size=short                            \\\n          \"${_target_path}\"\n      elif _command_exists \"eza\"      && [[ \"${_tool:-eza}\"     == \"eza\"      ]]\n      then\n        eza                         \\\n          -1labm                    \\\n          --icons                   \\\n          --color=always            \\\n          --color-scale             \\\n          --git                     \\\n          --git-ignore              \\\n          --group-directories-first \\\n          --no-user                 \\\n          --sort=name               \\\n          --time-style=long-iso     \\\n          \"${_target_path}\"\n      elif _command_exists \"exa\"      && [[ \"${_tool:-exa}\"     == \"exa\"      ]]\n      then\n        # TODO: remove in favor of eza\n        exa -lah --git \"${_target_path}\"\n      else\n        # gnu || bsd\n        ls -lah --color=always \"${_target_path}\" 2>/dev/null  ||\n          ls -lah -G \"${_target_path}\"\n      fi\n    elif _command_exists \"termvisage\"     &&\n         _file_is_image \"${_target_path}\" &&\n         [[   \"${_tool:-termvisage}\"  == \"termvisage\" ]]\n    then\n      local _render_style=\"auto\"\n\n      if    [[ -n \"${VIMRUNTIME:-}\"                   ]] ||\n            [[ -n \"${MYVIMRC:-}\"                      ]]\n      then\n        _render_style=\"block\"\n      elif  [[    \"${TERM_PROGRAM:-}\" == \"iTerm.app\"  ]]\n      then\n        _render_style=\"iterm2\"\n      elif  [[ -n \"${KITTY_WINDOW_ID:-}\"              ]]\n      then\n        _render_style=\"kitty\"\n      fi\n\n      termvisage \"${_target_path}\"  \\\n        --cli                       \\\n        --force-style               \\\n        --quiet                     \\\n        --style \"${_render_style}\"  |   {\n        if _command_exists \"less\"   &&  ! ((_print_output))\n        then\n          less -r --prompt=\"$(_less_prompt)\"\n        else\n          cat\n        fi\n      }\n    elif _command_exists \"imgcat\"                     &&\n         _file_is_image \"${_target_path}\"             &&\n         [[ ! \"${_target_path}\"   =~ \\.afphoto$   ]]  &&\n         [[ ! \"${_target_path}\"   =~ \\.svg$       ]]  &&\n         [[   \"${TERM_PROGRAM:-}\" == \"iTerm.app\"  ]]  &&\n         [[   \"${_tool:-imgcat}\"  == \"imgcat\"     ]]\n    then\n      imgcat \"${_target_path}\"    |   {\n        if _command_exists \"less\" &&  ! ((_print_output))\n        then\n          less -r --prompt=\"$(_less_prompt)\"\n        else\n          cat\n        fi\n      }\n    elif _command_exists \"chafa\"                      &&\n         _file_is_image \"${_target_path}\"             &&\n         [[ ! \"${_target_path}\"   =~ \\.afphoto$   ]]  &&\n         [[ ! \"${_target_path}\"   =~ \\.svg$       ]]  &&\n         [[   \"${_tool:-chafa}\"   == \"chafa\"      ]]\n    then\n      chafa \"${_target_path}\"     |   {\n        if _command_exists \"less\" &&  ! ((_print_output))\n        then\n          less -r --prompt=\"$(_less_prompt)\"\n        else\n          cat\n        fi\n      }\n    elif _command_exists \"timg\"                       &&\n         _file_is_image \"${_target_path}\"             &&\n         [[ ! \"${_target_path}\"   =~ \\.afphoto$   ]]  &&\n         [[ ! \"${_target_path}\"   =~ \\.svg$       ]]  &&\n         [[   \"${_tool:-timg}\"    == \"timg\"       ]]\n    then\n      timg \"${_target_path}\"      |   {\n        if _command_exists \"less\" &&  ! ((_print_output))\n        then\n          less -r --prompt=\"$(_less_prompt)\"\n        else\n          cat\n        fi\n      }\n    elif _command_exists \"viu\"                        &&\n         _file_is_image \"${_target_path}\"             &&\n         [[   \"${_tool:-viu}\"  == \"viu\"           ]]\n    then\n      viu \"${_target_path}\"\n    elif _command_exists \"catimg\"                     &&\n         _file_is_image \"${_target_path}\"             &&\n         [[   \"${_tool:-catimg}\"  == \"catimg\"     ]]\n    then\n      catimg \"${_target_path}\"\n    elif _command_exists \"magick\"                     &&\n         _file_is_image \"${_target_path}\"             &&\n         [[ ! \"${_target_path}\"   =~ afphoto$     ]]  &&\n         {\n           # Detect sixel support. Via: https://git.io/JfCel\n           local __reply=\n           IFS=\";\" read -ra __reply -s -t 1 -d \"c\" -p $'\\e[c' >&2\n\n           [[ \"${__reply[*]}\"     =~ 4            ]]  ||\n           [[ \"$TERM\"             == yaft*        ]]\n         } && {\n           [[ \"${_tool:-magick}\"  == \"magick\"     ]]\n         }\n    then\n      magick \"${_target_path}\" sixel:-  | {\n        if _command_exists \"less\" &&    ! ((_print_output))\n        then\n          less -r --prompt=\"$(_less_prompt)\"\n        else\n          cat\n        fi\n      }\n    elif [[ -n  \"${KITTY_WINDOW_ID:-}\"            ]]  &&\n         _file_is_image \"${_target_path}\"             &&\n         [[     \"${_tool:-icat}\"  == \"icat\"       ]]\n    then\n      kitty +kitten icat \"${_target_path}\"  | {\n        if _command_exists \"less\" &&  ! ((_print_output))\n        then\n          less -r --prompt=\"$(_less_prompt)\"\n        else\n          cat\n        fi\n      }\n    elif ((${NB_VIDEO_TO_ASCII_ENABLED:-0}))          &&\n         _command_exists \"video-to-ascii\"             &&\n         _file_is_video \"${_target_path:-}\"           &&\n         [[ \"${_tool:-\"video-to-ascii\"}\" == \"video-to-ascii\"        ]]\n    then # https://github.com/joelibaceta/video-to-ascii\n      video-to-ascii -f \"${_target_path:-}\"\n    elif _command_exists \"mplayer\"                    &&\n         _file_is_audio \"${_target_path}\"             &&\n         [[ \"${_tool:-${NB_AUDIO_TOOL:-mplayer}}\"   == \"mplayer\"    ]]\n    then\n      printf \"Playing audio. Press %s to quit.\\\\n\" \"$(_color_primary \"Ctrl-C\")\"\n      mplayer \"${_target_path}\"\n    elif _command_exists \"afplay\"                     &&\n         _file_is_audio \"${_target_path}\"             &&\n         [[ \"${_tool:-${NB_AUDIO_TOOL:-afplay}}\"      == \"afplay\"   ]]\n    then\n      printf \"Playing audio. Press %s to quit.\\\\n\" \"$(_color_primary \"Ctrl-C\")\"\n      afplay \"${_target_path}\"\n    elif _command_exists \"mpg123\"                     &&\n         _file_is_audio \"${_target_path}\"             &&\n         [[ \"${_tool:-afplay}\"    == \"afplay\"     ]]  &&\n         [[ \"${_target_path}\"     =~ mp[(1|2|3)]$ ]]  &&\n         [[ \"${_tool:-${NB_AUDIO_TOOL:-mpg123}}\"      == \"mpg123\"   ]]\n    then\n      printf \"Playing audio. Press %s to quit.\\\\n\" \"$(_color_primary \"Ctrl-C\")\"\n      mpg123 \"${_target_path}\"\n    elif _command_exists \"ffplay\"                     &&\n         _file_is_audio \"${_target_path}\"             &&\n         [[ \"${_tool:-${NB_AUDIO_TOOL:-ffplay}}\"      == \"ffplay\"   ]]\n    then\n      printf \"Playing audio. Press %s to quit.\\\\n\" \"$(_color_primary \"Ctrl-C\")\"\n      ffplay -loglevel quiet \"${_target_path}\"\n    elif _command_exists \"termpdf.py\"                 &&\n         [[     \"${_target_path}\" =~ pdf$         ]]  &&\n         [[ -n  \"${KITTY_WINDOW_ID:-}\"            ]]  &&\n         _contains \"${_tool:-termpdf.py}\" \"termpdf.py\" \"termpdf\"\n    then\n      termpdf.py \"${_target_path}\"\n    elif _command_exists \"pdftotext\"                  &&\n         [[     \"${_target_path}\" =~ pdf$         ]]  &&\n         [[ \"${_tool:-pdftotext}\" == \"pdftotext\"  ]]\n    then\n      pdftotext \"${_target_path}\" - | tr -d '\\014'  | {\n        if ! ((_print_output))\n        then\n          _pager\n        else\n          cat\n        fi\n      }\n    elif [[ \"${_target_path}\" =~ docx$  ]]  &&\n         _command_exists \"pandoc\"\n    then\n      pandoc                                \\\n        --from  docx                        \\\n        --to    markdown                    \\\n        \"${_target_path}\"                   \\\n        | LC_ALL=C sed -E                   \\\n          -e 's/\\\\\\[\\\\\\[/\\[\\[/g'            \\\n          -e 's/\\\\\\]\\\\\\]/\\]\\]/g'            \\\n          | _highlight_syntax_if_available  \\\n          | if ! ((_print_output))\n            then\n              _pager\n            else\n              cat\n            fi\n    elif [[ \"${_target_path}\" =~ epub$  ]]  &&\n         _command_exists \"pandoc\"           &&\n         _web_browser --check\n    then\n      pandoc          \\\n        --from  epub  \\\n        --to    html  \\\n        \"${_target_path}\" | _web_browser\n    elif _open_in_gui_app \"${_target_path:-}\"\n    then\n      return 0\n    else\n      _exit_1 printf                                \\\n        \"%s doesn't know how to show this item.\\\\n\" \\\n        \"$(_color_primary \"${_ME}\")\"\n    fi\n  else # file is text\n    if ((_browse))                              &&\n         [[ -n \"${NB_BROWSE_SERVER_TOOL:-}\" ]]  &&\n         _command_exists \"pandoc\"               &&\n         _web_browser --check\n    then\n      cd \"${_CURRENT_WORKING_DIR}\"\n\n      local _browse_arguments=(\"${_target_path}\")\n      ((_print_output)) && _browse_arguments+=(\"--print\")\n      ((_browse_gui))   && _browse_arguments+=(\"--gui\")\n\n      _defer \"_browse\" \"${_browse_arguments[@]:-}\"\n\n      return 0\n    elif ((_render))                &&\n         _command_exists \"pandoc\"   &&\n         _web_browser --check\n    then\n      local _rendered_temp_file_path=\n      _rendered_temp_file_path=\"$(_temp file \".html\" --touch)\"\n\n      if [[ \"${_target_path:-}\" =~ (\\.asciidoc$|\\.adoc$)    ]]  &&\n         _file_is_text \"${_target_path:-}\"                      &&\n         _command_exists \"asciidoctor\"\n      then\n        {\n          asciidoctor           \\\n            -o -                \\\n            --no-header-footer  \\\n            \"${_target_path:-}\"\n        } | {\n          _resolve_links \"${_notebook_path}\"\n        } | {\n          _render\n        } | {\n          cat >> \"${_rendered_temp_file_path}\"\n        }\n      elif [[ \"${_target_path}\" =~ \\.org                    ]]\n      then # resolve Org [[wiki-style links]] before rendering to HTML\n        {\n          cat \"${_target_path}\"\n        } | {\n          _resolve_links \"${_notebook_path}\" --type org\n        } | {\n          # avoid pandoc bug with brackets in Org link descriptions\n          LC_ALL=C sed -E                                   \\\n            -e \"s/\\]\\[\\[\\[/\\]\\[${_ME}-placeholder-${_ME}/g\" \\\n            -e \"s/\\]\\]\\]\\]/${_ME}-placeholder-${_ME}\\]\\]/g\"\n        } | {\n          _pandoc --standard-input --from org --to html\n        } | {\n          LC_ALL=C sed -E                                   \\\n            -e \"s/>${_ME}-placeholder-${_ME}/>\\[\\[/g\"       \\\n            -e \"s/${_ME}-placeholder-${_ME}</\\]\\]</g\"\n        } | {\n          _render\n        } | {\n          cat >> \"${_rendered_temp_file_path}\"\n        }\n      else\n        {\n          _render \"${_target_path}\" --pandoc --body\n        } | {\n          if [[ \"${_target_path}\" =~ \\.bookmark\\.md ]]\n          then\n            _resolve_links \"${_notebook_path}\" --bookmark\n          else\n            _resolve_links \"${_notebook_path}\"\n          fi\n        } | {\n          _render\n        } | {\n          cat >> \"${_rendered_temp_file_path}\"\n        }\n      fi\n\n      if ((_print_output))\n      then\n        if ((_COLOR_ENABLED))\n        then\n          cat \"${_rendered_temp_file_path}\" | _web_browser --dump\n        else\n          cat \"${_rendered_temp_file_path}\"\n        fi\n      elif _web_browser --gui\n      then\n        (_web_browser \"file://${_rendered_temp_file_path:-}\") &\n\n        printf \"Serving: %s\\\\n\" \"$(_color_primary \"${_rendered_temp_file_path}\")\"\n\n        while true\n        do\n          read -n 1 -s -r -p \"Press any key to quit$(_color_muted \"...\")\"\n\n          printf \"\\\\n\"\n\n          exit 0\n        done\n      else\n        _web_browser \"file://${_rendered_temp_file_path:-}\"\n      fi\n\n      rm -f \"${_rendered_temp_file_path:?}\"\n    else # default\n      if ((_print_output))\n      then # `show --print [--no-color]`\n        if ((_COLOR_ENABLED))\n        then # `show --print`\n          _highlight_syntax_if_available \"${_target_path}\"\n        else # `show --print --no-color`\n          cat \"${_target_path}\"\n        fi\n      else # `show`\n        local _target_extension=\n        local _target_filename=\"${_target_path##*/}\"\n\n        if [[ \"${_target_filename:-}\" =~ \\. ]]\n        then\n          _target_extension=\"${_target_filename##*.}\"\n        fi\n\n        {\n          cat \"${_target_path}\"\n        } | {\n          local _markdown_tool=\"${_tool:-${NB_MARKDOWN_TOOL:-}}\"\n\n          if _contains \"${_target_extension:-}\" \"markdown\" \"md\" &&\n             [[ ! \"${_markdown_tool:-}\" =~ \\                 ]] &&\n             _command_exists \"${_markdown_tool:-}\"              &&\n             _contains \"${_markdown_tool:-}\"                    \\\n               \"bat\"                                            \\\n               \"batcat\"                                         \\\n               \"glow\"                                           \\\n               \"lowdown\"                                        \\\n               \"mdcat\"                                          \\\n               \"mdless\"                                         \\\n               \"mdv\"\n          then\n            case \"${_markdown_tool:-}\" in\n              bat|batcat)\n                _bat --language \"${_target_extension:-md}\"\n                ;;\n              glow)\n                glow --tui\n                ;;\n              lowdown)\n                lowdown                         \\\n                  -Tterm                        \\\n                  --term-columns=\"${_COLUMNS}\"  \\\n                  --term-width=\"${_COLUMNS}\"    \\\n                  | _pager\n                ;;\n              mdcat)\n                mdcat --paginate\n                ;;\n              mdless)\n                mdless\n                ;;\n              mdv)\n                mdv \"${_target_path}\" | _pager\n                ;;\n            esac\n          elif _contains \"${_target_extension:-}\" \"markdown\" \"md\" &&\n               [[ \"${_markdown_tool:-}\" =~ \\                      ]]\n          then\n            local _markdown_command=\n\n            IFS=' ' read -r -a _markdown_command <<< \"${_markdown_tool:-}\"\n\n            \"${_markdown_command[@]}\" \"${_target_path}\"\n          else\n            {\n              # fold to current terminal width and preserve list formatting\n              LC_ALL=C sed -E                                    \\\n                  -e \"s/^([[:space:]]*-) /\\1${_ME}-ph-${_ME}/g\"  \\\n                  -e \"s/^([[:space:]]*\\*) /\\1${_ME}-ph-${_ME}/g\" \\\n              | LC_ALL=C fold -s -w \"${_COLUMNS}\"                \\\n              | LC_ALL=C sed -E                                  \\\n                  -e \"s/^([[:space:]]*-)${_ME}-ph-${_ME}/\\1 /g\"  \\\n                  -e \"s/^([[:space:]]*\\*)${_ME}-ph-${_ME}/\\1 /g\"\n            } | {\n              _highlight_syntax_if_available \"${_target_extension:-}\"\n            } | {\n              _pager\n            }\n          fi\n        }\n      fi\n    fi\n  fi\n\n  # turn off case-insensitive matching\n  shopt -u nocasematch\n\n  if [[ -n \"${_decrypted_path:-}\" ]] && [[ -e \"${_decrypted_path}\" ]]\n  then\n    rm \"${_decrypted_path:?}\"\n  fi\n}\n_alias_subcommand \"show\" \"s\"\n_alias_subcommand \"show\" \"view\"\n\n# unpin ################################################################# unpin\n\n_describe_unpin() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} unpin ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\n$(_color_primary \"Description\"):\n  Unpin a pinned item.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-pinning\n\n$(_color_primary \"See Also\"):\n  ${_ME} help browse\n  ${_ME} help list\n  ${_ME} help ls\n  ${_ME} help pin\n\n$(_color_primary \"Examples\"):\n  ${_ME} unpin 123\n  ${_ME} unpin example:sample/321\nHEREDOC\n}\n_unpin() {\n  _pin unpin \"${@:-}\"\n}\n\n# use ##################################################################### use\n\n_describe_use() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} use <notebook>\n\n$(_color_primary \"Description\"):\n  Switch to the specified notebook. Shortcut for \\`${_ME} notebooks use\\`.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-notebooks\n\n$(_color_primary \"See Also\"):\n  ${_ME} help notebooks\n\n$(_color_primary \"Example\"):\n  ${_ME} use example\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} u\nHEREDOC\n}\n_use() {\n  local _name=\"${1:-}\"\n  if [[ -z \"${_name}\" ]]\n  then\n    _exit_1 _help use\n  fi\n  _notebooks use \"${_name}\"\n}\n_alias_subcommand \"use\" \"u\"\n\n# version ############################################################# version\n\n_describe_version() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} version\n\n$(_color_primary \"Description\"):\n  Display version information.\n\n$(_color_primary \"See Also\"):\n  ${_ME} help env\n  ${_ME} help update\nHEREDOC\n}\n_version() {\n  printf \"%s\\\\n\" \"${_VERSION}\"\n}\n\n###############################################################################\n# Call Deferred Command: Group 2                 Call Deferred Command: Group 2\n###############################################################################\n# --------------------------------------------------------------------------- #\n\n_call_deferred_command --group 2\n\n###############################################################################\n# Subcommands: Group 3                                     Subcommands: Group 3\n# --------------------                                     --------------------\n###############################################################################\n# --------------------------------------------------------------------------- #\n\n# archive ############################################################# archive\n\n_describe_archive() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} archive [<name>]\n\n$(_color_primary \"Description\"):\n  Set the current notebook or notebook <name> to \"archived\" status.\n\n  This is an alias for \\`${_ME} notebooks archive\\`.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#archiving-notebooks\n\n$(_color_primary \"See Also\"):\n  ${_ME} help notebooks\n  ${_ME} help status\n  ${_ME} help unarchive\n\n$(_color_primary \"Examples\"):\n  ${_ME} archive\n  ${_ME} archive example\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} ar\nHEREDOC\n}\n_archive() {\n  _notebooks archive \"${@:-}\"\n}\n_alias_subcommand \"archive\" \"ar\"\n\n# browse ############################################################### browse\n\n_describe_browse() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} browse [<notebook>:][<folder-path>/][<id> | <filename> | <title>] [--daemon]\n            [-g | --gui] [-n | --notebooks] [-p | --print] [-q | --query <query>]\n            [-s | --serve] [-t <tag> | --tag <tag> | --tags <tag1>,<tag2>...]\n  ${_ME} browse add [<notebook>:][<folder-path>/][<filename>]\n            [-c <content> | --content <content>] [--tags <tag1>,<tag2>...]\n            [-t <title> | --title <title>]\n  ${_ME} browse delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} browse edit ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\n$(_color_primary \"Subcommands\"):\n  (default)  Open a notebook, folder, or item in the terminal or GUI web browser.\n  add        Open the add view in the browser.\n             Shortcut Aliases: \\`a\\`, \\`+\\`\n  delete     Open the delete view in the browser.\n             Shortcut Aliases: \\`d\\`, \\`-\\`\n  edit       Open the edit view in the browser.\n             Shortcut Alias:   \\`e\\`\n\n$(_color_primary \"Options\"):\n  -c, --content <content>      Add content to the new note.\n  --daemon                     Start the web server. Close with <CTRL-C>.\n  -g, --gui                    Open in the system's primary GUI web browser.\n  -n, --notebooks              Browse notebooks.\n  -p, --print                  Print to standard output.\n  -q, --query <query>          Open to the search results for <query>.\n  -s, --serve                  Start the web server. Close with any key.\n  -t, --tag <tag>              Search for a tag.\n  --tags <tag1>,<tag2>...      A comma-separated list of tags.\n  -t, --title <title>          Add a title to the new note.\n\n$(_color_primary \"Description\"):\n  Browse, view, and edit linked notes, bookmarks, notebooks, folders, and\n  other items using terminal and GUI web browsers.\n\n  \\`browse\\` includes an embedded web application designed for terminal\n  and GUI web browsers that renders [[wiki-style links]] and #tags as\n  internal links, providing the ability to browse notes and notebooks,\n  as well as seamlessly browse to and from the offsite links in\n  bookmarks and notes.\n\n  To link to a note or bookmark from another, include the selector for the\n  target item within double square brackets anywhere in the linking document:\n\n    # link to item 123 in the \"sample\" folder in the \"example\" notebook\n    [[example:sample/123]]\n\n    # link to the item titled \"Example Title\" in the \"demo\" notebook\n    [[demo:Example Title]]\n\n  \\`browse\\` supports \\`w3m\\` [1] and \\`links\\` [2], and depends on\n  \\`ncat\\` [3] or \\`socat\\` [4] and \\`pandoc\\` [5]:\n\n    1. https://en.wikipedia.org/wiki/W3m\n    2. https://en.wikipedia.org/wiki/Links_(web_browser)\n    3. https://nmap.org/ncat/\n    4. https://www.kali.org/tools/socat/\n    5. https://pandoc.org/\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-browsing\n\n$(_color_primary \"See Also\"):\n  ${_ME} help add\n  ${_ME} help delete\n  ${_ME} help edit\n  ${_ME} help list\n  ${_ME} help ls\n  ${_ME} help open\n  ${_ME} help peek\n  ${_ME} help pin\n  ${_ME} help search\n  ${_ME} help show\n  ${_ME} help unpin\n\n$(_color_primary \"Examples\"):\n  ${_ME} browse\n  ${_ME} browse example:\n  ${_ME} browse Example\\ Folder/\n  ${_ME} browse 123\n  ${_ME} browse demo:456\n  ${_ME} br\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} b\nHEREDOC\n}\n_browse() {\n  # Inspired by bashttpd: https://github.com/avleen/bashttpd\n\n  # _browse_http_response_message()\n  #\n  # Usage:\n  #   _browse_http_response_message <status-code>\n  #\n  # Description:\n  #   Print the response message for a given status code.\n  _browse_http_response_message() {\n    local _status_code=\"${1:-}\"\n\n    case \"${_status_code}\" in\n      200) printf \"OK\\\\n\"                     ;;\n      302) printf \"Found\\\\n\"                  ;;\n      400) printf \"Bad Request\\\\n\"            ;;\n      403) printf \"Forbidden\\\\n\"              ;;\n      404) printf \"Not Found\\\\n\"              ;;\n      405) printf \"Method Not Allowed\\\\n\"     ;;\n      415) printf \"Unsupported Media Type\\\\n\" ;;\n      500) printf \"Internal Server Error\\\\n\"  ;;\n    esac\n  }\n\n  # _browse_item_create()\n  #\n  # Usage:\n  #   _browse_item_create <container-path> --message-body <message-body>\n  #\n  # Description:\n  #   Add a new item in the folder or notebook at <container-path>.\n  _browse_item_create() {\n    local _message_body=\n    local _selector=\n    local _subcommand_options=()\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --col*|--limit|--local|--page|-n|--num|--number|--per*)\n          _option_value_is_present \"${2:-}\" && shift\n          ;;\n        --message*body)\n          _message_body=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n          shift\n          ;;\n        --terminal)\n          :\n          ;;\n        *)\n          if [[ -z \"${_selector:-}\" ]]\n          then\n            _selector=\"${1:-}\"\n          else\n            _subcommand_options+=(\"${1:-}\")\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    if [[ -z \"${_selector:-}\"       ]]\n    then\n      _browse_respond_with 404\n    fi\n\n    local _notebook_path=\n    _notebook_path=\"$(\n      _notebooks show \"${_selector:-}\" --path 2>/dev/null ||\n        _notebooks current --path\n    )\"\n\n    local _fields=()\n    IFS='&' read -r -a _fields <<< \"${_message_body}\"\n\n    local _add_options=()\n    local _prepared_encoded_content=\n\n    local __field=\n    for   __field in \"${_fields[@]:-}\"\n    do\n      case \"${__field:-}\" in\n        content=*)\n          _prepared_encoded_content=\"${__field#content=}\"\n          _prepared_encoded_content=\"${_prepared_encoded_content//+/ }\"\n          _prepared_encoded_content=\"${_prepared_encoded_content//%/\\\\x}\"\n          ;;\n        *)\n          if [[ \"${__field:-}\" =~ \\= ]]\n          then\n            _add_options+=(\"${__field%%=*}\")\n\n            local _value=\n            _value=\"$(_get_uri --decode \"${__field#*=}\")\"\n            _value=\"${_value//$'\\r'}\"\n\n            _add_options+=(\"${_value:-}\")\n          else\n            _add_options+=(\"${__field:-}\")\n          fi\n          ;;\n      esac\n    done\n\n    if [[   -n \"${_prepared_encoded_content:-}\" ]]\n    then\n      if [[ -n \"${_selector:-}\"                 ]]\n      then\n        _add_options=(\"${_selector:-}\" \"${_add_options[@]:-}\")\n      fi\n\n      _add_options=(\"--no-color\" \"${_add_options[@]:-}\")\n\n      local _new_info_line=\n      _new_info_line=\"$(\n        _add \"${_add_options[@]:-}\" --content \"$(\n          printf \"%b\\\\n\" \"${_prepared_encoded_content:-}\" \\\n            | tr -d $'\\r'\n        )\" --skip-standard-input\n      )\"\n\n      local _new_selector=\"${_new_info_line#*[}\"\n      _new_selector=\"${_new_selector%%]*}\"\n      _new_selector=\"${_new_selector//'\\ '/ }\"\n\n      printf \"%s\\\\n\" \"${_new_selector}\"\n    fi\n  }\n\n  # _browse_item_delete()\n  #\n  # Usage:\n  #   _browse_item_delete <path>\n  #\n  # Description:\n  #   Delete the item at <path>.\n  _browse_item_delete() {\n    local _source_path=\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --col*|--limit|--local|-n|--num|--number|--page|--per*|--raw-url)\n          _option_value_is_present \"${2:-}\" && shift\n          ;;\n        --terminal)\n          :\n          ;;\n        *)\n          _source_path=\"${1:-}\"\n          ;;\n      esac\n\n      shift\n    done\n\n    [[ -z \"${_source_path:-}\" ]] && _browse_respond_with 404\n\n    _delete \"${_source_path:-}\" --force\n  }\n\n  # _browse_item_update()\n  #\n  # Usage:\n  #   _browse_item_update <path> --message-body <message-body>\n  #\n  # Description:\n  #   Update the content of item at <path>.\n  _browse_item_update() {\n    local _message_body=\n    local _source_path=\n    local _subcommand_options=()\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --col*|--limit|--local|-n|--num|--number|--page|--per*|--raw-url)\n          _option_value_is_present \"${2:-}\" && shift\n          ;;\n        --message*body)\n          _message_body=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n          shift\n          ;;\n        --terminal)\n          :\n          ;;\n        *)\n          if [[ -z \"${_source_path:-}\" ]] && [[ \"${1:-}\" =~ ^/ ]]\n          then\n            _source_path=\"${1:-}\"\n          else\n            _subcommand_options+=(\"${1:-}\")\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    if [[ -z \"${_source_path:-}\" ]]\n    then\n      _browse_respond_with 404\n    fi\n\n    local _notebook_path=\n    _notebook_path=\"$(\n      _notebooks show \"${_source_path:-}\" --path 2>/dev/null ||\n        _notebooks current --path\n    )\"\n\n    if [[ \"${_message_body:-}\" =~ ^content= ]]\n    then\n      local _prepared_encoded_content=\"${_message_body#content=}\"\n      _prepared_encoded_content=\"${_prepared_encoded_content//+/ }\"\n      _prepared_encoded_content=\"${_prepared_encoded_content//%/\\\\x}\"\n\n      printf \"%b\\\\n\" \"${_prepared_encoded_content:-}\" \\\n        | tr -d $'\\r'                                 \\\n        > \"${_source_path}\"\n\n      _git checkpoint \"${_notebook_path}\"             \\\n        \"[${_ME}] Edit: ${_source_path#\"${_notebook_path}\"/}\"\n    fi\n  }\n\n  # _browse_render_add()\n  #\n  # Usage:\n  #   _browse_render_add [--columns <columns>] [--content <content>]\n  #                      [--limit <limit>] [--local <url-encoded-path>]\n  #                      [--tags <tag-list>] [--terminal] [--title <title>]\n  #                      [--type <type>] [<add-option>...]\n  #\n  # Description:\n  #   Print an HTML page for creating a text file.\n  _browse_render_add() {\n    local _columns=\"${NB_BROWSE_COLUMNS:-70}\"\n    local _content=\n    local _encoded_local_notebook_path=\n    local _limit=\"${NB_BROWSE_LIMIT:-30}\"\n    local _pagination_options=()\n    local _selector=\n    local _subcommand_options=()\n    local _tag_list=\n    local _target_type=\n    local _title=\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --col*)\n          _columns=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        -c|--content)\n          _content=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n          shift\n          ;;\n        --limit|-n|--num|--number|--per*)\n          _limit=\"${2:?}\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --local)\n          _encoded_local_notebook_path=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --page)\n          _option_value_is_present \"${2:-}\" && shift\n          ;;\n        --tags)\n          _tag_list=\"$(_option_get_tags \"${1:-}\" \"${2:-}\")\"\n\n          shift\n          ;;\n        --terminal)\n          _pagination_options+=(\"--terminal\")\n          ;;\n        -t|--title)\n          _title=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n          shift\n          ;;\n        --type)\n          _target_type=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _subcommand_options+=(\"${1:-}\" \"${2:-}\")\n\n          shift\n          ;;\n        --*)\n          _subcommand_options+=(\"${1:-}\")\n\n          if _option_value_is_present \"${2:-}\"\n          then\n            _subcommand_options+=(\"${2:-}\")\n\n            shift\n          fi\n          ;;\n        -*)\n          _subcommand_options+=(\"${1:-}\")\n          ;;\n        *)\n          if [[ -z \"${_selector:-}\" ]]\n          then\n            _selector=\"${1:-}\"\n          else\n            _subcommand_options+=(\"${1:-}\")\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    if [[ \"${_selector:-}\" =~ ^/    ]] &&\n       [[ -d \"${_selector}\"         ]]\n    then # file already exists\n      _browse_respond_with 302 \\\n\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/$(_get_id_selector \"${_selector:-}\"  --notebook)\"\n    elif [[ -n \"${_selector:-}\"     ]]\n    then\n      local _notebook_name=\n      _notebook_name=\"$(\n        _notebooks show \"${_selector:-}\" --name 2>/dev/null ||\n          _notebooks current --name\n      )\"\n\n      if [[ ! \"${_selector:-}\" =~ : ]]\n      then\n        _selector=\"${_notebook_name}:${_selector:-}\"\n      fi\n    fi\n\n    local _html_title=\"${_ME} browse add ${_selector// /\\\\ }\"\n    local _rows=30\n    local _text_area_columns=\"${_columns:-}\"\n    local _url_params=\n\n    if _contains \"--terminal\" \"${_pagination_options[@]:-}\"\n    then\n      _url_params+=\"&--columns=${_columns}\"\n      _text_area_columns=\"$((_text_area_columns - 3))\"\n\n      _url_params+=\"&--limit=${_limit}\"\n      _rows=\"$((_limit + 2))\"\n    fi\n\n    if [[ \"${_target_type:-not-folder}\" != \"folder\" ]]\n    then\n      _target_type=\"${NB_DEFAULT_EXTENSION:-}\"\n    fi\n\n    if [[ -n \"${_encoded_local_notebook_path:-}\"    ]]\n    then\n      _url_params+=\"&--local=${_encoded_local_notebook_path}\"\n    fi\n\n    local _form_content=\n\n    if [[ -n  \"${_title:-}\"                 ]]\n    then\n      if [[   \"${_target_type:-}\" == \"org\"  ]]\n      then\n        _form_content+=\"#+TITLE: ${_title}${_NEWLINE}\"\n      else\n        _form_content+=\"# ${_title}${_NEWLINE}\"\n      fi\n    fi\n\n    if [[ -n \"${_tag_list:-}\"     ]]\n    then\n      [[ -n \"${_form_content:-}\"  ]] && _form_content+=\"${_NEWLINE}\"\n\n      _form_content+=\"${_tag_list:-}${_NEWLINE}\"\n    fi\n\n    if [[ -n \"${_content:-}\"      ]]\n    then\n      [[ -n \"${_form_content:-}\"  ]] && _form_content+=\"${_NEWLINE}\"\n\n      _form_content+=\"${_content:-}${_NEWLINE}\"\n    fi\n\n    {\n      # TODO: https://stackoverflow.com/a/15844977\n      cat <<HEREDOC\n<form\n  accept-charset=\"UTF-8\"\n  action=\"/${_selector//' '/%20}?--add${_url_params:-}\"\n  method=\"post\">\n<textarea\n  class=\"content\"\n  cols=\"${_text_area_columns}\"\n  id=\"content\"\n  name=\"content\"\n  rows=\"${_rows}\">${_form_content:-}</textarea>\n<br><br>\n<input\n  type=\"submit\"\n  value=\"add\">\n$(_browse_render_option_fields \"${_subcommand_options[@]:-}\")\n</form>\nHEREDOC\n    } | {\n      printf \"%s\\\\n\" \"$(\n        _browse_render_header           \\\n          \"${_selector}\"                \\\n          \"${_pagination_options[@]:-}\" \\\n          --add\n      )\"\n\n      printf \"<div class=\\\"main\\\">\\\\n\"\n\n      cat\n\n      printf \"</div>\\\\n\"\n    } | {\n      _render                                             \\\n        --source-extension \"${NB_DEFAULT_EXTENSION:-md}\"  \\\n        --title \"${_html_title}\"\n    }\n  }\n\n  # _browse_render_container()\n  #\n  # Usage:\n  #   _browse_render_container <target-path> [--columns <columns>]\n  #                            [--local <url-encoded-path>]\n  #                            [--page <page-number>] [--limit <limit>]\n  #                            [--query <query>] [--terminal]\n  #\n  # Description:\n  #   Render a notebook or folder as an HTML page.\n  _browse_render_container() {\n    local _columns=\"${NB_BROWSE_COLUMNS:-70}\"\n    local _current_page=1\n    local _encoded_local_notebook_path=\n    local _limit=\"${NB_BROWSE_LIMIT:-30}\"\n    local _pagination_options=()\n    local _query=\n    local _target_path=\n    local _terminal_browser=0\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --col*)\n          _columns=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:-}\" \"${2:?}\")\n\n          shift\n          ;;\n        --limit|-n|--num|--number|--per*)\n          _limit=\"${2:?}\"\n          _pagination_options+=(\"${1:-}\" \"${2:?}\")\n\n          shift\n          ;;\n        --local)\n          _encoded_local_notebook_path=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:-}\" \"${2:?}\")\n          ;;\n        --page)\n          _current_page=\"${2:?}\"\n          _pagination_options+=(\"${1:-}\" \"${2:?}\")\n\n          shift\n          ;;\n        --query)\n          if [[ -n \"${2:-}\" ]]\n          then\n            _query=\"${2:-}\"\n          else\n            _exit_1 printf                        \\\n              \"%s requires a valid argument.\\\\n\"  \\\n              \"$(_color_primary \"${1:-}\")\"\n          fi\n\n          shift\n          ;;\n        -t|--tag*)\n          if _option_value_is_present \"${2:-}\"\n          then\n            shift\n          fi\n          ;;\n        --terminal)\n          _terminal_browser=1\n          _pagination_options+=(\"${1:-}\")\n          ;;\n        *)\n          _target_path=\"${1:-}\"\n          _pagination_options+=(\"${1:-}\")\n          ;;\n      esac\n\n      shift\n    done\n\n    if [[ -z \"${_target_path:-}\"  ]]\n    then\n      _target_path=\"$(_notebooks current --path)\"\n    fi\n\n    local _encoded_query=\n\n    if [[ -n \"${_query:-}\"        ]]\n    then\n      _query_arguments=($(\n        printf \"%s\\\\n\" \"${_query}\" | xargs -n 1 printf \"%s\\\\n\" 2>/dev/null\n      )) || IFS=' ' read -ra _query_arguments <<< \"${_query}\"\n\n      _encoded_query=\"$(\n        LC_ALL=C sed          \\\n          -e \"s/&/\\&amp;/g\"   \\\n          -e \"s/</\\&lt;/g\"    \\\n          -e \"s/>/\\&gt;/g\"    \\\n          -e \"s/\\\"/\\&quot;/g\" \\\n          -e \"s/#/\\&#35;/g\"   \\\n          -e \"s/'/\\&#39;/g\"   <<< \"${_query}\"\n      )\"\n    fi\n\n    [[ ! \"${_target_path}\" =~ /$ ]] && _target_path=\"${_target_path}/\"\n\n    local _url_params=\n\n    if ((_terminal_browser))\n    then\n      _url_params+=\"?--columns=${_columns}&--limit=${_limit}\"\n    fi\n\n    if [[   -n \"${_encoded_local_notebook_path:-}\"  ]]\n    then\n      if [[ -z \"${_url_params:-}\"                   ]]\n      then\n        _url_params+=\"?\"\n      else\n        _url_params+=\"&\"\n      fi\n\n      _url_params+=\"--local=${_encoded_local_notebook_path:-}\"\n    fi\n\n    local _maybe_columns_input=\n\n    if ((${_columns:-}))\n    then\n      _maybe_columns_input=\"\\\n<input type=\\\"hidden\\\" name=\\\"--columns\\\"   value=\\\"${_columns}\\\">\"\n    fi\n\n    local _current_selector=\n    local _maybe_local_input=\n\n    local _local_notebook_path=\n    _local_notebook_path=\"$(_get_uri --decode \"${_encoded_local_notebook_path:-}\")\"\n\n    if [[ \"${_target_path%/}\" == \"${_local_notebook_path%/}\" ]]\n    then\n      _current_selector=\"local:\"\n      _maybe_local_input=\"\\\n<input type=\\\"hidden\\\" name=\\\"--local\\\"     value=\\\"${_local_notebook_path}\\\">${_NEWLINE}\"\n    else\n      _current_selector=\"$(_get_id_selector \"${_target_path%/}\" || :)\"\n    fi\n\n    local _url_encoded_selector=\"${_current_selector//' '/%20}\"\n\n    {\n      if [[ -n \"${_query:-}\" ]]\n      then\n        _search \"${_target_path}\"         \\\n          \"${_query_arguments[@]:-}\"      \\\n          --limit \"${_limit}\"             \\\n          --list                          \\\n          --no-color                      \\\n          --notebook-selectors            \\\n          --page  \"${_current_page}\"      \\\n          2>&1 || :\n      else\n        local _list_options=(\n          --limit \"${_limit}\"\n          --no-color\n          --notebook-selectors\n          --page  \"${_current_page}\"\n          --with-pinned\n        )\n\n        if ((${NB_FOLDERS_FIRST:-0}))\n        then\n          _list_options+=(\"--folders-first\")\n        fi\n\n        _list \"${_target_path}\" \"${_list_options[@]:-}\"\n      fi\n    } | {\n      local _truncate_length=9999\n\n      if ((_terminal_browser))\n      then\n        case \"${NB_BROWSER:-}\" in\n          # TODO: improve\n          *elinks*) _truncate_length=\"$((_columns - 23))\" ;;\n          *links*)  _truncate_length=\"$((_columns - 5))\"  ;;\n          *)        _truncate_length=\"$((_columns - 2))\"  ;;\n        esac\n      else\n        _truncate_length=\"$((_columns + 6))\"\n      fi\n\n      local         __list_item=\n      while read -r __list_item\n      do\n        if [[ -n \"${_truncate_length:-}\"          ]] &&\n           [[ ! \"${__list_item:-}\" =~ Not\\ found  ]]\n        then\n          local _list_item_length=\"${#__list_item}\"\n          local _list_item_visible_length=\n          _list_item_visible_length=\"$(_get_visible_length \"${__list_item}\")\"\n\n          local _difference=\n          _difference=\"$((_list_item_visible_length - _list_item_length))\"\n\n          local _adjusted_truncate_length=\n          _adjusted_truncate_length=\"$((_truncate_length - _difference))\"\n\n          if [[ \"${_list_item_visible_length}\" -ge \"${_adjusted_truncate_length}\" ]]\n          then\n            __list_item=\"${__list_item:0:$((_adjusted_truncate_length))}…\"\n          fi\n        fi\n\n        local _display_item=\"${__list_item:-}\"\n\n        local _maybe_escaped_ampersand='\\&'\n\n        if [[ \"${BASH_VERSINFO[0]:-999999999}\"  -lt 5   ]]  ||  {\n             [[ \"${BASH_VERSINFO[0]:-999999999}\"  ==  5 ]]  &&\n             [[ \"${BASH_VERSINFO[1]:-999999999}\"  -lt 2 ]]\n           }\n        then\n          _maybe_escaped_ampersand=\"&\"\n        fi\n\n        local _35=\"${_maybe_escaped_ampersand}#35;\"\n        local _36=\"${_maybe_escaped_ampersand}#36;\"\n        local _40=\"${_maybe_escaped_ampersand}#40;\"\n        local _41=\"${_maybe_escaped_ampersand}#41;\"\n        local _60=\"${_maybe_escaped_ampersand}#60;\"\n        local _62=\"${_maybe_escaped_ampersand}#62;\"\n        local _64=\"${_maybe_escaped_ampersand}#64;\"\n\n        _display_item=\"${_display_item//'&'/&amp;}\"\n        _display_item=\"${_display_item//'#'/${_35}}\"\n        _display_item=\"${_display_item//'$'/${_36}}\"\n        _display_item=\"${_display_item//'('/${_40}}\"\n        _display_item=\"${_display_item//')'/${_41}}\"\n        _display_item=\"${_display_item//'<'/${_60}}\"\n        _display_item=\"${_display_item//'>'/${_62}}\"\n        _display_item=\"${_display_item//'@'/${_64}}\"\n        _display_item=\"${_display_item//\\\\\\ /${_NBSP}}\"\n        _display_item=\"${_display_item//' '/${_NBSP}}\"\n\n        # shellcheck disable=SC2140\n        _display_item=\"${_display_item//\\[/<span class=\\\"muted\\\">[</span><span class=\\\"identifier\\\">}\"\n        _display_item=\"${_display_item//\\]/</span><span class=\\\"muted\\\">]</span>}\"\n\n        if [[   \"${_display_item:-}\" =~ ^0${_NBSP}items.        ]]\n        then\n          printf \"%s\\\\n<br>\\\\n\" \"${_display_item}\"\n\n          break\n        elif [[ \"${_display_item:-}\" =~ ^.*\\!.*Not${_NBSP}found ]]\n        then\n          _display_item=\"Not${_display_item#*Not}\"\n          printf \"%s\\\\n<br>\\\\n\" \"${_display_item//${_NBSP}in*:/:}\"\n\n          break\n        fi\n\n        local _item_selector=\"${__list_item%%]*}\"\n        _item_selector=\"${_item_selector#[}\"\n        _item_selector=\"${_item_selector//\\\\/}\"\n\n        local _link_selector=\n        _link_selector=\"$(_get_id_selector \"${_item_selector}\" --notebook)\"\n        _link_selector=\"${_link_selector//' '/%20}\"\n\n        printf \"<a href=\\\"//%s:%s/%s%s\\\" class=\\\"list-item\\\">%s</a><br>\\\\n\"  \\\n          \"${NB_SERVER_HOST}\"                                                \\\n          \"${NB_SERVER_PORT}\"                                                \\\n          \"${_link_selector:-}\"                                              \\\n          \"${_url_params:-}\"                                                 \\\n          \"${_display_item:-}\"\n      done\n    } | {\n      local _list_count=\n      _list_count=\"$(_count \"${_target_path}\")\"\n\n      local _print_prev=0\n\n      if ((_list_count)) && [[ \"${_current_page}\" -gt 1 ]]\n      then\n        _print_prev=1\n      fi\n\n      local _print_next=0\n\n      if ((_list_count)) &&\n         [[ \"$((_current_page * _limit))\" -lt \"${_list_count}\" ]]\n      then\n        _print_next=1\n      fi\n\n      cat <<HEREDOC\n<form\n  accept-charset=\"UTF-8\"\n  action=\"/${_url_encoded_selector}${_url_params:-}\"\n  id=\"search\"\n  method=\"get\">\n<label for=\"search-input\">search:</label>\n<input\n  autocapitalize=\"off\"\n  autocomplete=\"off\"\n  id=\"search-input\"\n  name=\"--query\"\n  placeholder=\"search\"\n  type=\"text\"\n  value=\"${_encoded_query}\">\n<i></i>\n<input type=\"hidden\" name=\"--limit\" value=\"${_limit}\">\n<input type=\"hidden\" name=\"--page\"  value=\"${_current_page}\">\n${_maybe_columns_input:-}\n${_maybe_local_input:-}</form>\n<br>\nHEREDOC\n\n      printf \"<p class=\\\"item-list\\\">\\\\n\"\n\n      local _pagination_count=0\n\n      local         __line=\n      while read -r __line\n      do\n        printf \"%s\\\\n\" \"${__line}\"\n\n        _pagination_count=\"$((_pagination_count+1))\"\n      done\n\n      printf \"</p>\\\\n\"\n\n      if [[ -n \"${_query:-}\"                              ]] &&\n         [[ \"${_pagination_count}\" -lt \"${_limit:-0}\"  ]]\n      then\n        _print_next=0\n      fi\n\n      if ((_print_prev)) || ((_print_next))\n      then\n        printf \"<p class=\\\"pagination\\\">\\\\n\"\n      fi\n\n      if [[ -n \"${_query:-}\" ]]\n      then\n        local _url_encoded_query=\n        _url_encoded_query=\"$(_get_uri --encode \"${_query:-}\")\"\n\n        _url_params+=\"&--query=${_url_encoded_query}\"\n      fi\n\n      if ! ((_terminal_browser)) &&\n         _contains \"--limit\" \"${_pagination_options[@]:-}\"\n      then\n        _url_params+=\"&--limit=${_limit}\"\n      fi\n\n      if ((_print_prev))\n      then\n        local _prev_page_number=\n        _prev_page_number=\"$((_current_page - 1))\"\n\n        local _prev_url_params=\"${_url_params#$'?'}\"\n\n        if [[ \"${_prev_page_number:-0}\" -gt 1     ]]\n        then\n          _prev_url_params+=\"&--page=${_prev_page_number:-}\"\n        fi\n\n        _prev_url_params=\"${_prev_url_params#$'&'}\"\n\n        if [[ -n \"${_prev_url_params:-}\"          ]]\n        then\n          _prev_url_params=\"?${_prev_url_params:-}\"\n        fi\n\n        printf                                    \\\n          \"<a href=\\\"//%s:%s/%s%s\\\">%s prev</a>\"  \\\n          \"${NB_SERVER_HOST}\"                     \\\n          \"${NB_SERVER_PORT}\"                     \\\n          \"${_url_encoded_selector}\"              \\\n          \"${_prev_url_params:-}\"                 \\\n          \"${_CHEVRON_LEFT}\"\n      fi\n\n      if ((_print_prev)) && ((_print_next))\n      then\n        printf \" <span class=\\\"muted\\\">%s</span> \" \"${_MD}\"\n      fi\n\n      if ((_print_next))\n      then\n        local _next_url_params=\n        _next_url_params=\"${_url_params#$'?'}&--page=$((_current_page + 1))\"\n\n        printf                                    \\\n          \"<a href=\\\"//%s:%s/%s?%s\\\">next %s</a>\" \\\n          \"${NB_SERVER_HOST}\"                     \\\n          \"${NB_SERVER_PORT}\"                     \\\n          \"${_url_encoded_selector}\"              \\\n          \"${_next_url_params#$'&'}\"              \\\n          \"${_CHEVRON_RIGHT}\"\n      fi\n\n      if ((_print_prev)) || ((_print_next))\n      then\n        printf \"</p>\\\\n\"\n      fi\n    } | {\n      printf \"%s\\\\n\" \"$(_browse_render_header \"${_pagination_options[@]:-}\")\"\n\n      printf \"<div class=\\\"main\\\">\\\\n\"\n\n      cat\n\n      printf \"</div>\\\\n\"\n    } | {\n      local _html_title=\"${_ME} browse\"\n\n      if [[ -n \"${_current_selector:-}\" ]]\n      then\n        _html_title+=\" ${_current_selector// /\\\\ }\"\n      fi\n\n      if [[ -n \"${_encoded_query:-}\"    ]]\n      then\n        _html_title+=\" --query \\\"${_encoded_query:-}\\\"\"\n      fi\n\n      if [[ \"${_current_page:-0}\" -gt 1 ]]\n      then\n        _html_title+=\" --page ${_current_page}\"\n      fi\n\n      _render --title \"${_html_title}\"\n    }\n  }\n\n  # _browse_render_delete()\n  #\n  # Usage:\n  #   _browse_render_delete <path> [--columns <columns>]\n  #                         [--limit <limit>] [--local <url-encoded-path>]\n  #                         [--terminal]\n  #\n  # Description:\n  #   Print an form for deleting an item.\n  _browse_render_delete() {\n    local _columns=\"${NB_BROWSE_COLUMNS:-70}\"\n    local _encoded_local_notebook_path=\n    local _limit=\"${NB_BROWSE_LIMIT:-30}\"\n    local _pagination_options=()\n    local _raw_url=\n    local _source_path=\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --col*)\n          _columns=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --limit|-n|--num|--number|--per*)\n          _limit=\"${2:?}\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --local)\n          _encoded_local_notebook_path=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --page)\n          _option_value_is_present \"${2:-}\" && shift\n          ;;\n        --raw-url)\n          _raw_url=\"${2:?}\"\n\n          shift\n          ;;\n        --terminal)\n          _pagination_options+=(\"--terminal\")\n          ;;\n        *)\n          _source_path=\"${1:-}\"\n          ;;\n      esac\n\n      shift\n    done\n\n    local _info_line=\n    _info_line=\"$(_show \"${_source_path}\" --info-line --no-color)\"\n\n    local _id_selector=\n    _id_selector=\"$(_get_id_selector \"${_source_path}\")\"\n\n    local _url_params=\n\n    if [[ -n \"${_encoded_local_notebook_path:-}\" ]]\n    then\n      _url_params+=\"&--local=${_encoded_local_notebook_path}\"\n    fi\n\n    if _contains \"--terminal\" \"${_pagination_options[@]:-}\"\n    then\n      _url_params+=\"&--columns=${_columns}\"\n      _url_params+=\"&--limit=${_limit}\"\n    fi\n\n    {\n      cat <<HEREDOC\n<h2 align=\"center\">deleting</h2>\n\n<p align=\"center\">\n<a href=\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_id_selector}${_url_params/&/?}\">\n${_info_line//'\\ '/ }\n</a>\n</p>\n<p align=\"center\" class=\"muted\">\n  This item will still be available in git history.\n</p>\n<div align=\"center\">\n<form\n  accept-charset=\"UTF-8\"\n  action=\"/${_id_selector:-}?--delete${_url_params:-}\"\n  align=\"center\"\n  method=\"post\">\n<input\n  align=\"center\"\n  type=\"submit\"\n  value=\"delete\">\n</form>\n</div>\nHEREDOC\n    } | {\n      printf \"%s\\\\n\" \"$(\n        _browse_render_header           \\\n          \"${_source_path}\"             \\\n          \"${_pagination_options[@]:-}\" \\\n          --raw-url \"${_raw_url}\"       \\\n          --delete\n      )\"\n\n      printf \"<div class=\\\"main\\\">\\\\n\"\n\n      cat\n\n      printf \"</div>\\\\n\"\n    } | {\n      _render --title \"${_ME} browse delete ${_id_selector// /\\\\ }\"\n    }\n  }\n\n  # _browse_render_edit()\n  #\n  # Usage:\n  #   _browse_render_edit <path> [--columns <columns>]\n  #                       [--limit <limit>] [--local <url-encoded-path>]\n  #                       [--terminal] [<edit-option>...]\n  #\n  # Description:\n  #   Print an HTML page for editing a text file.\n  _browse_render_edit() {\n    local _columns=\"${NB_BROWSE_COLUMNS:-70}\"\n    local _encoded_local_notebook_path=\n    local _limit=\"${NB_BROWSE_LIMIT:-30}\"\n    local _pagination_options=()\n    local _raw_url=\n    local _source_path=\n    local _subcommand_options=()\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --col*)\n          _columns=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --limit|-n|--num|--number|--per*)\n          _limit=\"${2:?}\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --local)\n          _encoded_local_notebook_path=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --page)\n          _option_value_is_present \"${2:-}\" && shift\n          ;;\n        --raw-url)\n          _raw_url=\"${2:?}\"\n\n          shift\n          ;;\n        --terminal)\n          _pagination_options+=(\"--terminal\")\n          ;;\n        *)\n          if [[ -z \"${_source_path:-}\"  ]] && [[    \"${1:-}\" =~ ^/    ]]\n          then\n            _source_path=\"${1:-}\"\n          elif [[ \"${1:-}\" =~ :         ]] && [[ !  \"${1:-}\" =~ \\-\\-  ]]\n          then\n            : # skip selector\n          else\n            _subcommand_options+=(\"${1:-}\")\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    local _content=\n    _content=\"$(_show \"${_source_path}\" --print --no-color)\"\n\n    local _id_selector=\n    _id_selector=\"$(_get_id_selector \"${_source_path}\" --notebook)\"\n\n    local _form_action_selector=\n    _form_action_selector=\"${_id_selector// /%20}\"\n\n    local _last_saved_at=\n    _last_saved_at=\"$(_show \"${_source_path}\" --updated)\"\n    _last_saved_at=\"${_last_saved_at% -[0-9][0-9][0-9][0-9]}\"\n\n    local _rows=30\n    local _text_area_columns=\"${_columns:-}\"\n    local _url_params=\n\n    if _contains \"--terminal\" \"${_pagination_options[@]:-}\"\n    then\n      _url_params+=\"&--columns=${_columns}\"\n      _text_area_columns=\"$((_text_area_columns - 3))\"\n\n      _url_params+=\"&--limit=${_limit}\"\n      _rows=\"$((_limit + 2))\"\n    fi\n\n    if [[ -n \"${_encoded_local_notebook_path:-}\" ]]\n    then\n      _url_params+=\"&--local=${_encoded_local_notebook_path}\"\n    fi\n\n    {\n      # TODO: https://stackoverflow.com/a/15844977\n      cat <<HEREDOC\n<form\n  accept-charset=\"UTF-8\"\n  action=\"/${_form_action_selector:-}?--edit${_url_params:-}\"\n  method=\"post\">\n<textarea\n  class=\"content\"\n  cols=\"${_text_area_columns}\"\n  id=\"content\"\n  name=\"content\"\n  rows=\"${_rows}\">${_content}</textarea>\n<br><br>\n<input\n  type=\"submit\"\n  value=\"save\"> <span class=\"muted\">${_MD}</span> <span class=\"muted last-saved\">last: ${_last_saved_at}</span>\n$(_browse_render_option_fields \"${_subcommand_options[@]:-}\")\n</form>\nHEREDOC\n    } | {\n      printf \"%s\\\\n\" \"$(\n        _browse_render_header           \\\n          \"${_source_path}\"             \\\n          \"${_pagination_options[@]:-}\" \\\n          --raw-url \"${_raw_url}\"       \\\n          --edit\n      )\"\n\n      printf \"<div class=\\\"main\\\">\\\\n\"\n\n      cat\n\n      printf \"</div>\\\\n\"\n    } | {\n      _render                                     \\\n        --source-extension \"${_source_path##*.}\"  \\\n        --title \"${_ME} browse edit ${_id_selector// /\\\\ }\"\n    }\n  }\n\n  # _browse_render_header()\n  #\n  # Usage:\n  #   _browse_render_header <selector> [--columns <columns>]\n  #                         [--local <url-encoded-path>] [--limit <limit>]\n  #                         [--raw-url <url>] [--terminal]\n  #\n  # Description:\n  #   Print a context-aware, linked nav header.\n  _browse_render_header() {\n    local _action=\n    local _columns=\"${NB_BROWSE_COLUMNS:-70}\"\n    local _encoded_local_notebook_path=\n    local _limit=\"${NB_BROWSE_LIMIT:-30}\"\n    local _raw_url=\n    local _selector=\n    local _terminal_browser=0\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        '') : ;;\n        --add|--delete|--edit)\n          _action=\"${1#--}\"\n          ;;\n        --col*)\n          _columns=\"${2:?}\"\n\n          shift\n          ;;\n        --limit|-n|--num|--number|--per*)\n          _limit=\"${2:?}\"\n\n          shift\n          ;;\n        --local)    _encoded_local_notebook_path=\"${2:?}\" && shift  ;;\n        --page)     _option_value_is_present     \"${2:-}\" && shift  ;;\n        --raw-url)  _raw_url=\"${2:?}\"                     && shift  ;;\n        --terminal) _terminal_browser=1                             ;;\n        --*)        _option_value_is_present \"${2:-}\"     && shift  ;;\n        -*)         :                                               ;;\n        *)          _selector=\"${1:-}\"                              ;;\n      esac\n\n      shift\n    done\n\n    local _url_params=()\n\n    if [[ -n \"${_encoded_local_notebook_path:-}\" ]]\n    then\n      _url_params+=(\"--local=${_encoded_local_notebook_path}\")\n    fi\n\n    if ((_terminal_browser))\n    then\n      _url_params+=(\n        \"--columns=${_columns}\"\n        \"--limit=${_limit}\"\n      )\n    fi\n\n    local _url_param_string=\n    _url_param_string=\"$(_join \"&\" \"${_url_params[@]:-}\")\"\n\n    if [[ -n \"${_url_param_string:-}\" ]]\n    then\n      _url_param_string=\"?${_url_param_string}\"\n      local _url_params_ext=\"${_url_param_string}&\"\n    else\n      local _url_params_ext=\"?\"\n    fi\n\n    local _header_content=\"\\\n<a href=\\\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_url_param_string:-}\\\">\"\n    _header_content+=\"<span class=\\\"muted\\\">${_CHEVRON_RIGHT}</span>${_ME}</a>\"\n    _header_content+=\" <span class=\\\"muted\\\">${_MD}</span>\"\n\n    if [[ -z \"${_selector:-}\"         ]]\n    then\n      _header_content+=\" <span class=\\\"muted\\\">notebooks</span>\"\n    else\n      local _notebook_name=\n\n      if [[ \"${_selector}\" =~ (:|^/)  ]]\n      then\n        _notebook_name=\"$(_notebooks show \"${_selector}\" --name)\"\n      fi\n\n      if [[ -z \"${_notebook_name}\"    ]]\n      then\n        _notebook_name=\"$(_notebooks current --name)\"\n      fi\n\n      local _notebook_path=\n      _notebook_path=\"$(_notebooks show \"${_notebook_name}\" --path)\"\n\n      _notebooks select \"${_notebook_path}\"\n\n      _header_content+=\"\\\n <a href=\\\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_notebook_name//' '/%20}:${_url_param_string:-}\\\">${_notebook_name}</a>\"\n      _header_content+=\" <span class=\\\"muted\\\">:</span>\"\n\n      local _relative_folder_path=\n      local _selector_relative_folder_path=\n\n      if [[ \"${_selector}\" =~ ^/      ]]\n      then\n        local _relative_path=\"${_selector#\"${_notebook_path}\"/}\"\n\n        if [[ \"${_relative_path:-}\" == \"${_notebook_path:-}\" ]]\n        then\n          _relative_path=\n        fi\n\n        if [[ -d \"${_selector}\"       ]]\n        then\n          _relative_folder_path=\"${_relative_path:-}\"\n        else\n          if [[ \"${_relative_path:-}\" =~ / ]]\n          then\n            _relative_folder_path=\"${_relative_path%/*}\"\n          else\n            _relative_folder_path=\n          fi\n        fi\n\n        _selector_relative_folder_path=\"${_relative_folder_path:-}\"\n      else\n        _selector_relative_folder_path=\"${_selector#*:}\"\n        _relative_folder_path=\"$(\n          _selector_resolve_folders \"${_selector_relative_folder_path}\" || :\n        )\"\n      fi\n\n      if [[ -n \"${_relative_folder_path:-}\"                  ]] &&\n         [[ -d \"${_notebook_path}/${_relative_folder_path}\"  ]]\n      then\n        local _selector_folders=()\n        IFS='/' read -ra _selector_folders <<< \"${_relative_folder_path}\"\n\n        local _folder_id_path=\n        _folder_id_path=\"$(\n          _get_id_selector \"$(\n            _join \"/\" \"${_selector_folders[@]:-}\"\n          )/\" \"${_notebook_path}\"\n        )\"\n\n        local _selector_folder_ids=()\n        IFS='/' read -ra _selector_folder_ids <<< \"${_folder_id_path}\"\n\n        local _url_path=\"${_notebook_name}:\"\n\n        local i=\n        for ((i=0; i < ${#_selector_folders[@]}; i++))\n        do\n          _url_path+=\"${_selector_folder_ids[i]:-}/\"\n\n          _header_content+=\"\\\n <a href=\\\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_url_path}${_url_param_string:-}\\\">${_selector_folders[i]}</a>\"\n          _header_content+=\" <span class=\\\"muted\\\">/</span>\"\n        done\n      fi\n    fi\n\n    local _item_path=\n    _item_path=\"$(_show \"${_selector:-}\" --path 2>/dev/null || :)\"\n\n    if [[ -f \"${_item_path:-}\"  ]]\n    then\n      local _id_selector=\n      _id_selector=\"$(_get_id_selector \"${_selector:-}\" --notebook)\"\n\n      local _selector_id=\"${_id_selector#*:}\"\n      _selector_id=\"${_selector_id##*/}\"\n\n      if _contains \"${_action:-}\" \"edit\" \"delete\"\n      then\n        _header_content+=\"\\\n <a href=\\\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_id_selector:-}${_url_param_string:-}\\\">${_selector_id:-}</a>\"\n      elif [[ \"${_action:-}\" != \"add\"   ]]\n      then\n        _header_content+=\" <span class=\\\"muted\\\">${_selector_id:-}</span>\"\n      fi\n\n      # NOTE: backup _raw_url calculation. TODO: remove\n      if [[ -z \"${_raw_url:-}\"  ]]\n      then\n        local _raw_url=\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/--original/\"\n\n        if [[ !   \"${_item_path:-}\" =~ ^${NB_DIR}     ]] &&\n           [[ -n  \"${_encoded_local_notebook_path:-}\" ]]\n        then\n          local _local_notebook_path=\n          _local_notebook_path=\"$(_get_uri --decode \"${_encoded_local_notebook_path}\")\"\n\n          _raw_url+=\"local/${_item_path#\"${_local_notebook_path}\"/}?--local=${_encoded_local_notebook_path}\"\n        else\n          _raw_url+=\"${_item_path#\"${NB_DIR}\"/}\"\n        fi\n      fi\n\n      if [[ -n \"${_raw_url:-}\"  ]]\n      then\n        _header_content+=\" <span class=\\\"muted\\\">${_MD}</span>\"\n        _header_content+=\" <a href=\\\"${_raw_url}\\\">↓</a>\"\n      fi\n\n      if [[ \"${_action:-}\"  == \"edit\"   ]]\n      then\n        _header_content+=\" <span class=\\\"muted\\\">${_MD}</span>\"\n        _header_content+=\" <span class=\\\"muted\\\">editing</span>\"\n      elif _file_is_text \"${_selector:-}\"\n      then\n        _header_content+=\" <span class=\\\"muted\\\">${_MD}</span>\"\n        _header_content+=\"\\\n <a href=\\\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_id_selector:-}${_url_params_ext:-}--edit\\\">edit</a>\"\n      fi\n\n      case \"${_action:-}\" in\n        delete)\n          _header_content+=\" <span class=\\\"muted\\\">${_MD}</span>\"\n          _header_content+=\" <span class=\\\"muted\\\">-</span>\"\n          _header_content+=\" <span class=\\\"muted\\\">|</span>\"\n          ;;\n        edit)\n          _header_content+=\" <span class=\\\"muted\\\">${_MD}</span>\"\n          _header_content+=\"\\\n <a href=\\\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_id_selector:-}${_url_params_ext:-}--delete\\\">-</a>\"\n          _header_content+=\" <span class=\\\"muted\\\">|</span>\"\n          ;;\n        *)\n          _header_content+=\" <span class=\\\"muted\\\">|</span>\"\n          ;;\n      esac\n    fi\n\n    if [[ -n \"${_selector:-}\"           ]]\n    then\n      if [[ \"${_action:-}\"  == \"add\"    ]]\n      then\n        _header_content+=\" <span class=\\\"muted\\\">+</span>\"\n      else\n        _header_content+=\"\\\n <a href=\\\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_notebook_name}:${_folder_id_path:-}${_url_params_ext:-}--add\\\">+</a>\"\n      fi\n    fi\n\n    cat <<HEREDOC\n<nav class=\"header-crumbs\"><strong>${_header_content:-}</strong></nav>\n<p class=\"header-crumbs-spacer\"></p>\nHEREDOC\n  }\n\n  # _browse_render_item()\n  #\n  # Usage:\n  #   _browse_render_item <path> [--columns <columns>]\n  #                       [--limit <limit>] [--local <url-encoded-path>]\n  #                       [--raw-url <url>] [--terminal]\n  #\n  # Description:\n  #   Render an item to HTML with links resolved to internal web server.\n  _browse_render_item() {\n    local _columns=\"${NB_BROWSE_COLUMNS:-70}\"\n    local _pagination_options=()\n    local _raw_url=\n    local _respond_with_arguments=(\"--standard-input\")\n    local _source_path=\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --col*)\n          _columns=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:-}\" \"${2:?}\")\n\n          shift\n          ;;\n        --headers)\n          _respond_with_arguments+=(\"${1:-}\")\n          ;;\n        --limit|-n|--num|--number|--per*)\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --local)\n          _pagination_options+=(\"${1:-}\" \"${2:?}\")\n\n          shift\n          ;;\n        --page)\n          _option_value_is_present \"${2:-}\" && shift\n          ;;\n        --raw-url)\n          _raw_url=\"${2:?}\"\n\n          shift\n          ;;\n        --terminal)\n          _pagination_options+=(\"--terminal\")\n          ;;\n        *)\n          if [[ -z \"${_source_path:-}\"  ]]\n          then\n            _source_path=\"${1:-}\"\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    local _header_options=(\"${_pagination_options[@]:-}\")\n\n    if [[ -n \"${_raw_url:-}\" ]]\n    then\n      _header_options+=(\"--raw-url\" \"${_raw_url}\")\n    fi\n\n    local _id_selector=\n    _id_selector=\"$(_get_id_selector \"${_source_path:-}\" --notebook)\"\n\n    local _html_title=\"${_ME} browse ${_id_selector// /\\\\\\ }\"\n\n    local _render_type=\n\n    if _file_is_text \"${_source_path:-}\"  ||\n       [[   \"${_source_path:-}\" =~ (\\.docx$|\\.epub$|\\.odt$) ]]\n    then\n      _render_type=\"pandoc\"\n    elif _contains \"${_source_path##*.}\"  \\\n           apng avif gif jfif jpeg jpg pjpeg pjp png svg webp\n    then\n      _render_type=\"image\"\n    elif _file_is_audio \"${_source_path:-}\"\n    then\n      _render_type=\"audio\"\n    elif _file_is_video \"${_source_path:-}\"\n    then\n      _render_type=\"video\"\n    elif [[ \"${_source_path}\" =~ \\.pdf    ]]\n    then\n      _render_type=\"pdf\"\n    else\n      {\n        printf \"%s\\\\n\" \"$(\n          _browse_render_header           \\\n            \"${_source_path}\"             \\\n            \"${_header_options[@]:-}\"\n        )\"\n\n        printf \"<div class=\\\"main\\\">\\\\n<p>\\\\n\"\n\n        if _file_is_encrypted \"${_source_path:-}\"\n        then\n          printf \"415 %s: File is encrypted\\\\n\" \\\n            \"$(_browse_http_response_message 415)\"\n        else\n          printf \"415 %s\\\\n\"                    \\\n            \"$(_browse_http_response_message 415)\"\n        fi\n\n        printf \"</p>\\\\n</div>\\\\n\"\n      } | {\n        _render --title \"${_html_title}\"\n      } | {\n        _browse_respond_with 415 \"${_respond_with_arguments[@]:-}\"\n      }\n\n      return 1\n    fi\n\n    local _notebook_path=\n    _notebook_path=\"$(\n      _notebooks show \"${_source_path:-}\" --path 2>/dev/null  ||\n        _notebooks current --path\n    )\"\n\n    if [[ \"${_source_path:-}\" =~ (\\.asciidoc$|\\.adoc$)  ]]    &&\n       _file_is_text \"${_source_path:-}\"                      &&\n       _command_exists \"asciidoctor\"\n    then\n      {\n        asciidoctor           \\\n          -o -                \\\n          --no-header-footer  \\\n          \"${_source_path:-}\"\n      } | {\n        printf \"%s\\\\n\" \"$(\n          _browse_render_header           \\\n            \"${_source_path}\"             \\\n            \"${_header_options[@]:-}\"\n        )\"\n\n        printf \"<div class=\\\"main\\\">\\\\n\"\n\n        cat\n\n        printf \"</div>\\\\n\"\n      } | {\n        _resolve_links                    \\\n          \"${_notebook_path}\"             \\\n          \"${_pagination_options[@]:-}\"   \\\n          --browse\n      } | {\n        _render --title \"${_html_title}\"\n      }\n    elif [[ \"${_source_path:-}\" =~ \\.org$               ]]    &&\n         _file_is_text \"${_source_path:-}\"\n    then # resolve Org [[wiki-style links]] before rendering to HTML\n      {\n        cat \"${_source_path}\"\n      } | {\n        _resolve_links                    \\\n          \"${_notebook_path}\"             \\\n          \"${_pagination_options[@]:-}\"   \\\n          --browse                        \\\n          --type org\n      } | {\n        # avoid pandoc bug with brackets in Org link descriptions\n        LC_ALL=C sed -E                                   \\\n          -e \"s/\\]\\[\\[\\[/\\]\\[${_ME}-placeholder-${_ME}/g\" \\\n          -e \"s/\\]\\]\\]\\]/${_ME}-placeholder-${_ME}\\]\\]/g\"\n      } | {\n        if _command_exists \"pandoc\"\n        then\n          _pandoc             \\\n            --standard-input  \\\n            --from  org       \\\n            --to    html\n        else\n          cat\n        fi\n      } | {\n        LC_ALL=C sed -E                                   \\\n          -e \"s/>${_ME}-placeholder-${_ME}/>\\[\\[/g\"       \\\n          -e \"s/${_ME}-placeholder-${_ME}</\\]\\]</g\"\n      } | {\n        # undo pandoc adding \"file://\" or \"file:///\" to protocol-relative URLs\n        LC_ALL=C sed -E -e \"s/file:\\/\\/\\/\\/\\/?/\\/\\//g\"\n      } | {\n        printf \"%s\\\\n\" \"$(\n          _browse_render_header           \\\n            \"${_source_path}\"             \\\n            \"${_header_options[@]:-}\"\n        )\"\n\n        printf \"<div class=\\\"main\\\">\\\\n\"\n\n        cat\n\n        printf \"</div>\\\\n\"\n      } | {\n        _render --title \"${_html_title}\"\n      }\n    else # render non-Org to HTML before resolving [[wiki-style links]]\n      {\n        case \"${_render_type:-}\" in\n          pandoc)\n            local _render_options=(\"--pandoc\" \"--body\" \"--title\" \"${_html_title}\")\n\n            if [[ \"${_source_path:-}\" =~ \\.bookmark\\.md ]]\n            then\n              _render_options+=(\"--bookmark\")\n            fi\n\n            {\n              printf \"\" | _render \"${_source_path}\" \"${_render_options[@]:-}\"\n            } | {\n              if _command_exists \"pandoc\"\n              then\n                cat\n              else\n                if ! _contains \"--terminal\" \"${_pagination_options[@]:-}\"\n                then\n                  printf \"<br>\"\n                fi\n\n                LC_ALL=C sed -E                               \\\n                  -e \"/<span class=\\\"muted\\\"/!s/</\\&lt;/g\"    \\\n                  -e \"/<span class=\\\"muted\\\"/!s/\\//\\&#47;/g\"  \\\n                  -e \"s/.*/&<br>/g\" # \" TODO: vim highlighting bug\n              fi\n            }\n            ;;\n          *)\n            { # begin media markup pipeline\n              case \"${_render_type:-}\" in\n                audio)\n                  local _mime_type=\n                  _mime_type=\"$(file -b --mime-type \"${_source_path}\" 2>/dev/null || :)\"\n\n                  # handle `file` 5.40 bug: https://bugs.astron.com/view.php?id=259\n                  _mime_type=\"${_mime_type//audio\\/mpegapplication\\/octet-stream/audio/mpeg}\"\n                  _mime_type=\"${_mime_type//audio\\/mpegaudio\\/mpeg/audio/mpeg}\"\n\n                  cat <<HEREDOC\n<audio controls>\n  <source src=\"${_raw_url}\" type=\"${_mime_type:-}\">\n</audio>\nHEREDOC\n                  ;;\n                image)\n                  cat <<HEREDOC\n<a href=\"${_raw_url}\">\n  <img src=\"${_raw_url}\" alt=\"${_NB_INDICATOR_IMAGE:-}${_source_path##*/}\" />\n</a>\nHEREDOC\n                  ;;\n                pdf)\n                  if ((${NB_BROWSE_PDF_TO_TEXT_ENABLED:-0}))  &&\n                     _command_exists \"pdftotext\"\n                  then\n                    # TODO: spacing\n                    # NOTE: add uniform newlines: `sed  '/^$/d' | sed G`\n                    pdftotext \"${_source_path}\" - \\\n                      | tr -d '\\014'              \\\n                      | _render --from=\"md\" --pandoc --body\n                  else\n                    cat <<HEREDOC\n<iframe src=\"${_raw_url}\" width=\"100%\" height=\"700px\"></iframe>\nHEREDOC\n                  fi\n                  ;;\n                video)\n                  local _mime_type=\n                  _mime_type=\"$(file -b --mime-type \"${_source_path}\" 2>/dev/null || :)\"\n\n                  cat <<HEREDOC\n<video width=\"320\" height=\"240\" controls>\n  <source src=\"${_raw_url}\" type=\"${_mime_type}\">\n</video>\nHEREDOC\n                  ;;\n              esac\n            } | { # media markup pipeline\n              cat <<HEREDOC\n<div align=\"center\" class=\"media-item\">\n  $(cat)\n</div>\n\n<p align=\"center\" class=\"media-caption\">\n  <a href=\"${_raw_url}\">\n    ${_source_path##*/}\n  </a>\n</p>\nHEREDOC\n            } # end media markup pipeline\n            ;;\n        esac\n      } | {\n        printf \"%s\\\\n\" \"$(\n          _browse_render_header           \\\n            \"${_source_path}\"             \\\n            \"${_header_options[@]:-}\"\n        )\"\n\n        printf \"<div class=\\\"main\\\">\\\\n\"\n\n        cat\n\n        printf \"</div>\\\\n\"\n      } | {\n        local _resolve_links_options=(${_pagination_options[@]:-})\n\n        if [[ \"${_source_path:-}\" =~ \\.bookmark\\.md ]]\n        then\n          _resolve_links_options+=(\"--bookmark\")\n        fi\n\n        _resolve_links                      \\\n          \"${_notebook_path}\"               \\\n          \"${_resolve_links_options[@]:-}\"  \\\n          --browse\n      } | {\n        _render --title \"${_html_title}\"\n      }\n    fi | {\n      # rewrite relative image paths to use --original URLs\n\n      local _encoded_notebook_name=\"${_raw_url#//\"${NB_SERVER_HOST}\":\"${NB_SERVER_PORT}\"/--original/}\"\n      _encoded_notebook_name=\"${_encoded_notebook_name%%/*}\"\n\n      local _raw_url_base_pattern=\"\\/\\/${NB_SERVER_HOST}:${NB_SERVER_PORT}\\/--original\\/${_encoded_notebook_name}\\/\"\n      local _raw_url_pattern=\"${_raw_url_base_pattern}\\1\"\n\n      local _sed_arguments=()\n\n      _sed_arguments+=(\n-e \"s/<img src=\\\"([^\\\"]+)\\\"/<img src=\\\"${_raw_url_pattern}\\\"/g\"\n-e \"s/<img src=\\\"${_raw_url_base_pattern}(https?:[^\\\"]+)\\\"/<img src=\\\"\\1\\\"/g\"\n-e \"s/<img src=\\\"${_raw_url_base_pattern}(\\/\\/[^\\\"]+)\\\"/<img src=\\\"\\1\\\"/g\"\n      )\n\n      if [[ -n \"${_encoded_local_notebook_path:-}\" ]]\n      then\n        local _local_param_pattern=\"\\1\\?--local=${_encoded_local_notebook_path}\"\n\n        _sed_arguments+=(\n-e \"s/<img src=\\\"(${_raw_url_base_pattern}[^\\\"]+)\\\"/<img src=\\\"${_local_param_pattern}\\\"/g\"\n-e \"s/<img src=\\\"([^\\\"]+\\?--local=[^\\\"]+)\\?--local=[^\\\"]+\\\"/<img src=\\\"\\1\\\"/g\"\n        )\n      fi\n\n      LC_ALL=C sed -E \"${_sed_arguments[@]:-}\"\n    } | {\n      _browse_respond_with 200 \"${_respond_with_arguments[@]:-}\"\n    }\n\n    return 0\n  }\n\n  # _browse_render_notebooks()\n  #\n  # Usage:\n  #   _browse_render_notebooks [--columns <columns>]\n  #                            [--limit <limit>] [--local <url-encoded-path>]\n  #                            [--terminal]\n  #\n  # Description:\n  #   Print an HTML page listing notebooks.\n  _browse_render_notebooks() {\n    local _add_line_breaks=0\n    local _columns=\"${NB_BROWSE_COLUMNS:-70}\"\n    local _encoded_local_notebook_path=\n    local _limit=\"${NB_BROWSE_LIMIT:-30}\"\n    local _pagination_options=()\n    local _user_agent=\n\n    while ((${#}))\n    do\n      case \"${1:-}\" in\n        --col*)\n          _columns=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:-}\" \"${2:?}\")\n          _add_line_breaks=1\n\n          shift\n          ;;\n        --limit|-n|--num|--number|--per*)\n          _limit=\"${2:?}\"\n          _pagination_options+=(\"${1:-}\" \"${2:?}\")\n\n          shift\n          ;;\n        --local)\n          _encoded_local_notebook_path=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n          _pagination_options+=(\"${1:?}\" \"${2:?}\")\n\n          shift\n          ;;\n        --page)\n          _option_value_is_present \"${2:-}\" && shift\n          ;;\n        --terminal)\n          _pagination_options+=(\"--terminal\")\n          _add_line_breaks=1\n          ;;\n        --user-agent)\n          if [[ -n \"${2:-}\" ]]\n          then\n            _user_agent=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n            shift\n          fi\n          ;;\n      esac\n\n      shift\n    done\n\n    local _notebook_names=()\n    _notebook_names=($(_notebooks --names --unarchived --no-color --global))\n\n    local _url_param_string=\n\n    if [[ -n \"${_encoded_local_notebook_path:-}\" ]]\n    then\n      _notebook_names=(\"local\" \"${_notebook_names[@]:-}\")\n      _url_param_string+=\"&--local=${_encoded_local_notebook_path}\"\n    fi\n\n    if _contains \"--terminal\" \"${_pagination_options[@]:-}\"\n    then\n      _url_param_string+=\"&--columns=${_columns}&--limit=${_limit}\"\n    fi\n\n    # turn on case-insensitive matching\n    shopt -s nocasematch\n    case \"${_user_agent:-}\" in\n      *elinks*)\n        _columns=\"$((_columns - 30))\"\n        ;;\n      *links*)\n        _columns=\"$((_columns - 5))\"\n        ;;\n    esac\n    # turn off case-insensitive matching\n    shopt -u nocasematch\n\n    {\n      printf \"<p>\"\n\n      local _first=1\n      local _test_line=\n\n      local __name=\n      for   __name in \"${_notebook_names[@]:-}\"\n      do\n        if ((_first))\n        then\n          _first=0\n          _test_line+=\"${__name}${_NBSP}${_MD}\"\n        else\n          _test_line+=\" ${__name}${_NBSP}${_MD}\"\n\n          if ((_add_line_breaks)) && [[ \"${#_test_line}\" -gt \"${_columns}\" ]]\n          then\n            printf \"<br>\\\\n\"\n            _test_line=\"${__name}${_NBSP}${_MD}\"\n          else\n            printf \"%s<span class=\\\"muted\\\">%s</span> \" \"${_NBSP}\" \"${_MD}\"\n          fi\n        fi\n\n        printf                                \\\n          \"<a href=\\\"//%s:%s/%s:%s\\\">%s</a>\"  \\\n          \"${NB_SERVER_HOST}\"                 \\\n          \"${NB_SERVER_PORT}\"                 \\\n          \"${__name//' '/%20}\"                \\\n          \"${_url_param_string/&/?}\"          \\\n          \"${__name//\\ /${_NBSP}}\"\n      done\n\n      printf \"</p>\\\\n\"\n    } | {\n      printf \"%s\\\\n\" \"$(_browse_render_header \"${_pagination_options[@]:-}\")\"\n\n      printf \"<div class=\\\"main\\\">\\\\n\"\n\n      cat\n\n      if ((${NB_BROWSE_SUPPORT_LINKS:-1})) &&\n         ((${#_notebook_names[@]} - 40))\n      then\n        printf \"<br /><div align=\\\"center\\\" class=\\\"muted\\\">\"\n        printf \"<a href=\\\"https://github.com/sponsors/xwmx\\\">Sponsor</a>\\\\n\"\n        printf \"<span class=\\\"muted\\\">•</span>\\\\n\"\n        printf \"<a href=\\\"https://www.paypal.com/paypalme/WilliamMelody\\\">Donate</a>\"\n        printf \"</div>\\\\n\"\n      fi\n\n      printf \"</div>\\\\n\"\n    } | {\n      _render --title \"${_ME} browse --notebooks\"\n    }\n  }\n\n  # _browse_render_option_fields\n  #\n  # Usage:\n  #   _browse_render_option_fields <option>...\n  #\n  # Description:\n  #   Render a series of hidden form fields for the given options.\n  _browse_render_option_fields() {\n    local _subcommand_options=(\"${@:-}\")\n\n    local i=\n    for ((i=0; i < ${#_subcommand_options[@]}; i++))\n    do\n      if [[   \"${_subcommand_options[i]}\"           =~ \\--  ]] &&\n         [[ ! \"${_subcommand_options[$((i+1))]:--}\" =~ ^-   ]]\n      then\n        printf \"<input type=\\\"hidden\\\" name=\\\"%s\\\" value=\\\"%s\\\">\\\\n\"  \\\n          \"$(_get_uri --encode \"${_subcommand_options[i]}\")\"          \\\n          \"$(_get_uri --encode \"${_subcommand_options[$((i+1))]}\")\"\n\n        i=\"$((i+1))\"\n      elif [[ -n \"${_subcommand_options[i]:-}\" ]]\n      then\n        printf \"<input type=\\\"hidden\\\" name=\\\"%s\\\">\\\\n\"               \\\n          \"$(_get_uri --encode \"${_subcommand_options[i]}\")\"\n      fi\n    done\n  }\n\n  # _browse_respond()\n  #\n  # Usage:\n  #   _browse_respond\n  #\n  # Description:\n  #   Build a response using standard input and print to standard output.\n  _browse_respond() {\n    # ---------------\n    # Request parsing\n\n    # Request-Line HTTP RFC 2616 §5\n    # https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html\n    local   _request_line=\n    read -r _request_line || _browse_respond_with 400\n\n    # strip trailing CR if it exists\n    _request_line=\"${_request_line%%$'\\r'}\"\n\n    local _request_http_version=\n    local _request_method=\n    local _request_uri=\n\n    IFS=' ' read -r   \\\n      _request_method \\\n      _request_uri    \\\n      _request_http_version <<< \"${_request_line}\"\n\n    if [[ -z \"${_request_method:-}\"       ]] ||\n       [[ -z \"${_request_uri:-}\"          ]] ||\n       [[ -z \"${_request_http_version:-}\" ]]\n    then\n      _browse_respond_with 400\n    fi\n\n    # parse headers and message body\n\n    local _content_length=\n\n    case \"${_request_method:-}\" in\n      POST) local _looking_for_content_length=1 ;;\n      *)    local _looking_for_content_length=0 ;;\n    esac\n\n    local _looking_for_end_of_headers=1\n    local _looking_for_user_agent=1\n    local _request_user_agent=\n    local _terminal_browser=1\n\n    while ((_looking_for_user_agent))     ||\n          ((_looking_for_content_length)) ||\n          ((_looking_for_end_of_headers))\n    do\n      local   __request_line=\n      read -r __request_line\n\n      if ((_looking_for_user_agent))  &&\n         [[ \"${__request_line:-}\"     =~ User-Agent             ]]\n      then # detect browser type\n        # turn on case-insensitive matching\n        shopt -s nocasematch\n        if [[ ! \"${__request_line}\"   =~ (curl|Links|Lynx|w3m)  ]]\n        then\n          _terminal_browser=0\n        fi\n        # turn off case-insensitive matching\n        shopt -u nocasematch\n\n        _looking_for_user_agent=0\n        _request_user_agent=\"${__request_line:-}\"\n      elif ((_looking_for_content_length)) &&\n           [[ \"${__request_line:-}\"   =~ Content-Length ]]\n      then # assign content length\n        _content_length=\"${__request_line##*: }\"\n        _content_length=\"${_content_length%%$'\\r'}\"\n\n        _looking_for_content_length=0\n      elif [[ -z \"${__request_line%%$'\\r'}\"             ]]\n      then\n        _looking_for_end_of_headers=0\n\n        break\n      fi\n    done\n\n    # get message body\n\n    local _message_body=\n\n    if [[ \"${_request_method}\"  == \"POST\"         ]]  &&\n       ((${_content_length:-0}))\n    then\n      read -r -n \"${_content_length}\" _message_body\n    fi\n\n    # serve ace editor files\n\n    if [[ \"${_request_uri}\"     =~ /--ace/.*      ]]\n    then\n      local _target_relative_path=\"${_request_uri#/--ace/}\"\n\n      _browse_respond_with 200 \\\n        \"${NB_DIR}/.assets/ace-builds/src-min-noconflict/${_target_relative_path}\"\n\n      return 0\n    fi\n\n    # serve mathjax files\n\n    if [[ \"${_request_uri}\"     =~ /--mathjax/.*  ]]\n    then\n      local _target_relative_path=\"${_request_uri#/--mathjax/}\"\n\n      if [[   -e \"${NB_DIR}/.assets/MathJax/es5/${_target_relative_path}\"   ]]\n      then\n        _browse_respond_with 200 \\\n          \"${NB_DIR}/.assets/MathJax/es5/${_target_relative_path}\"\n      elif [[ -e \"${NB_DIR}/.assets/MathJax/${_target_relative_path}\"  ]]\n      then\n        _browse_respond_with 200 \\\n          \"${NB_DIR}/.assets/MathJax/${_target_relative_path}\"\n      else\n        _browse_respond_with 404\n      fi\n\n      return 0\n    fi\n\n    # query string\n\n    local _query_string=\n\n    if [[ \"${_request_uri:-}\" =~ \\? ]]\n    then\n      _query_string=\"${_request_uri#*\\?}\"\n    fi\n\n    local _action=\n    local _columns=1\n    local _encoded_local_notebook_path=\n    local _limit=\"${NB_BROWSE_LIMIT:-30}\"\n    local _local_notebook_path=\n    local _page_number=1\n    local _query=\n    local _render_function_options=()\n    local _request_parameters=()\n\n    if [[ -n \"${_query_string:-}\"   ]]\n    then\n      IFS='&' read -r -a _request_parameters <<< \"${_query_string}\"\n\n      local __parameter=\n      for   __parameter in \"${_request_parameters[@]:-}\"\n      do\n        case \"${__parameter:-}\" in\n          url=*)\n            _browse_respond_with 302 \"$(_get_uri --decode \"${__parameter#*=}\")\"\n            ;;\n          --add|--delete|--edit)\n            _action=\"${__parameter#--}\"\n            ;;\n          --columns=*)\n            _columns=\"${__parameter#*=}\"\n            _render_function_options+=(\"--columns\" \"${_columns}\")\n            ;;\n          --gui)\n            _terminal_browser=0\n            ;;\n          --limit=*|-n=*|-num=*|--number=*|--per*page=*)\n            _limit=\"${__parameter#*=}\"\n            _render_function_options+=(\"--limit\" \"${_limit}\")\n            ;;\n          --local=*)\n            _encoded_local_notebook_path=\"${__parameter#*=}\"\n            _local_notebook_path=\"$(\n              _get_uri --decode \"${_encoded_local_notebook_path}\"\n            )\"\n            ;;\n          --page=*)\n            _page_number=\"${__parameter#*=}\"\n            ;;\n          --query=*)\n            _query=\"$(_get_uri --decode \"${__parameter#*=}\")\"\n            ;;\n          --terminal)\n            _terminal_browser=1\n            ;;\n          -*)\n            _render_function_options+=(\"${__parameter%=*}\")\n\n            if [[ \"${__parameter:-}\" =~ \\=    ]]\n            then\n              _render_function_options+=(\"$(\n                _get_uri --decode \"${__parameter#*=}\"\n              )\")\n            fi\n            ;;\n        esac\n      done\n    fi\n\n    # serve raw files\n\n    if [[ \"${_request_uri}\" =~ /--original/.* ]]\n    then\n      local _target_relative_path_with_notebook=\"${_request_uri#/--original/}\"\n      _target_relative_path_with_notebook=\"${_target_relative_path_with_notebook%%\\?*}\"\n\n      _target_relative_path_with_notebook=\"$(\n        _get_uri --decode \"${_target_relative_path_with_notebook:-}\"\n      )\"\n\n      if [[ \"${_target_relative_path_with_notebook}\" =~ ^local/ ]] &&\n         [[ -n \"${_local_notebook_path:-}\"                      ]]\n      then\n        _browse_respond_with 200  \\\n          --original              \\\n          \"${_local_notebook_path:-}/${_target_relative_path_with_notebook#*/}\"\n      else\n        _browse_respond_with 200  \\\n          --original              \\\n          \"${NB_DIR}/${_target_relative_path_with_notebook}\"\n      fi\n\n      return 0\n    fi\n\n    # prepare response\n\n    local _request_uri_base=\"${_request_uri%\\?--*}\" # strip parameters\n    local _target_selector=\"${_request_uri_base#\\/}\"\n\n    _target_selector=\"$(_get_uri --decode \"${_target_selector:-}\")\"\n\n    local _response_url_params=\n\n    if ((_terminal_browser))\n    then\n      _render_function_options+=(\"--terminal\")\n      _response_url_params+=\"&--limit=${_limit}\"\n    fi\n\n    if [[ -n \"${_encoded_local_notebook_path:-}\"  ]]\n    then\n      _render_function_options+=(\"--local\" \"${_encoded_local_notebook_path:-}\")\n      _response_url_params+=\"&--local=${_encoded_local_notebook_path:-}\"\n    fi\n\n    _response_url_params=\"${_response_url_params/&/?}\"\n\n    local _respond_with_200_arguments=(\"--standard-input\")\n\n    case \"${_request_method}\" in\n      HEAD) _respond_with_200_arguments+=(\"--headers\")  ;;\n    esac\n\n    # respond\n\n    if [[ -z \"${_target_selector:-}\"  ]]\n    then\n      _browse_render_notebooks                    \\\n        \"${_render_function_options[@]:-}\"        \\\n        --user-agent \"${_request_user_agent:-}\"   \\\n        | _browse_respond_with 200                \\\n          \"${_respond_with_200_arguments[@]:-}\"\n\n      return 0\n    fi\n\n    if [[ \"${_action:-}\" == \"add\"     ]]\n    then\n      _render_function_options+=(\"${_target_selector:-}\")\n\n      case \"${_request_method:-}\" in\n        GET)\n            _browse_render_add                    \\\n              \"${_render_function_options[@]:-}\"  \\\n              | _browse_respond_with 200          \\\n                \"${_respond_with_200_arguments[@]:-}\"\n          ;;\n        POST)\n          local _new_selector=\n          _new_selector=\"$(\n            _browse_item_create                   \\\n              \"${_render_function_options[@]:-}\"  \\\n              --message-body \"${_message_body:-}\"\n          )\"\n\n          _browse_respond_with 302                \\\n\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_new_selector}${_response_url_params:-}\"\n          ;;\n      esac\n\n      return 0\n    fi\n\n    local _selector_path=\n\n    if [[ \"${_target_selector}\" =~ ^local:  ]]\n    then\n      if [[ -z \"${_local_notebook_path:-}\"  ]]\n      then\n        _browse_respond_with 400\n\n        return 1\n      fi\n\n      _selector_path=\"$(\n        cd \"${_local_notebook_path:-}\"      &&\n          __set_notebook_paths              &&\n          _show \"${_target_selector%%\\?*}\" --path --no-color 2>&1 || :\n      )\"\n    else\n      _selector_path=\"$(\n        _show \"${_target_selector%%\\?*}\" --path 2>/dev/null || :\n      )\"\n    fi\n\n    if [[ -n \"${_selector_path:-}\"    ]]\n    then\n      _render_function_options+=(\"${_selector_path}\")\n    else\n      _browse_respond_with 404\n\n      return 1\n    fi\n\n    if [[ -d \"${_selector_path:-}\"    ]]\n    then\n      if [[ -n \"${_page_number:-}\"    ]]\n      then\n        _render_function_options+=(\"--page\" \"${_page_number}\")\n      fi\n\n      if [[ -n \"${_query:-}\"          ]]\n      then\n        _render_function_options+=(\"--query\" \"${_query}\")\n      fi\n\n      _browse_render_container \"${_render_function_options[@]:-}\"   \\\n        | _browse_respond_with 200 \"${_respond_with_200_arguments[@]:-}\"\n\n      return 0\n    fi\n\n    local _raw_url=\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/--original/\"\n\n    if [[ !   \"${_selector_path:-}\" =~ ^${NB_DIR} ]] &&\n       [[ -n  \"${_encoded_local_notebook_path:-}\" ]] &&\n       [[ -n  \"${_local_notebook_path:-}\"         ]]\n    then\n      _raw_url+=\"local/${_selector_path#\"${_local_notebook_path}\"/}?--local=${_encoded_local_notebook_path}\"\n    else\n      _raw_url+=\"${_selector_path#\"${NB_DIR}\"/}\"\n    fi\n\n    _render_function_options+=(\"--raw-url\" \"${_raw_url}\")\n\n    if [[ \"${_action:-}\" == \"delete\"  ]]\n    then\n      case \"${_request_method:-}\" in\n        GET)\n          _browse_render_delete                 \\\n            \"${_render_function_options[@]:-}\"  \\\n            | _browse_respond_with 200          \\\n              \"${_respond_with_200_arguments[@]:-}\"\n          ;;\n        POST)\n          local _container_id_selector=\n          _container_id_selector=\"$(\n            _get_id_selector \"${_selector_path%/*}\" --notebook\n          )\"\n\n          _browse_item_delete         \\\n            \"${_render_function_options[@]:-}\" &>/dev/null\n\n          _browse_respond_with 302    \\\n\"//${NB_SERVER_HOST}:${NB_SERVER_PORT}/${_container_id_selector}${_response_url_params:-}\"\n          ;;\n      esac\n\n      return 0\n    elif [[ \"${_action:-}\" == \"edit\"  ]]        &&\n         _file_is_text \"${_selector_path:-}\"\n    then\n      if [[ \"${_request_method}\"  == \"POST\"     ]]\n      then\n        _browse_item_update                     \\\n          \"${_render_function_options[@]:-}\"    \\\n          --message-body \"${_message_body:-}\"\n      fi\n\n      _browse_render_edit                       \\\n        \"${_render_function_options[@]:-}\"      \\\n        | _browse_respond_with 200              \\\n          \"${_respond_with_200_arguments[@]:-}\"\n\n      return 0\n    else\n      _browse_render_item                       \\\n        \"${_render_function_options[@]:-}\"      \\\n        \"${_respond_with_200_arguments[@]:-}\"\n\n      return 0\n    fi\n\n    # fall back to 500 response\n\n    _browse_respond_with 500\n\n    return 1\n  }\n\n  # _browse_respond_with()\n  #\n  # Usage:\n  #   _browse_respond_with <status-code> [<path> | <string>] [--headers]\n  #                        [--standard-input]\n  #\n  # Options:\n  #   --headers  Only print headers.\n  #\n  # Description:\n  #   Send a response with <status-code> as status and an optional <file>\n  #   or <string>.\n  #\n  # Exit / Error / Return Status:\n  #   0 (success, true)  HTTP status 200 or 302.\n  #   1 (error,  false)  All others.\n  _browse_respond_with() {\n    local _only_headers=0\n    local _path=\n    local _read_from_standard_input=0\n    local _serve_original_file=0\n    local _status_code=\"${1:-}\"\n    local _string=\n\n    local _date=\n    _date=$(date +\"%a, %d %b %Y %H:%M:%S %Z\")\n\n    local _response_headers=(\n         \"Date: ${_date}\"\n      \"Expires: ${_date}\"\n       \"Server: ${_ME}\"\n    )\n\n    local __arg=\n    for   __arg in \"${@:-}\"\n    do\n      case \"${__arg:-}\" in\n        '')\n          :\n          ;;\n        --*header*)\n          _only_headers=1\n          ;;\n        --original)\n          _serve_original_file=1\n          ;;\n        --standard*input)\n          _read_from_standard_input=1\n          ;;\n        *)\n          if [[     \"${__arg:-}\" =~ ^/  ]] &&\n             [[ -f  \"${__arg:-}\"        ]]\n          then\n            _path=\"${__arg:-}\"\n          fi\n          ;;\n      esac\n    done\n\n    if [[ -n \"${_path:-}\"             ]]\n    then\n      if _file_is_text \"${_path}\" && ((_serve_original_file))\n      then\n        _response_headers+=(\"Content-Type: text/plain; charset=UTF-8\")\n      elif [[ \"${_path}\" =~ \\.svg$    ]]\n      then\n        _response_headers+=(\"Content-Type: image/svg+xml\")\n     elif [[ \"${_path}\" =~ \\.js$      ]]\n      then\n        _response_headers+=(\"Content-Type: application/javascript\")\n      else\n        if _command_exists \"file\"\n        then\n          _response_headers+=(\"Content-Type: $(file -b --mime-type \"${_path}\")\")\n        fi\n      fi\n\n      local _content_length=\n      _content_length=\"$(wc -c < \"${_path}\" | xargs)\"\n\n      if [[ -n \"${_content_length:-}\" ]]\n      then\n        _response_headers+=(\"Content-Length: ${_content_length}\")\n      fi\n    elif _contains \"${_status_code:-}\" \"302\"\n    then\n      _only_headers=1\n      _response_headers+=(\"Location: ${2:-}\")\n    else\n      _string=\"${2:-}\"\n\n      _response_headers+=(\"Content-Type: text/html; charset=UTF-8\")\n    fi\n\n    printf \"%s\\\\r\\\\n\" \\\n      \"HTTP/1.0 ${_status_code} $(_browse_http_response_message \"${_status_code}\")\"\n\n    local __response_header=\n    for   __response_header in \"${_response_headers[@]:-}\"\n    do\n      [[ -n \"${__response_header:-}\"  ]] || continue\n\n      printf \"%s\\\\r\\\\n\" \"${__response_header:-}\"\n    done\n\n    if ! ((_only_headers))\n    then\n      printf \"\\\\r\\\\n\"\n\n      if ((_read_from_standard_input))\n      then\n        cat\n      elif [[ -n \"${_string:-}\"     ]]\n      then\n        printf \"%s\\\\n\" \"${_string}\" | _render\n      elif [[ \"${_path:-}\" =~ ^/    ]]\n      then\n        cat \"${_path}\"\n      else\n        printf                                                            \\\n          \"<div class=\\\"main\\\"><h1 class=\\\"center\\\">%s %s</h1></div>\\\\n\"  \\\n          \"${_status_code}\"                                               \\\n          \"$(_browse_http_response_message \"${_status_code}\")\"            \\\n          | _render\n      fi\n    fi\n\n    if _contains \"${1:-}\" \"200\" \"302\"\n    then\n      return 0\n    else\n      return 1\n    fi\n  }\n\n  # _browse_serve()\n  #\n  # Usage:\n  #   _browse_serve\n  #\n  # Description:\n  #   Start the HTTP server in the background.\n  _browse_serve() {\n    case \"${NB_BROWSE_SERVER_TOOL:-}\" in\n      ncat)\n        (\n\n          ncat                                      \\\n            --exec \"${_MY_PATH} browse --respond\"   \\\n            --keep-open                             \\\n            --listen                                \\\n            \"${NB_SERVER_HOST}\" \"${NB_SERVER_PORT}\"\n        ) &\n        ;;\n      nc|netcat)\n        # TODO: improve concurrency\n        (\n          while true\n          do\n            nc                                      \\\n              --exec \"${_MY_PATH} browse --respond\" \\\n              --listen                              \\\n              --local-port=\"${NB_SERVER_PORT}\"      \\\n              --source=\"${NB_SERVER_HOST}\"\n          done\n        ) &\n        ;;\n      socat)\n        (\n          socat                                                                               \\\n            tcp-listen:\"${NB_SERVER_PORT}\",bind=\"${NB_SERVER_HOST:-localhost}\",reuseaddr,fork \\\n            \"system:{ ${_MY_PATH} browse --respond; }\"\n        ) &\n        ;;\n      accept|bash)\n        # More info: https://github.com/dzove855/Bash-web-server\n        # TODO: improve concurrency\n\n        local _bash_root_path=\"${BASH%/bin/bash}\"\n\n        if [[ -d \"${_bash_root_path}/lib/bash\"    ]]\n        then\n          export BASH_LOADABLE_PATH=\"${_bash_root_path}/lib/bash\"\n        fi\n\n        if [[ -f \"${BASH_LOADABLE_PATH:-}/accept\" ]]\n        then\n          enable -f \"${BASH_LOADABLE_PATH%/}/accept\" accept ||\n            _exit_1 printf \"%s\\\\n\" \"Could not load accept...\"\n        fi\n\n        (\n          local _server_temp_file=\n          _server_temp_file=\"$(_temp file --touch)\"\n\n          while true\n          do\n            : > \"${_server_temp_file:?}\"\n\n            (\n              accept -r \"${NB_SERVER_HOST}\" \"${NB_SERVER_PORT}\" 2>/dev/null\n\n              if [[ -n \"${ACCEPT_FD:-}\"           ]]\n              then\n                if [[ -f \"${_server_temp_file:?}\" ]]\n                then\n                  printf \"1\\\\n\" >> \"${_server_temp_file}\"\n                fi\n\n                \"${_MY_PATH}\" browse --respond <&\"${ACCEPT_FD}\" >&\"${ACCEPT_FD}\"\n\n                exec {ACCEPT_FD}>&- # close connection\n              fi\n            ) &\n\n            until [[ -s \"${_server_temp_file}\"    ]]\n            do\n              :\n            done\n          done\n\n          if [[ -f \"${_server_temp_file:?}\"       ]]\n          then\n            rm \"${_server_temp_file:?}\"\n          fi\n        ) &\n        ;;\n    esac\n\n    local _pid=\"${!}\"\n\n    _temp pid \"${_pid}\"\n\n    sleep 0.05\n  }\n\n  local _action=\n  local _browse_columns=\"${_COLUMNS}\"\n  local _browse_notebooks=0\n  local _browse_limit=\n  local _daemon=0\n  local _force_terminal_request=0\n  local _only_serve=0\n  local _open_gui=0\n  local _print_browse_render_function=\n  local _print_headers=0\n  local _print_output=0\n  local _search_query=\n  local _selector=\n  local _subcommand_options=()\n  local _target_page=\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      a|add|-a|--add|--create|--new|+)\n        _action=\"add\"\n        ;;\n      --and)\n        [[ -n \"${_search_query:-}\" ]] && _search_query=\"${_search_query:-} \"\n\n        case \"${2:-}\" in\n          -t|--tag*)\n            _search_query+=\"--and $(_option_get_tags \"${2:-}\" \"${3:-}\")\"\n\n            shift\n            ;;\n          *)\n            _search_query+=\"--and ${2:-}\"\n            ;;\n        esac\n\n        shift\n        ;;\n      --col*)\n        _browse_columns=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --*container)\n        _print_browse_render_function=\"container\"\n        ;;\n      --daemon)\n        _daemon=1\n        _only_serve=1\n        ;;\n      d|delete|rm|trash|-d|--delete|-)\n        _action=\"delete\"\n        ;;\n      e|edit|-e|--edit)\n        _action=\"edit\"\n        ;;\n      -g|--gui)\n        _open_gui=1\n        ;;\n      --*header)\n        _print_browse_render_function=\"header\"\n        ;;\n      --headers)\n        _print_headers=1\n        ;;\n      --*item)\n        _print_browse_render_function=\"item\"\n        ;;\n      --limit|--num|--number|--per*)\n        _browse_limit=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      ls|list|--ls|--list)\n        : # skip, since this is the default\n        ;;\n      -n)\n        if _option_value_is_present \"${2:-}\"\n        then\n          _browse_limit=\"${2:-}\"\n\n          shift\n        else\n          _browse_notebooks=1\n        fi\n        ;;\n      --notebook*|--nb*)\n        _browse_notebooks=1\n        ;;\n      --or)\n        [[ -n \"${_search_query:-}\" ]] && _search_query=\"${_search_query:-} \"\n\n        case \"${2:-}\" in\n          -t|--tag*)\n            _search_query+=\"--or $(_option_get_tags \"${2:-}\" \"${3:-}\")\"\n\n            shift\n            ;;\n          *)\n            _search_query+=\"--or ${2:-}\"\n            ;;\n        esac\n\n        shift\n        ;;\n      --page)\n        _target_page=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      -p|--print)\n        _print_output=1\n        ;;\n      --render*add)\n        _print_browse_render_function=\"add\"\n        _action=\"add\"\n        ;;\n      --render*delete)\n        _print_browse_render_function=\"delete\"\n        _action=\"delete\"\n        ;;\n      --render*edit)\n        _print_browse_render_function=\"edit\"\n        _action=\"edit\"\n        ;;\n      --render*notebooks)\n        _print_browse_render_function=\"notebooks\"\n        ;;\n      --respond)\n        _browse_respond\n\n        exit 0\n        ;;\n      --search|search|q|-q|--query)\n        if [[ -n \"${2:-}\" ]]\n        then\n          _search_query=\"${2:-}\"\n        else\n          _exit_1 printf                        \\\n            \"%s requires a valid argument.\\\\n\"  \\\n            \"$(_color_primary \"${1:-}\")\"\n        fi\n\n        shift\n        ;;\n      s|serve|-s|--serve*)\n        _only_serve=1\n        ;;\n      -t|--tag*)\n        if [[ -n \"${_search_query:-}\" ]]\n        then\n          _search_query=\"${_search_query:-} \"\n        fi\n\n        _search_query+=\"$(_option_get_tags \"${1:-}\" \"${2:-}\")\"\n\n        _subcommand_options+=(\"${1:-}\" \"${2:-}\")\n\n        shift\n        ;;\n      --terminal)\n        _force_terminal_request=1\n        ;;\n      -*)\n        if [[ \"${1:-}\" =~ ^-+[0-9]+$  ]]\n        then\n          _browse_limit=\"${1##*-}\"\n\n          _subcommand_options+=(--limit \"${_browse_limit:-}\")\n        else\n          _subcommand_options+=(\"${1:-}\")\n\n          if [[ \"${1:-}\" =~ ^-- ]] && _option_value_is_present \"${2:-}\"\n          then\n            _subcommand_options+=(\"${2:-}\")\n\n            shift\n          fi\n        fi\n        ;;\n      *)\n        if [[ -z \"${_selector:-}\"     ]]\n        then\n          _selector=\"${1:-}\"\n        fi\n        ;;\n    esac\n\n    shift\n  done\n\n  if ! ((_browse_notebooks))                                        &&\n       [[   \"${_print_browse_render_function}\"  != \"notebooks\"  ]]  &&\n       [[ ! \"${_selector:-}\"                    =~ :            ]]\n  then\n    _selector=\"$(_notebooks current --name --no-color):${_selector:-}\"\n  fi\n\n  local _arguments=()\n\n  if ! ((_browse_notebooks))                                        &&\n     ! [[ \"${_action:-}\"                        == \"add\"        ]]  &&\n     ! [[ \"${_print_browse_render_function:-}\"  == \"add\"        ]]  &&\n     ! [[ \"${_print_browse_render_function:-}\"  == \"notebooks\"  ]]\n  then\n    _arguments+=(\"$(\n      _show \"${_selector:-}\" --path 2>/dev/null || :\n    )\")\n  fi\n\n  if [[ -z \"${NB_BROWSE_SERVER_TOOL:-}\" ]]\n  then\n    _show \"${_selector:-}\" --render\n    _warn cat <<HEREDOC\nInstall \\`ncat\\`, GNU \\`nc\\` / \\`netcat\\`, \\`socat\\`, or Bash 5.2+ for full browsing and linking:\n$(_color_primary \"https://nmap.org/ncat/\")\n$(_color_primary \"https://en.wikipedia.org/wiki/Netcat\")\n$(_color_primary \"http://www.dest-unreach.org/socat/\")\nHEREDOC\n\n    exit 0\n  fi\n\n  # install enabled assets\n\n  if ! ((${NB_TESTING:-0}))\n  then\n    if ((${NB_ACE_ENABLED:-0}))\n    then\n      if [[ ! -e \"${NB_DIR}/.assets/ace-builds\" ]]\n      then\n        printf \"Installing %s%s\\\\n\"         \\\n          \"$(_color_primary \"Ace Editor\")\"  \\\n          \"$(_color_muted \"...\")\"\n\n        _env install --ace\n      elif [[ -e \"${NB_DIR}/.assets/ace-builds/.git/FETCH_HEAD\" ]]\n      then\n        local _ace_last_modified=\n        _ace_last_modified=\"$(\n          _get_last_modified_timestamp \"${NB_DIR}/.assets/ace-builds/.git/FETCH_HEAD\"\n        )\"\n\n        local _my_last_modified=\n        _my_last_modified=\"$(\n          _get_last_modified_timestamp \"${_MY_PATH}\"\n        )\"\n\n        if (( _my_last_modified > _ace_last_modified ))\n        then\n          printf \"Updating %s%s\\\\n\"           \\\n            \"$(_color_primary \"Ace Editor\")\"  \\\n            \"$(_color_muted \"...\")\"\n\n          _env install --ace\n        fi\n      fi\n    fi\n\n    if   ((${NB_MATHJAX_ENABLED:-0})) &&\n       [[ ! -e \"${NB_DIR}/.assets/MathJax\"    ]]\n    then\n      printf \"Installing %s%s\\\\n\"         \\\n        \"$(_color_primary \"MathJax\")\"     \\\n        \"$(_color_muted \"...\")\"\n\n      _env install --mathjax\n    elif [[ -e \"${NB_DIR}/.assets/MathJax/.git/FETCH_HEAD\"      ]]\n    then\n      local _mathjax_last_modified=\n      _mathjax_last_modified=\"$(\n        _get_last_modified_timestamp \"${NB_DIR}/.assets/MathJax/.git/FETCH_HEAD\"\n      )\"\n\n      local _my_last_modified=\n      _my_last_modified=\"$(\n        _get_last_modified_timestamp \"${_MY_PATH}\"\n      )\"\n\n      if (( _my_last_modified > _mathjax_last_modified ))\n      then\n        printf \"Updating %s%s\\\\n\"         \\\n          \"$(_color_primary \"MathJax\")\"   \\\n          \"$(_color_muted \"...\")\"\n\n        _env install --mathjax\n      fi\n    fi\n  fi\n\n  # build initial request URL parameters and arguments\n\n  local _url_params=()\n\n  if _notebooks current --local\n  then\n    local _encoded_local_path=\n    _encoded_local_path=\"$(_get_uri --encode \"$(_notebooks current --path)\")\"\n\n    _arguments+=(\"--local\" \"${_encoded_local_path}\")\n    _url_params+=(\"--local=${_encoded_local_path}\")\n  fi\n\n  if [[ -n \"${_search_query:-}\" ]]\n  then\n    _arguments+=(\"--query\" \"${_search_query}\")\n\n    local _encoded_query=\n    _encoded_query=\"$(_get_uri --encode \"${_search_query}\")\"\n    _url_params+=(\"--query=${_encoded_query}\")\n  fi\n\n  if [[ -n \"${_action:-}\"       ]]\n  then\n    _arguments+=(\"--${_action}\")\n    _url_params+=(\"--${_action}\")\n  fi\n\n  local i=\n  for ((i=0; i < ${#_subcommand_options[@]}; i++))\n  do\n    [[ -z \"${#_subcommand_options[i]}\" ]] && continue\n\n    _arguments+=(\"${_subcommand_options[i]:-}\")\n\n    if [[   \"${_subcommand_options[i]}\"           =~ \\--  ]] &&\n       [[ ! \"${_subcommand_options[$((i+1))]:--}\" =~ ^-   ]]\n    then\n      local _field=\"${_subcommand_options[i]:-}\"\n      local _value=\"${_subcommand_options[$((i+1))]:--}\"\n\n      _arguments+=(\"${_value}\")\n      _url_params+=(\"${_field}=$(_get_uri --encode \"${_value}\")\")\n\n      i=\"$((i+1))\"\n    else\n      _url_params+=(\"${_subcommand_options[i]:-}\")\n    fi\n  done\n\n  # configure pagination\n\n  if ((_force_terminal_request))  ||\n     ! {\n        ((_open_gui))             ||\n        _web_browser --gui        ||\n        ((_only_serve))\n     }\n  then\n    if [[ -z \"${_browse_limit:-}\"  ]]\n    then # set per page based on terminal height\n      if [[   \"${NB_BROWSER:-}\" =~ links  ]]\n      then\n        _browse_limit=\"$(($(_tput lines) - 9))\"\n      elif [[ \"${NB_BROWSER:-}\" =~ lynx   ]]\n      then\n        _browse_limit=\"$(($(_tput lines) - 10))\"\n      else\n        _browse_limit=\"$(($(_tput lines) - 8))\"\n      fi\n    fi\n\n    if [[ -n \"${_browse_limit:-}\"  ]]\n    then\n      _arguments+=(\"--limit\" \"${_browse_limit}\")\n      _arguments+=(\"--terminal\")\n\n      _url_params+=(\"--limit=${_browse_limit}\")\n      _url_params+=(\"--terminal\")\n    fi\n\n    if [[ -n \"${_browse_columns:-}\"   ]]\n    then\n      _arguments+=(\"--columns\" \"${_browse_columns}\")\n      _url_params+=(\"--columns=${_browse_columns}\")\n    fi\n\n    if [[ -n \"${_target_page:-}\"      ]]\n    then\n      _arguments+=(\"--page\" \"${_target_page:-}\")\n      _url_params+=(\"--page=${_target_page}\")\n    fi\n  fi\n\n  # build initial request URL\n\n  local _request_url_base=\"http://${NB_SERVER_HOST}:${NB_SERVER_PORT}\"\n\n  if [[ \"${_action:-}\" == \"add\" ]]\n  then\n    local _selector_path=\n    _selector_path=\"$(_show \"${_selector:-}\" --path 2>/dev/null || :)\"\n\n    local _notebook_path=\n    _notebook_path=\"$(_notebooks show \"${_selector:-}\" --path 2>/dev/null || :)\"\n\n    if [[ ! \"${_selector}\"      =~ /$                     ]] &&\n       [[ -d \"${_selector_path:-}\"                        ]] &&\n       [[ \"${_selector_path:-}\" != \"${_notebook_path:-}\"  ]]\n    then\n      _selector=\"${_selector:-}/\"\n    fi\n\n    _arguments=(\"${_selector:-}\" \"${_arguments[@]:-}\")\n  fi\n\n  local _request_url_base=\"http://${NB_SERVER_HOST}:${NB_SERVER_PORT}\"\n  local _request_url=\"${_request_url_base}/${_selector:-}\"\n\n  if ((${#_url_params[@]}))\n  then\n    _request_url+=\"?$(_join \"&\" \"${_url_params[@]:-}\")\"\n  fi\n\n  # call functions directly\n\n  if [[ -n \"${_print_browse_render_function:-}\" ]]\n  then\n    case \"${_print_browse_render_function:-}\" in\n      add)        _browse_render_add        \"${_arguments[@]:-}\" ;;\n      container)  _browse_render_container  \"${_arguments[@]:-}\" ;;\n      delete)     _browse_render_delete     \"${_arguments[@]:-}\" ;;\n      edit)       _browse_render_edit       \"${_arguments[@]:-}\" ;;\n      header)     _browse_render_header     \"${_arguments[@]:-}\" ;;\n      item)       _browse_render_item       \"${_arguments[@]:-}\" ;;\n      notebooks)  _browse_render_notebooks  \"${_arguments[@]:-}\" ;;\n    esac\n\n    return 0\n  fi\n\n  # start server\n\n  if ((${_USE_DEBUG:-0}))\n  then\n    _browse_serve             || : # TODO: return status\n  else\n    _browse_serve 2>/dev/null || : # TODO: return status\n  fi\n\n  # request URL\n\n  if ((_print_output))\n  then\n    local _retry_counter=0\n    local _printable_response=\n\n    while [[ -z \"${_printable_response:-}\"  ]]\n    do\n      ((_retry_counter)) && sleep 0.5\n\n      _printable_response=\"$(\n        if ((_print_headers))\n        then\n          curl -s -I      \"${_request_url//' '/%20}\"              || :\n        else\n          _download_from  \"${_request_url//' '/%20}\" --no-chrome  || :\n        fi\n      )\"\n\n      _retry_counter=$((_retry_counter+1))\n    done\n\n    printf \"%s\\\\n\" \"${_printable_response:-}\"\n  elif ((_open_gui))  || _web_browser --gui || ((_only_serve))\n  then\n    local _display_params=\n\n    if _notebooks current --local     ||\n       _notebooks current --selected  ||\n       [[ \"${_selector}\" != \"$(_notebooks current --name):\" ]]\n    then\n      _display_params=\"${_request_url#\"${_request_url_base}\"}\"\n    fi\n\n    printf \"Listening: %s%s\\\\n\"                   \\\n      \"$(_color_primary \"${_request_url_base}\")\"  \\\n      \"${_display_params//\\ /%20}\"\n\n    if ! ((_only_serve))\n    then\n      if _web_browser --gui\n      then\n        _web_browser \"${_request_url:-}\"\n      elif ((_open_gui))\n      then\n        _open_in_gui_app \"${_request_url:-}\"\n      fi\n    fi\n\n    if ((_daemon))\n    then\n      printf \"Press %s%s%s to exit%s\" \\\n        \"$(_color_muted \"<\")\"         \\\n        \"$(_color_primary \"CTRL-C\")\"  \\\n        \"$(_color_muted \">\")\"         \\\n        \"$(_color_muted \"...\")\"\n\n      while true\n      do\n        sleep 1\n      done\n    else\n      while true\n      do\n        read -n 1 -s -r -p \"Press any key to exit$(_color_muted \"...\")\"\n\n        printf \"\\\\n\"\n\n        break\n      done\n    fi\n  else\n    _web_browser \"${_request_url}\"\n  fi\n\n  # make a final request to clear any listening process\n\n  (sleep 0.5 && _download_from \"${_request_url_base}\" --no-chrome &>/dev/null) &\n\n  exit 0\n}\n_alias_subcommand \"browse\" \"b\"\n_alias_subcommand \"browse\" \"br\"\n_alias_subcommand \"browse\" \"browser\"\n\n# copy ################################################################### copy\n\n_describe_copy() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} copy ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [[<notebook>:][<folder-path>/]<filename>]\n\n$(_color_primary \"Description\"):\n  Copy or duplicate an item.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-moving--renaming\n\n$(_color_primary \"See Also\"):\n  ${_ME} help move\n\n$(_color_primary \"Examples\"):\n  ${_ME} copy 321\n  ${_ME} copy 456 example:\n  ${_ME} copy 987 sample/demo.md\n\n$(_color_primary \"Alias\"):\n  ${_ME} duplicate\nHEREDOC\n}\n_copy() {\n  local _source_selector=\"${1:-}\"\n  local _target_selector=\"${2:-}\"\n\n  if [[ -z \"${_source_selector:-}\" ]]\n  then\n    _help \"copy\"\n\n    exit 1\n  fi\n\n  local _source_notebook_path=\n  _source_notebook_path=\"$(\n    _notebooks show \"${_source_selector:-}\" --path 2>/dev/null  ||\n      _notebooks current --path\n  )\"\n\n  local _source_relative_path=\n  _source_relative_path=\"$(\n    _show \"${_source_selector}\" --relative-path 2>/dev/null || :\n  )\"\n\n  local _source_basename=\"${_source_relative_path##*/}\"\n\n  if [[   -z \"${_source_relative_path:-}\"                         ]] ||\n     [[ ! -e \"${_source_notebook_path}/${_source_relative_path}\"  ]]\n  then\n    _warn printf \"Not found: %s\\\\n\" \"$(\n      _color_primary \"${_source_selector:-}\"\n    )\"\n\n    return 1\n  fi\n\n  local _target_folder_path=\n  local _target_notebook_path=\n  local _target_relative_path=\n\n  if [[ -n \"${_target_selector:-}\" ]]\n  then\n    _target_notebook_path=\"$(\n      _notebooks show \"${_target_selector:-}\" --path 2>/dev/null  ||\n        _notebooks current --path\n    )\"\n\n    local _target_folder_relative_path=\n    _target_folder_relative_path=\"$(\n      _selector_resolve_folders \"${_target_selector:-}\" --build   || :\n    )\"\n\n    _target_folder_path=\"${_target_notebook_path:-}/${_target_folder_relative_path:-}\"\n\n    _target_relative_path=\"$(\n      _selector_get_identifier \"${_target_selector:-}\"\n    )\"\n\n    if [[ -z \"${_target_relative_path:-}\" ]]\n    then\n      _target_relative_path=\"${_source_basename:-}\"\n    fi\n\n    _target_relative_path=\"${_target_relative_path%/}\"\n\n    if [[ \"${_target_selector:-}\" =~ /$   ]]\n    then\n      _target_relative_path=\"${_target_relative_path:-}/${_source_basename:-}\"\n    fi\n\n    if [[ -e \"${_target_notebook_path:-}/${_target_relative_path:-}\"  ]]\n    then\n      _warn printf \"Already exists: %s\\\\n\" \"$(\n        _color_primary \"${_target_selector:-}\"\n      )\"\n\n      return 1\n    fi\n  else\n    _target_notebook_path=\"$(\n      _notebooks show \"${_source_selector}\" --path 2>/dev/null    ||\n        _notebooks current --path\n    )\"\n\n    _target_relative_path=\"$(\n      _notebooks current --filename \"${_source_relative_path}\"\n    )\"\n\n    if [[ \"${_target_relative_path:-}\" =~ / ]]\n    then\n      _target_folder_path=\"${_source_notebook_path}/${_target_relative_path%/*}\"\n    else\n      _target_folder_path=\"${_source_notebook_path}\"\n    fi\n  fi\n\n  if _show \"${_source_notebook_path}/${_source_relative_path}\" --type text\n  then # Text can use `_add`.\n    # Print the source contents and pipe to `_add`:\n    _show \"${_source_notebook_path}/${_source_relative_path}\"     \\\n      --no-color --print                                          \\\n      | _add \"${_target_notebook_path}/${_target_relative_path}\" --no-template\n  else\n    local _copy_arguments=(\n      \"${_source_notebook_path}/${_source_relative_path}\"\n      \"${_target_notebook_path}/${_target_relative_path}\"\n    )\n\n    if [[ -d \"${_source_notebook_path}/${_source_relative_path}\"  ]]\n    then\n      _copy_arguments=(\"-R\" \"${_copy_arguments[@]:-}\")\n    fi\n\n    if [[ ! -e \"${_target_folder_path:-}\"   ]]\n    then\n      mkdir -p \"${_target_folder_path:-}\"\n    fi\n\n    cp \"${_copy_arguments[@]:-}\"\n\n    _index add \"${_target_relative_path##*/}\" \"${_target_folder_path}\"\n\n    _git checkpoint \"${_target_notebook_path:-}\" \"[${_ME}] Add: ${_target_relative_path}\"\n\n    printf \"Added: %s\\\\n\" \"$(\n      _show \"${_target_notebook_path}/${_target_relative_path}\" --info-line\n    )\"\n  fi\n}\n_alias_subcommand \"copy\" \"duplicate\"\n\n# do ####################################################################### do\n\n_describe_do() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} do ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n        [<task-number>]\n\n$(_color_primary \"Description\"):\n  Mark a todo or task as done.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-todos\n\n$(_color_primary \"See Also\"):\n  ${_ME} help tasks\n  ${_ME} help todo\n  ${_ME} help undo\n\n$(_color_primary \"Examples\"):\n  ${_ME} do 123\n  ${_ME} do example:sample/321\n  ${_ME} do 543 7\nHEREDOC\n}\n_do() {\n  _todo \"do\" \"${@:-}\"\n}\n_alias_subcommand \"do\" \"done\"\n_alias_subcommand \"do\" \"close\"\n\n# folders ############################################################# folders\n\n_describe_folders() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} folders add [<notebook>:][<folder-path>/]<folder-name>\n  ${_ME} folders delete [<notebook>:][<folder-path>/]<folder-name>\n  ${_ME} folders <list-options>...\n\n$(_color_primary \"Subcommands\"):\n  (default)  List folders.\n  add        Add a new folder.\n  delete     Delete a folder.\n\n$(_color_primary \"Description\"):\n  Add, delete, and list folders.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-folders\n\n$(_color_primary \"See Also\"):\n  ${_ME} help add\n  ${_ME} help delete\n  ${_ME} help list\n  ${_ME} help ls\n\n$(_color_primary \"Examples\"):\n  ${_ME} folders\n  ${_ME} folders add example\n  ${_ME} folders delete example:sample\n\n$(_color_primary \"Alias\"):\n  ${_ME} folder\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} f\nHEREDOC\n}\n_folders() {\n  local _arguments=()\n  local _selector=\n  local _subcommand=\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      add|a|+)\n        _subcommand=\"add\"\n        ;;\n      delete|d|rm|trash|-)\n        _subcommand=\"delete\"\n        ;;\n      list|ls)\n        _subcommand=\"list\"\n        ;;\n      *)\n        if [[ -z \"${_selector:-}\" ]]\n        then\n          _selector=\"${1:-}\"\n        fi\n\n        _arguments+=(\"${1:-}\")\n        ;;\n    esac\n\n    shift\n  done\n\n  if [[ -z \"${_subcommand:-}\"     ]]\n  then\n    _subcommand=\"list\"\n  fi\n\n  if [[ -z \"${_selector:-}\"       ]] &&\n     _contains \"${_subcommand:-}\" \"+\" \"-\" \"a\" \"add\" \"d\" \"delete\" \"rm\" \"trash\"\n  then\n    _help \"folders\"\n\n    return 1\n  fi\n\n  case \"${_subcommand:-}\" in\n    add)\n      _add folder \"${_arguments[@]:-}\"\n      ;;\n    delete)\n      local _target_path=\n      _target_path=\"$(_show \"${_selector:-}\" --path)\"\n\n      if [[ ! -e \"${_target_path:-}\"    ]]\n      then\n        _warn printf \"Not found: %s\\\\n\"     \\\n          \"$(_color_primary \"${_selector:-}\")\"\n\n        return 1\n      elif [[ ! -d \"${_target_path:-}\"  ]]\n      then\n        _warn printf \"Not a folder: %s\\\\n\"  \\\n          \"$(_color_primary \"${_selector:-}\")\"\n\n        return 1\n      fi\n\n      _delete \"${_arguments[@]:-}\"\n      ;;\n    list)\n      if [[ -n \"${_selector:-}\"         ]]\n      then\n        local _selector_path=\n        _selector_path=\"$(_show \"${_selector:-}\" --path)\"\n\n        if [[ -n \"${_selector_path:-}\"  ]]\n        then\n          _notebooks select \"${_selector_path:-}\"\n        fi\n      fi\n\n      _list --type folder \"${_arguments[@]:-}\" --with-pinned\n      ;;\n  esac\n}\n_alias_subcommand \"folders\" \"f\"\n_alias_subcommand \"folders\" \"folder\"\n\n# helpers ############################################################# helpers\n\n_describe_helpers() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} helpers <name> [<options≥...]\n\n$(_color_primary \"Description\"):\n  Call helper functions.\nHEREDOC\n}\n_helpers() {\n  local _name=\"${1:-}\"\n\n  shift\n\n  local _options=(\"${@:-}\")\n\n  case \"${_name:-}\" in\n    *browser*)\n      _web_browser                    \"${_options[@]:-}\"\n      ;;\n    build*|*related*)\n      _build_related_list             \"${_options[@]:-}\"\n      ;;\n    *decryption*)\n      _get_decryption_tool            \"${_options[@]:-}\"\n      ;;\n    decrypt*)\n      _decrypt_file                   \"${_options[@]:-}\"\n      ;;\n    download*)\n      _download_from                  \"${_options[@]:-}\"\n      ;;\n    edit*)\n      _edit_file                      \"${_options[@]:-}\"\n      ;;\n    encrypt*)\n      _encrypt_file                   \"${_options[@]:-}\"\n      ;;\n    *archive*)\n      _file_is_archive                \"${_options[@]:-}\"\n      ;;\n    *audio*)\n      _file_is_audio                  \"${_options[@]:-}\"\n      ;;\n    *bookmark*)\n      _file_is_bookmark               \"${_options[@]:-}\"\n      ;;\n    *document*)\n      _file_is_document               \"${_options[@]:-}\"\n      ;;\n    *encrypted*)\n      _file_is_encrypted              \"${_options[@]:-}\"\n      ;;\n    *image*)\n      _file_is_image                  \"${_options[@]:-}\"\n      ;;\n    *text*)\n      _file_is_text                   \"${_options[@]:-}\"\n      ;;\n    *video*)\n      _file_is_video                  \"${_options[@]:-}\"\n      ;;\n    *content*)\n      _get_content                    \"${_options[@]:-}\"\n      ;;\n    *d*selector)\n      _get_id_selector                \"${_options[@]:-}\"\n      ;;\n    *hash*)\n      _get_hash                       \"${_options[@]:-}\"\n      ;;\n    *http*)\n      _get_http_status                \"${_options[@]:-}\"\n      ;;\n    *last*mod*)\n      _get_last_modified_timestamp    \"${_options[@]:-}\"\n      ;;\n    *unique*basename*|*unique*relative*)\n      _get_unique_relative_path       \"${_options[@]:-}\"\n      ;;\n    *unique*path*)\n      _get_unique_path                \"${_options[@]:-}\"\n      ;;\n    *highlight*|*syntax*)\n      _highlight_syntax_if_available  \"${_options[@]:-}\"\n      ;;\n    join)\n      _join                           \"${_options[@]:-}\"\n      ;;\n    less*|*prompt)\n      _less_prompt                    \"${_options[@]:-}\"\n      ;;\n    line*wrap*off|unwrap)\n      _wrap off                       \"${_options[@]:-}\"\n      ;;\n    line*wrap*on|wrap)\n      _wrap on                        \"${_options[@]:-}\"\n      ;;\n    list*files)\n      _list_files                     \"${_options[@]:-}\"\n      ;;\n    *line)\n      _print_line                     \"${_options[@]:-}\"\n      ;;\n    *norm*|*options*)\n      _print_normalized_options       \"${_options[@]:-}\"\n      ;;\n    *padding)\n      _print_padding                  \"${_options[@]:-}\"\n      ;;\n    pandoc)\n      _pandoc                         \"${_options[@]:-}\"\n      ;;\n    *piped*|*input*)\n      _piped_input                    \"${_options[@]:-}\"\n      ;;\n    *print*welcome|welcome)\n      _print_welcome                  \"${_options[@]:-}\"\n      ;;\n    *option*|*get*tag*)\n      _option_get_tags                \"${_options[@]:-}\"\n      ;;\n    render)\n      _render                         \"${_options[@]:-}\"\n      ;;\n    resolve*links)\n      _resolve_links                  \"${_options[@]:-}\"\n      ;;\n    *selector*folder*)\n      _selector_resolve_folders       \"${_options[@]:-}\"\n      ;;\n    *selector*path*)\n      _selector_resolve_path          \"${_options[@]:-}\"\n      ;;\n    spinner)\n      _spinner                        \"${_options[@]:-}\"\n      ;;\n    *email)\n      _string_is_email                \"${_options[@]:-}\"\n      ;;\n    *uri*)\n      _get_uri                        \"${_options[@]:-}\"\n      ;;\n    *url)\n      _string_is_url                  \"${_options[@]:-}\"\n      ;;\n    *)\n      _exit_1 _help \"helpers\"\n      ;;\n  esac\n}\n\n# plugins ############################################################# plugins\n\n_describe_plugins() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} plugins [<name>] [--paths]\n  ${_ME} plugins install [<path> | <url>] [--force]\n  ${_ME} plugins uninstall <name> [--force]\n\n$(_color_primary \"Options\"):\n  --force  Skip the confirmation prompt.\n  --paths  Print the full path to each plugin.\n\n$(_color_primary \"Subcommands\"):\n  (default)  List plugins.\n  install    Install a plugin from a <path> or <url>.\n  uninstall  Uninstall the specified plugin.\n\n$(_color_primary \"Description\"):\n  Manage plugins and themes.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-plugins\n\n$(_color_primary \"Plugin Extensions\"):\n  .${_ME}-theme   Plugins defining color themes.\n  .${_ME}-plugin  Plugins defining new subcommands and functionality.\n\n$(_color_primary \"See Also\"):\n  ${_ME} help subcommands\n\n$(_color_primary \"Alias\"):\n  ${_ME} plugin\nHEREDOC\n}\n_plugins() {\n  local _basename=\n  local _force=0\n  local _name=\n  local _path=\n  local _print_paths=0\n  local _subcommand=\n  local _url=\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      -f|--force|--skip*|-y|--yes)\n        _force=1\n        ;;\n      --path*)\n        _print_paths=1\n        ;;\n      *)\n        if [[ \"${__arg}\" =~ ^install$|^uninstall$ ]]\n        then\n          _subcommand=\"${__arg}\"\n        elif [[ \"${_subcommand}\" == \"install\"   ]]\n        then\n          if [[ \"${__arg:-}\" =~ (^http|^file\\:) ]]\n          then\n            _url=\"${__arg}\"\n          else\n            _path=\"${__arg}\"\n          fi\n        else\n          _name=\"${__arg}\"\n        fi\n        ;;\n    esac\n  done\n\n  case \"${_subcommand}\" in\n    install)\n      [[ ! -e \"${NB_DIR}/.plugins\"      ]] && mkdir \"${NB_DIR}/.plugins\"\n\n      if [[ -n \"${_path:-}\"             ]]\n      then\n        if ! [[ -f \"${_path:-}\"         ]] ||\n           ! [[ \"${_path}\" =~ ${_ME}\\-  ]]\n        then\n          _exit_1 printf \"Not a valid \\`%s\\` plugin: %s\\\\n\" \"${_ME}\" \"${_path}\"\n        fi\n\n        _basename=\"$(basename -- \"${_path}\")\"\n\n        if [[ -f \"${NB_DIR}/.plugins/${_basename}\"  ]]\n        then\n          _warn printf \"Plugin already installed: %s\\\\n\" \"${_basename}\"\n\n          if ! ((_force))\n          then\n            while true\n            do\n              local __yn=\n              IFS='' read -r -e -d $'\\n' -p         \\\n\"$(_color_primary \"Reinstall?\") $(_color_brackets \"y/N\") \" __yn\n\n              case \"${__yn}\" in\n                [Yy]*)\n                  break\n                  ;;\n                *)\n                  printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n                  exit 0\n                  ;;\n              esac\n            done\n          fi\n        fi\n\n        if cp \"${_path}\" \"${NB_DIR}/.plugins/${_basename}\"\n        then\n          printf \"Plugin installed:\\\\n%s\\\\n\"        \\\n            \"$(_color_primary \"${NB_DIR}/.plugins/${_basename}\")\"\n        else\n          _exit_1 printf \"Unable to install plugin: %s\\\\n\" \"${_path}\"\n        fi\n      else\n        _basename=\"$(basename -- \"${_url}\" | tr -d '[:space:]')\"\n\n        if [[ \"${_url:-}\" =~ https\\:\\/\\/github.com ]]\n        then\n          _url=\"$(\n            printf \"%s\\\\n\" \"${_url}\"  \\\n              | LC_ALL=C sed          \\\n                -e 's/\\/blob//g'      \\\n                -e 's/https:\\/\\/github.com/https:\\/\\/raw.githubusercontent.com/g'\n          )\"\n        fi\n\n        if _download_from \"${_url}\" \"${NB_DIR}/.plugins/${_basename}\" --no-chrome\n        then\n          printf \"Plugin installed:\\\\n%s\\\\n\"  \\\n            \"$(_color_primary \"${NB_DIR}/.plugins/${_basename}\")\"\n        else\n          _exit_1 printf \"Unable to download and install: %s\\\\n\"  \"${_url}\"\n        fi\n      fi\n      ;;\n    uninstall)\n      local _plugin_path=\n\n      if ! _plugin_path=\"$(_plugins \"${_name}\" --paths 2>/dev/null)\"  ||\n           [[ -z \"${_plugin_path:-}\"  ]]                              ||\n         ! [[ -f \"${_plugin_path}\"    ]]\n      then\n        _exit_1 printf \"Plugin not found: %s\\\\n\" \"$(_color_primary \"${_name}\")\"\n      fi\n\n      if ! ((_force))\n      then\n        cat <<HEREDOC\nUninstalling plugin. Warning: This will permanently delete the following file:\n$(_color_primary \"${_plugin_path}\")\nHEREDOC\n        while true\n        do\n          local __yn=\n          IFS='' read -r -e -d $'\\n' -p \\\n\"$(_color_primary \"Proceed?\") $(_color_brackets \"y/N\") \" __yn\n\n          case \"${__yn}\" in\n            [Yy]*)\n              break\n              ;;\n            *)\n              printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n              exit 0\n              ;;\n          esac\n        done\n      fi\n\n      if [[ -f \"${_plugin_path}\" ]] && rm \"${_plugin_path:?}\"\n      then\n        printf \"Plugin successfully uninstalled:\\\\n%s\\\\n\" \\\n          \"$(_color_primary \"${_plugin_path}\")\"\n      else\n        _exit_1 printf \"Unable to uninstall plugin:\\\\n%s\\\\n\" \"${_plugin_path}\"\n      fi\n      ;;\n    *)\n      local _query=\"*${_ME}-*\"\n\n      if [[ -n \"${_name}\" ]]\n      then\n        _query=\"${_name}\"\n      fi\n\n      if [[ ! -e \"${NB_DIR}/.plugins\" ]]\n      then\n        (return 1)\n      else\n        {\n          if ((_print_paths))\n          then\n            find \"${NB_DIR}\"/.plugins \\\n              ! \\( -type d \\)         \\\n              -name \"${_query}\"\n          else\n            find \"${NB_DIR}\"/.plugins \\\n              ! \\( -type d \\)         \\\n              -name \"${_query}\"       \\\n              -exec basename {} \\;\n          fi\n        } | {\n          # `grep` for non-0 `find`. More info: https://serverfault.com/a/855083\n          grep . | sort\n        }\n      fi || if [[ -n \"${_name:-}\" ]]\n            then\n              _exit_1 printf \"No matching plugins found: %s\\\\n\" \"${_name}\"\n            else\n              _exit_1 printf \"No plugins found.\\\\n\"\n            fi\n      ;;\n  esac\n}\n_alias_subcommand \"plugins\" \"plugin\"\n\n# remote ############################################################### remote\n\n_describe_remote() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} remote\n  ${_ME} remote branches [<url>]\n  ${_ME} remote delete <branch-name>\n  ${_ME} remote remove\n  ${_ME} remote rename [<branch-name>] <name>\n  ${_ME} remote reset <branch-name>\n  ${_ME} remote set <url> [<branch-name>]\n\n$(_color_primary \"Subcommands\"):\n  (default)  Print the remote URL and branch for the notebook.\n  branches   List branches on the current or given remote.\n  delete     Delete <branch-name> from the remote.\n             Caveat: only orphan branches can be deleted.\n  remove     Remove the remote URL from the notebook.\n             Alias: \\`unset\\`\n  rename     Rename the current orphan branch or <branch-name> to <name>.\n             Caveat: only orphan branches can be renamed.\n  reset      Reset <branch-name> on the remote to a blank initial state.\n  set        Set the remote URL and branch for the notebook.\n\n$(_color_primary \"Description\"):\n  Configure the remote repository URL and branch for the current notebook.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-git-sync\n  ${_README_URL}#-revision-history\n\n$(_color_primary \"See Also\"):\n  ${_ME} help history\n  ${_ME} help notebooks\n  ${_ME} help status\n  ${_ME} help sync\n\n$(_color_primary \"Examples\"):\n  ${_ME} remote set https://github.com/example/example.git\n  ${_ME} remote remove\n  ${_ME} example-notebook:remote set https://github.com/example/example.git\nHEREDOC\n}\n_remote() {\n  local _new_branch=\n  local _new_remote_url=\n  local _only_url=0\n  local _remote_branch_name=\n  local _rename_arguments=()\n  local _skip_confirmation=0\n  local _skip_preamble=0\n  local _subcommand=\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      --skip*confirm*)  _skip_confirmation=1    ;;\n      --skip*preamble)  _skip_preamble=1        ;;\n      --url|url)        _only_url=1             ;;\n      *)\n        case \"${_subcommand:-}\" in\n          '') _subcommand=\"${1:-}\"              ;;\n          add|branches|set)\n            if [[   -z \"${_new_remote_url:-}\"   ]]\n            then\n              _new_remote_url=\"${1:-}\"\n            elif [[ -z \"${_new_branch:-}\"       ]]\n            then\n              _new_branch=\"${1:-}\"\n            fi\n            ;;\n          delete|reset|rm|trash)\n            _remote_branch_name=\"${1:-}\"\n            ;;\n          rename)\n            _rename_arguments+=(\"${1:-}\")\n            ;;\n        esac\n        ;;\n    esac\n\n    shift\n  done\n\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  local _current_branch=\n  _current_branch=\"$(\n    git -C \"${_notebook_path}\" rev-parse --abbrev-ref HEAD\n  )\"\n\n  local _current_remote_url=\n  _current_remote_url=\"$(\n    git -C \"${_notebook_path:-}\" remote get-url origin 2>/dev/null || :\n  )\"\n\n  local _remote_exists=0\n\n  if [[ -n \"${_current_remote_url:-}\"           ]]\n  then\n    _remote_exists=1\n  fi\n\n  case \"${_subcommand:-}\" in\n    branches)\n      {\n        if [[ -n \"${_new_remote_url:-}\"         ]]\n        then\n          git -C \"${_notebook_path}\" ls-remote  \\\n            --heads \"${_new_remote_url:-}\"      \\\n            2>/dev/null                         \\\n            | LC_ALL=C sed \"s/.*\\///g\"\n        elif ((_remote_exists))\n        then\n          git -C \"${_notebook_path}\" ls-remote  \\\n            --heads                             \\\n            2>/dev/null                         \\\n            | LC_ALL=C sed \"s/.*\\///g\"\n        else\n          _exit_1 printf \"No remote configured.\\\\n\"\n        fi\n      } | {\n        local _highlight_matching_branch=0\n\n        if ((_remote_exists))                   &&\n           [[ -z  \"${_new_remote_url:-}\"  ]]    ||\n           [[     \"${_new_remote_url:-}\"  ==    \"${_current_remote_url:-}\"  ]]\n        then\n          _highlight_matching_branch=1\n        fi\n\n        local         __line=\n        while read -r __line\n        do\n          if ((_highlight_matching_branch))     &&\n             [[   \"${__line:-}\"           ==    \"${_current_branch:-}\"      ]]\n          then\n            printf \"%s\\\\n\" \"$(_color_primary \"${__line}\")\"\n          else\n            printf \"%s\\\\n\" \"${__line}\"\n          fi\n        done\n      }\n\n      return 0\n      ;;\n    delete)\n      if ! ((_remote_exists))\n      then\n        _exit_1 printf \"No remote configured.\\\\n\"\n      fi\n\n      if [[ -z \"${_remote_branch_name:-}\"       ]]\n      then\n        _exit_1 _help \"remote\"\n      fi\n\n      # TODO: combine into single `ls-remote` operation\n      local _remote_branches=()\n      _remote_branches=($(\n        git -C \"${_notebook_path}\" ls-remote        \\\n          --heads \"${_current_remote_url:-}\"        \\\n           2>/dev/null                              \\\n          | LC_ALL=C sed \"s/.*\\///g\" || :\n      ))\n\n      local _primary_remote_branch=\n      _primary_remote_branch=\"$(\n        git -C \"${_notebook_path}\" ls-remote        \\\n          --symref \"${_current_remote_url:-}\" HEAD  \\\n          2>/dev/null                               \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}' || :\n      )\"\n\n      if [[ -z \"${_remote_branches[*]:-}\"       ]] ||\n         [[ -z \"${_primary_remote_branch:-}\"    ]]\n      then\n        _exit_1 printf \"Unable to contact remote.\\\\n\"\n      fi\n\n      if ! _contains \"${_remote_branch_name:-}\" \"${_remote_branches[@]:-}\"\n      then\n        _exit_1 printf \"Remote branch not found: %s\\\\n\" \\\n          \"${_remote_branch_name:-}\"\n      fi\n\n      if [[ \"${_remote_branch_name:-}\" == \"${_primary_remote_branch:-}\" ]]\n      then\n        _remote reset \"${_remote_branch_name:-}\"\n      fi\n\n      printf \"Deleting remote branch: %s\\\\n\"    \\\n        \"$(_color_primary \"${_remote_branch_name:-}\")\"\n\n      _print_line \"-----------------------\"\n\n      while true\n      do\n        local __yn=\n        IFS='' read -r -e -d $'\\n' -p           \\\n\"$(_color_primary \"Proceed?\") $(_color_brackets \"y/N\") \" __yn\n\n        case \"${__yn}\" in\n          [Yy]*)\n            break\n            ;;\n          *)\n            printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n            exit 0\n            ;;\n        esac\n      done\n\n      git -C \"${_notebook_path:-}\" push origin  \\\n        \":${_remote_branch_name}\"  --force      \\\n        &>/dev/null                             ||\n        _exit_1 printf \"Unable to delete remote branch: %s\\\\n\" \\\n          \"${_remote_branch_name}\"\n\n      printf \"Remote branch deleted.\\\\n\"\n      ;;\n    remove|rm|unset)\n      if ((_remote_exists))\n      then\n        printf \"Removing remote: %s\\\\n\"         \\\n          \"$(_color_primary \"${_current_remote_url:-}\")\"\n\n        if ! ((_skip_confirmation))\n        then\n          while true\n          do\n            local __yn=\n            IFS='' read -r -e -d $'\\n' -p       \\\n\"$(_color_primary \"Proceed?\") $(_color_brackets \"y/N\") \" __yn\n\n            case \"${__yn}\" in\n              [Yy]*)\n                break\n                ;;\n              *)\n                printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n                exit 0\n                ;;\n            esac\n          done\n        fi\n\n        # TODO: combine into single `ls-remote` operation\n        local _remote_branches=()\n        _remote_branches=($(\n          git -C \"${_notebook_path}\" ls-remote        \\\n            --heads \"${_current_remote_url:-}\"        \\\n             2>/dev/null                              \\\n            | LC_ALL=C sed \"s/.*\\///g\" || :\n        ))\n\n        local _primary_remote_branch=\n        _primary_remote_branch=\"$(\n          git -C \"${_notebook_path}\" ls-remote        \\\n            --symref \"${_current_remote_url:-}\" HEAD  \\\n            2>/dev/null                               \\\n            | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}' || :\n        )\"\n\n        if [[ -z \"${_remote_branches[*]:-}\"       ]] ||\n           [[ -z \"${_primary_remote_branch:-}\"    ]]\n        then\n          _warn printf \"Unable to contact remote.\\\\n\"\n        else\n          local _delete_remote_branch=0\n\n          if _contains \"${_current_branch}\" \"${_remote_branches[@]:-}\"\n          then\n            local _delete_action=\"Remove\"\n\n            if [[ \"${_current_branch:-}\" == \"${_primary_remote_branch:-}\" ]]\n            then\n              _delete_action=\"Reset\"\n            fi\n\n            local _branch_delete_prompt=\n            _branch_delete_prompt=\"\\\n$(_color_primary \"${_delete_action} branch on remote?\") ($(_color_primary \"${_current_branch}\"))\"\n\n            while true\n            do\n              local __yn=\n              IFS='' read -r -e -d $'\\n' -p             \\\n                \"${_branch_delete_prompt} $(_color_brackets \"y/N\") \" __yn\n\n              case \"${__yn}\" in\n                [Yy]*)\n                  _delete_remote_branch=1\n\n                  break\n                  ;;\n                q*|exit)\n                  printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n                  exit 0\n                  ;;\n                *)\n                  break\n                  ;;\n              esac\n            done\n          fi\n\n          if ((_delete_remote_branch))\n          then\n            if [[ \"${_current_branch}\" == \"${_primary_remote_branch}\" ]]\n            then\n              _remote reset \"${_current_branch}\"        \\\n                <<< \"y${_NEWLINE}\" 1>/dev/null          &&\n                printf \"Remote branch reset: %s\\\\n\"     \\\n                  \"$(_color_primary \"${_current_branch}\")\"\n            else\n              _remote delete \"${_current_branch}\"       \\\n                <<< \"y${_NEWLINE}\" 1>/dev/null          &&\n                printf \"Remote branch deleted: %s\\\\n\"   \\\n                  \"$(_color_primary \"${_current_branch}\")\"\n            fi\n          fi\n        fi\n\n        git -C \"${_notebook_path:-}\" remote rm origin &&\n          printf \"Remote removed.\\\\n\"\n\n        return 0\n      else\n        _exit_1 printf \"No remote configured.\\\\n\"\n      fi\n      ;;\n    rename)\n      local _target_branch_name=\n\n      local _remote_branches=()\n\n      if ((_remote_exists))\n      then\n        _remote_branches=($(\n          git -C \"${_notebook_path}\" ls-remote  \\\n            --heads \"${_current_remote_url:-}\"  \\\n            | LC_ALL=C sed \"s/.*\\///g\" || :\n        ))\n\n        if [[ -z \"${_remote_branches[*]:-}\"     ]]\n        then\n          _exit_1 printf \"Unable to contact remote.\\\\n\"\n        fi\n      fi\n\n      if [[ \"${#_rename_arguments[@]}\" -gt 1    ]]\n      then\n        if _contains \"${_rename_arguments[0]:-}\" \"${_remote_branches[@]:-}\"\n        then\n          _remote_branch_name=\"${_rename_arguments[0]:-}\"\n          _target_branch_name=\"${_rename_arguments[1]:-}\"\n        else\n          _exit_1 printf                        \\\n            \"Remote branch not found: %s\\\\n\"    \\\n            \"$(_color_primary \"${_rename_arguments[0]:-}\")\"\n        fi\n      else\n        _target_branch_name=\"${_rename_arguments[0]:-}\"\n      fi\n\n      if [[ -z \"${_target_branch_name:-}\"       ]]\n      then\n        _exit_1 _help \"remote\"\n      fi\n\n      if _contains \"${_target_branch_name:-}\" \"${_remote_branches[@]:-}\"\n      then\n        _exit_1 printf \"A remote branch with that name already exists.\\\\n\"\n      fi\n\n      local _remote_head_branch=\n\n      if [[ -n \"${_current_remote_url:-}\"       ]]\n      then\n        _remote_head_branch=\"$(\n          git ls-remote --symref \"${_current_remote_url:-}\" HEAD      \\\n            | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n        )\"\n      fi\n\n      if [[ -n  \"${_remote_head_branch:-}\"                            ]] &&\n         [[     \"${_remote_branch_name:-\"${_current_branch}\"}\" ==     \\\n                  \"${_remote_head_branch:-}\"                          ]]\n      then\n        _exit_1 printf \"Only orphan branches can be renamed.\\\\n\"\n      fi\n\n      if [[ -n \"${_remote_branch_name:-}\"                             ]] &&\n         [[    \"${_remote_branch_name:-}\" != \"${_current_branch:-}\"   ]]\n      then\n        printf      \"Renaming remote branch\\\\n\"\n        _print_line \"----------------------\"\n      else\n        printf      \"Renaming current branch\\\\n\"\n        _print_line \"-----------------------\"\n      fi\n\n      printf        \"From: %s\\\\n\" \"${_remote_branch_name:-\"${_current_branch:-}\"}\"\n      printf        \"To:   %s\\\\n\" \"$(_color_primary \"${_target_branch_name:-}\")\"\n\n      _print_line   \"-----------\"\n\n      while true\n      do\n        local __yn=\n        IFS='' read -r -e -d $'\\n' -p                     \\\n\"$(_color_primary \"Proceed?\") $(_color_brackets \"y/N\") \" __yn\n\n        case \"${__yn}\" in\n          [Yy]*)\n            break\n            ;;\n          *)\n            printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n            exit 0\n            ;;\n        esac\n      done\n\n      if ((_remote_exists))\n      then\n        if [[   -z  \"${_remote_branch_name:-}\"                           ]] ||\n           [[       \"${_remote_branch_name:-}\" == \"${_current_branch:-}\" ]]\n        then\n          {\n            git -C \"${_notebook_path}\" checkout           \\\n              -b \"${_target_branch_name}\"                 \\\n              \"${_current_branch}\"                        &&\n              git -C \"${_notebook_path}\" push             \\\n                -u origin \"${_target_branch_name}\"        &&\n              git -C \"${_notebook_path}\" branch           \\\n                -d \"${_current_branch}\"                   &&\n              git -C \"${_notebook_path}\" push             \\\n                --delete origin \"${_current_branch}\"      &&\n              git -C \"${_notebook_path}\" remote prune origin\n          } &>/dev/null || _exit_1 printf \"Unable to rename branch.\\\\n\"\n        elif [[ -n  \"${_remote_branch_name:-}\"                           ]] &&\n             [[     \"${_remote_branch_name:-}\" != \"${_current_branch:-}\" ]]\n        then\n          local _temp_repo_path=\"${_NB_TEMP_DIRECTORY}/${RANDOM}\"\n\n          {\n            cd \"${_NB_TEMP_DIRECTORY}\"                    &&\n              git clone --no-local                        \\\n                --single-branch                           \\\n                --branch \"${_remote_branch_name:-}\"       \\\n                \"${_current_remote_url}\"                  \\\n                \"${_temp_repo_path}\"                      &&\n              git -C \"${_temp_repo_path}\" checkout        \\\n                -b \"${_target_branch_name}\"               \\\n                \"${_remote_branch_name}\"                  &&\n              git -C \"${_temp_repo_path}\" push            \\\n                -u origin \"${_target_branch_name}\"        &&\n              git -C \"${_temp_repo_path}\" branch          \\\n                -d \"${_remote_branch_name}\"               &&\n              git -C \"${_temp_repo_path}\" push            \\\n                --delete origin \"${_remote_branch_name}\"  &&\n              git -C \"${_temp_repo_path}\" remote prune origin\n          } &>/dev/null || _exit_1 printf \"Unable to rename branch.\\\\n\"\n        fi\n      else\n        git -C \"${_notebook_path}\" branch                 \\\n          -m \"${_target_branch_name}\"                     \\\n          &>/dev/null || _exit_1 printf \"Unable to rename branch.\\\\n\"\n      fi\n\n      printf \"Renamed to: %s\\\\n\" \"$(_color_primary \"${_target_branch_name}\")\"\n      ;;\n    reset)\n      if ! ((_remote_exists))\n      then\n        _exit_1 printf \"No remote configured.\\\\n\"\n      fi\n\n      if [[ -z \"${_remote_branch_name:-}\"     ]]\n      then\n        _exit_1 _help \"remote\"\n      fi\n\n      local _remote_branches=()\n      _remote_branches=($(\n        git -C \"${_notebook_path}\" ls-remote  \\\n          --heads \"${_current_remote_url:-}\"  \\\n           2>/dev/null                        \\\n          | LC_ALL=C sed \"s/.*\\///g\" || :\n      ))\n\n      if [[ -z \"${_remote_branches[*]:-}\"     ]]\n      then\n        _exit_1 printf \"Unable to contact remote.\\\\n\"\n      fi\n\n      if ! _contains \"${_remote_branch_name:-}\" \"${_remote_branches[@]:-}\"\n      then\n        _exit_1 printf \"Remote branch not found: %s\\\\n\" \\\n          \"${_remote_branch_name:-}\"\n      fi\n\n      printf \"Resetting remote branch: %s\\\\n\"           \\\n        \"$(_color_primary \"${_remote_branch_name:-}\")\"\n\n      _print_line \"------------------------\"\n\n      while true\n      do\n        local __yn=\n        IFS='' read -r -e -d $'\\n' -p         \\\n\"$(_color_primary \"Proceed?\") $(_color_brackets \"y/N\") \" __yn\n\n        case \"${__yn}\" in\n          [Yy]*)\n            break\n            ;;\n          *)\n            printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n            exit 0\n            ;;\n        esac\n      done\n\n      local _blank_repo_path=\"${_NB_TEMP_DIRECTORY:-/tmp}/${RANDOM}\"\n\n      mkdir -p \"${_blank_repo_path}\"\n      cd \"${_blank_repo_path}\" || return 1\n\n      {\n        git -C \"${_blank_repo_path}\" init             \\\n            --initial-branch \"${_remote_branch_name}\" &&\n          touch \"${_blank_repo_path}/.index\"          &&\n          git -C \"${_blank_repo_path}\" add --all      &&\n          git -C \"${_blank_repo_path}\" commit         \\\n            -a -m \"[${_ME}] Initialize\"               &&\n          git -C \"${_blank_repo_path}\" remote add     \\\n            origin \"${_current_remote_url:-}\"         &&\n          git -C \"${_blank_repo_path}\" push origin    \\\n            \"${_remote_branch_name}\" --force\n      } &>/dev/null ||\n        _exit_1 printf \"Unable to reset remote branch: %s\\\\n\" \\\n          \"$(_color_primary \"${_remote_branch_name}\")\"\n\n      printf \"Remote branch reset.\\\\n\"\n      ;;\n    set|add)\n      if [[ -z \"${_new_remote_url:-}\" ]]\n      then\n        _exit_1 _help \"remote\"\n      fi\n\n      if [[ -z \"${_new_branch:-}\"     ]]\n      then\n        _new_branch=\"${_current_branch}\"\n      fi\n\n      if ! ((_skip_preamble))\n      then\n        if ((_remote_exists))\n        then\n          printf \"Updating remote for: %s\\\\n\" \\\n            \"$(_color_primary \"$(_notebooks current --name)\")\"\n\n          printf \"From:   %s (%s)\\\\n\" \"${_current_remote_url}\" \"${_current_branch}\"\n\n          _print_line \"Updating remote for: $(_notebooks current --name)\"\n        else\n          printf \"Adding remote to: %s\\\\n\"    \\\n            \"$(_color_primary \"$(_notebooks current --name)\")\"\n\n          _print_line \"Adding remote to: $(_notebooks current --name)\"\n        fi\n\n        printf \"URL:    %s\\\\n\" \"$(_color_primary \"${_new_remote_url}\")\"\n        printf \"Branch: %s\\\\n\" \"$(_color_primary \"${_new_branch}\")\"\n\n        _print_line \"--------------\"\n\n        while true\n        do\n          local __yn=\n\n          IFS='' read -r -e -d $'\\n' -p                               \\\n            \"$(_color_primary \"Proceed?\") $(_color_brackets \"y/N\") \"  \\\n            __yn\n\n          case \"${__yn:-}\" in\n            [Yy]*)\n              break\n              ;;\n            *)\n              printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n              exit 0\n              ;;\n          esac\n        done\n      fi\n\n      local _remote_branches=()\n      _remote_branches=($(\n        git -C \"${_notebook_path}\" ls-remote    \\\n          --heads \"${_new_remote_url:-}\"        \\\n          | LC_ALL=C sed \"s/.*\\///g\" || :\n      ))\n\n      local _selected_push_option=\n      local _show_branch_selection_prompt=0\n      local _show_branch_name_prompt=1\n\n      if [[ \"${#_remote_branches[@]}\" -eq 0     ]]\n      then\n        _selected_push_option=2\n        _show_branch_name_prompt=0\n      elif ! _contains \"${_new_branch}\" \"${_remote_branches[@]:-}\"\n      then\n        _print_line \"--------------\"\n\n        cat <<HEREDOC\nBranch not present on remote: $(_color_primary \"${_new_branch:-}\")\n\n$(_color_brackets \"1\") Merge and sync with an existing remote branch.\n$(_color_brackets \"2\") Sync as a new orphan branch on the remote.\n\nHEREDOC\n\n        while true\n        do\n          IFS='' read -r -e -d $'\\n' -p                                   \\\n\"$(_color_primary \"Choose an option\") or $(_color_primary \"q\") to quit: \" \\\n            _selected_push_option\n\n          case \"${_selected_push_option:-}\" in\n            1)\n              _show_branch_selection_prompt=1\n\n              break\n              ;;\n            2)\n              break\n              ;;\n            q*|exit)\n              printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n              exit 0\n              ;;\n          esac\n        done\n      else\n        local _temp_repo_path=\"${_NB_TEMP_DIRECTORY}/${RANDOM}\"\n\n        (\n          cd \"${_NB_TEMP_DIRECTORY}\"                            &&\n            git clone --no-local                                \\\n              --single-branch --branch \"${_new_branch:-}\"       \\\n              \"${_new_remote_url}\"                              \\\n              \"${_temp_repo_path}\" &>/dev/null\n        )\n\n        local _local_branch_root_hash=\n        _local_branch_root_hash=\"$(\n          git -C \"${_notebook_path}\" rev-list --max-parents=0   \\\n            \"${_current_branch}\"\n        )\"\n\n        local _remote_branch_root_hash=\n        _remote_branch_root_hash=\"$(\n          git -C \"${_temp_repo_path}\" rev-list --max-parents=0  \\\n            \"remotes/origin/${_new_branch}\"\n        )\"\n\n        local _remote_branch_commit_hashes=()\n        _remote_branch_commit_hashes=($(\n          git -C \"${_temp_repo_path}\" rev-list                  \\\n            --max-count 3 \"remotes/origin/${_new_branch}\"\n        ))\n\n        local _remote_branch_files=()\n        _remote_branch_files=($(\n          git -C \"${_temp_repo_path}\" ls-tree --name-only \"origin/${_new_branch}\"\n        ))\n\n        if [[ \"${_local_branch_root_hash:-}\"  ==  \"${_remote_branch_root_hash:-}\" ]]\n        then\n          _selected_push_option=1\n        else\n           if [[ \"${#_remote_branch_commit_hashes[@]}\"  -eq 1         ]]  &&\n              [[ \"${#_remote_branch_files[@]}\"          -eq 1         ]]  &&\n              [[ \"${_remote_branch_files[0]}\"           ==  \".index\"  ]]\n          then\n            _selected_push_option=1\n          else\n            _print_line \"--------------\"\n\n            cat <<HEREDOC\nRemote branch has existing history: $(_color_primary \"${_new_branch:-}\")\n\n$(_color_brackets \"1\") Merge and sync with the existing remote branch: $(_color_primary \"${_new_branch:-}\")\nHEREDOC\n\n            if [[ \"${#_remote_branches[@]}\" -le 1 ]]\n            then\n              cat <<HEREDOC\n$(_color_brackets \"2\") Sync as a new orphan branch on the remote.\n\nHEREDOC\n            else\n              cat <<HEREDOC\n$(_color_brackets \"2\") Merge and sync with a different existing remote branch.\n$(_color_brackets \"3\") Sync as a new orphan branch on the remote.\n\nHEREDOC\n            fi\n\n            local _existing_history_prompt_option=\n\n            while true\n            do\n              IFS='' read -r -e -d $'\\n' -p                               \\\n\"$(_color_primary \"Choose an option\") or $(_color_primary \"q\") to quit: \" \\\n              _existing_history_prompt_option\n\n              case \"${_existing_history_prompt_option:-}\" in\n                1)\n                  _selected_push_option=1\n\n                  break\n                  ;;\n                2)\n                  if [[ \"${#_remote_branches[@]}\" -le 1 ]]\n                  then\n                    _selected_push_option=2\n                  else\n                    _selected_push_option=1\n                    _show_branch_selection_prompt=1\n                  fi\n\n                  break\n                  ;;\n                3)\n                  _selected_push_option=2\n\n                  break\n                  ;;\n                q*|exit)\n                  printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n                  exit 0\n                  ;;\n              esac\n            done\n          fi\n        fi\n      fi\n\n      if ((_show_branch_selection_prompt))\n      then\n        _print_line \"------------------------------\"\n\n        printf \"Remote branches:\\\\n\\\\n\"\n\n        local i=\n        for ((i=0; i < ${#_remote_branches[@]}; i++))\n        do\n          printf \"%s %s\\\\n\"                       \\\n            \"$(_color_brackets \"$((i+1))\")\"       \\\n            \"${_remote_branches[${i}]:-}\"\n        done\n\n        printf \"\\\\n\"\n\n        local _selected_branch=\n\n        while true\n        do\n          IFS='' read -r -e -d $'\\n' -p                                               \\\n            \"$(_color_primary \"Choose a branch\") or $(_color_primary \"q\") to quit: \"  \\\n            _selected_branch\n\n          case \"${_selected_branch:-}\" in\n            q*|exit)\n              printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n              exit 0\n              ;;\n            [0-9]*)\n              if [[ -n \"${_remote_branches[$((_selected_branch - 1))]:-}\" ]]\n              then\n                _new_branch=\"${_remote_branches[$((_selected_branch - 1))]:-}\"\n\n                break\n              fi\n              ;;\n          esac\n        done\n      fi\n\n      if [[ \"${_selected_push_option:-}\" == \"2\"               ]]\n      then\n        local _target_orphan_branch_name=\"${_new_branch}\"\n\n        if _contains \"${_new_branch}\" \"${_remote_branches[@]:-}\"\n        then\n          if [[ \"${_new_branch:-}\" == \"${_current_branch:-}\"  ]]\n          then\n            local _notebook_name_branch_name=\"${_notebook_path##*/}\"\n            _notebook_name_branch_name=\"${_notebook_name_branch_name//' '/-}\"\n            _notebook_name_branch_name=\"$(\n              printf \"%s\\\\n\" \"${_notebook_name_branch_name}\"  \\\n                | tr '[:upper:]' '[:lower:]'\n            )\"\n          fi\n\n          local _uniqueness_counter=0\n          local _unique_branch_name=\"${_notebook_name_branch_name}\"\n\n          while _contains \"${_unique_branch_name}\" \"${_remote_branches[@]:-}\"\n          do\n            _uniqueness_counter=\"$((_uniqueness_counter+1))\"\n\n            printf -v _unique_branch_name -- \"%s-%01d\"        \\\n              \"${_notebook_name_branch_name}\"                 \\\n              \"${_uniqueness_counter}\"\n          done\n\n          _target_orphan_branch_name=\"${_unique_branch_name}\"\n        fi\n\n        if ! ((_show_branch_name_prompt))\n        then\n          _new_branch=\"${_target_orphan_branch_name}\"\n        else\n          _print_line \"------------------------------\"\n\n          local _bk_name=  && _bk_name=\"$(_color_brackets \"${_target_orphan_branch_name}\")\"\n          local _hi_enter= && _hi_enter=\"$(_color_primary 'enter')\"\n          local _hi_q=     && _hi_q=\"$(_color_primary 'q')\"\n          local _hi_type=  && _hi_type=\"$(_color_primary 'type')\"\n\n          cat <<HEREDOC\nPress ${_hi_enter} to use the selected name, ${_hi_type} a new name, or press ${_hi_q} to quit.\n\nHEREDOC\n\n          while true\n          do\n            local _orphan_branch_prompt_response=\n\n            IFS='' read -r -e -d $'\\n' -p                     \\\n              \"Name ${_bk_name}: \"                            \\\n              _orphan_branch_prompt_response\n\n            case \"${_orphan_branch_prompt_response:-}\" in\n              '')\n                _new_branch=\"${_target_orphan_branch_name}\"\n\n                break\n                ;;\n              q*|exit)\n                printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n                exit 0\n                ;;\n              *)\n                _new_branch=\"${_orphan_branch_prompt_response}\"\n\n                break\n                ;;\n            esac\n          done\n        fi\n      fi\n\n      if [[ \"${_new_branch:-}\" != \"${_current_branch:-}\"      ]]\n      then\n        git -C \"${_notebook_path}\" branch -m \"${_new_branch:-}\"\n      fi\n\n      if ((_remote_exists))\n      then\n        _print_line \"--------------\"\n        _remote unset --skip-confirmation\n        _print_line \"---------------\"\n      fi\n\n      git -C \"${_notebook_path}\" remote add origin \"${_new_remote_url}\" ||\n        return 1\n\n      _git sync \"${_notebook_path}\" --skip-prompt\n\n      local _updated_current_branch=\n      _updated_current_branch=\"$(\n        git -C \"${_notebook_path}\" rev-parse --abbrev-ref HEAD\n      )\"\n\n      local __local_branch=\n      for   __local_branch in $(git -C \"${_notebook_path}\" branch --all)\n      do\n        if [[   \"${__local_branch:-}\" =~ ^\\ \\ remotes/              ]] &&\n           [[ ! \"${__local_branch:-}\" =~ ^\\ \\ remotes/origin/HEAD   ]] &&\n           [[ ! \"${__local_branch:-}\" =~ ^\\ \\ remotes/origin/${_updated_current_branch}$ ]]\n        then\n          git -C \"${_notebook_path}\" branch               \\\n            --delete --remotes \"${__local_branch#\\ \\ remotes/}\" &>/dev/null\n        fi\n      done\n\n      local _updated_remote_url=\n      _updated_remote_url=\"$(\n        git -C \"${_notebook_path}\" remote get-url origin 2>/dev/null\n      )\"\n\n      printf \"Remote set to: %s (%s)\\\\n\"                  \\\n        \"$(_color_primary \"${_updated_remote_url}\")\"      \\\n        \"$(_color_primary \"${_updated_current_branch}\")\"\n\n      return 0\n      ;;\n    *)\n      if ((_remote_exists))\n      then\n        if ((_only_url))\n        then\n          printf \"%s\\\\n\" \"${_current_remote_url:-}\"\n        else\n          printf \"%s (%s)\\\\n\" \"${_current_remote_url:-}\" \"${_current_branch:-}\"\n        fi\n      else\n        _warn printf \"No remote configured.\\\\n\"\n\n        return 1\n      fi\n      ;;\n  esac\n}\n\n# settings ########################################################### settings\n\n_describe_settings() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} set [<name> [<value>] | <number> [<value>]]\n  ${_ME} settings colors [<number> | themes]\n  ${_ME} settings edit\n  ${_ME} settings get   (<name> | <number>)\n  ${_ME} settings list  [--long]\n  ${_ME} settings set   (<name> | <number>) <value>\n  ${_ME} settings show  (<name> | <number>)\n  ${_ME} settings unset (<name> | <number>)\n\n$(_color_primary \"Subcommands\"):\n  (default)  Open the settings prompt, to <name> or <number>, if present.\n             When <value> is also present, assign <value> to the setting.\n  colors     Print a table of available colors and their xterm color numbers.\n             When <number> is provided, print the number in its color.\n             \\`settings colors themes\\` prints a list of installed themes.\n  edit       Open the \\`${_ME}\\` configuration file in \\`\\$EDITOR\\`.\n  get        Print the value of a setting.\n  list       List information about available settings.\n  set        Assign <value> to a setting.\n  show       Print the help information and current value of a setting.\n  unset      Unset a setting, returning it to the default value.\n\n$(_color_primary \"Description\"):\n  Configure \\`${_ME}\\`. Use \\`${_ME} settings set\\` to customize a setting and\n  \\`${_ME} settings unset\\` to restore the default for a setting.\n\n  Use the \\`${_ME} set\\` alias to quickly assign values to settings:\n\n    ${_ME} set color_theme blacklight\n    ${_ME} set limit 40\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#%EF%B8%8F-set--settings\n\n$(_color_primary \"See Also\"):\n  ${_ME} help unset\n\n$(_color_primary \"Examples\"):\n  ${_ME} settings\n  ${_ME} set 5 \"org\"\n  ${_ME} set color_primary 105\n  ${_ME} set unset color_primary\n  ${_ME} set color_secondary unset\n  ${_ME} settings colors\n  ${_ME} settings colors 105\n  ${_ME} set limit 15\n\n$(_color_primary \"Alias\"):\n  ${_ME} set\nHEREDOC\n}\n_settings() {\n  # Usage: _settings_colors [<number>] [themes]\n  _settings_colors() {\n    # Usage: _settings_colors_print <number>\n    _settings_colors_print() {\n      printf '\\e[38;5;%dm %3d ' \"${1:-}\" \"${1:-}\"\n    }\n\n    if [[   -n  \"${1:-}\"              ]]\n    then\n      if [[     \"${1}\" == \"themes\"    ]]\n      then\n        printf \"%s\\\\n\" \"${_NB_COLOR_THEMES[@]}\"\n      else\n        if [[ ! \"${1}\" =~ [[:digit:]] ]]\n        then\n          _exit_1 printf \"Usage: %s settings colors [<number> | themes]\\\\n\" \"${_ME}\"\n        fi\n\n        _settings_colors_print \"${1:-}\"\n\n        printf \"\\\\n\"\n      fi\n    else\n      local i=\n      for ((i=0; i < 256; i++))\n      do\n        if ((i)) && ! ((i % 16))\n        then\n          printf \"\\\\n\"\n        fi\n\n        _settings_colors_print \"${i}\"\n      done\n\n      printf \"\\\\n\"\n    fi\n  }\n\n  # Usage: _settings_get_value (<number> | <name>)\n  _settings_get_value() {\n    local _setting_name=\n    _setting_name=\"$(_settings_identify \"${1:-}\")\"\n\n    _env | grep \"^${_setting_name}=\" | cut -d= -f2\n  }\n\n  # Usage: _settings_identify [--id] (<number> | <name>)\n  _settings_identify() {\n    local _get_id=0\n    local _id_or_name=\n\n    case \"${1:-}\" in\n      '')\n        return 1\n        ;;\n      --id)\n        _get_id=1\n\n        if [[ -n \"${2:-}\" ]]\n        then\n          _id_or_name=\"${2:-}\"\n        else\n          return 1\n        fi\n        ;;\n      *)\n        _id_or_name=\"${1}\"\n        ;;\n    esac\n\n    case \"${_id_or_name}\" in\n      1|*auto*|*AUTO*|*sync*|*SYNC*)\n        ((_get_id)) && printf \"1\"   || printf \"NB_AUTO_SYNC\"\n\n        return 0\n        ;;\n      2|*primary*|*PRIMARY*)\n        ((_get_id)) && printf \"2\"   || printf \"NB_COLOR_PRIMARY\"\n\n        return 0\n        ;;\n      3|*secondary*|*SECONDARY*)\n        ((_get_id)) && printf \"3\"   || printf \"NB_COLOR_SECONDARY\"\n\n        return 0\n        ;;\n      4|*color*theme*|*COLOR*THEME*|*scheme*|theme*)\n        ((_get_id)) && printf \"4\"   || printf \"NB_COLOR_THEME\"\n\n        return 0\n        ;;\n      5|*ext*|*EXT*)\n        ((_get_id)) && printf \"5\"   || printf \"NB_DEFAULT_EXTENSION\"\n\n        return 0\n        ;;\n      6|*editor*|*EDITOR*)\n        ((_get_id)) && printf \"6\"   || printf \"EDITOR\"\n\n        return 0\n        ;;\n      7|*encrypt*|*ENCRYPT*)\n        ((_get_id)) && printf \"7\"   || printf \"NB_ENCRYPTION_TOOL\"\n\n        return 0\n        ;;\n      8|*footer*|*FOOTER*)\n        ((_get_id)) && printf \"8\"   || printf \"NB_FOOTER\"\n\n        return 0\n        ;;\n      9|*header*|*HEADER*)\n        ((_get_id)) && printf \"9\"   || printf \"NB_HEADER\"\n\n        return 0\n        ;;\n      10|*limit*|*LIMIT*)\n        ((_get_id)) && printf \"10\"  || printf \"NB_LIMIT\"\n\n        return 0\n        ;;\n      11|*dir*|*DIR*)\n        ((_get_id)) && printf \"11\"  || printf \"NB_DIR\"\n\n        return 0\n        ;;\n      12|*syntax*|*SYNTAX*)\n        ((_get_id)) && printf \"12\"  || printf \"NB_SYNTAX_THEME\"\n\n        return 0\n        ;;\n      *)\n        _warn                                   \\\n          printf \"Setting not found: %s\\\\n\"     \\\n          \"$(_color_primary \"${_id_or_name}\")\"  &&\n            return 1\n        ;;\n    esac\n  }\n\n  # Usage: _settings_prompt [<id> | <name>]\n  _settings_prompt() {\n    local _setting_name=\"${1:-}\"\n\n    local _padding=\n    _padding=\"$(_print_padding \"-----------\" \"${_COLUMNS}\")\"\n\n    printf \"%s%s Settings\\\\n\" \"${_padding}\" \"$(_color_primary \"${_ME}\")\"\n    _print_line \"$(printf \"%-${_COLUMNS}s\" '.')\"\n\n    if [[ -n \"${_setting_name}\" ]]\n    then\n      _setting_name=\"$(_settings_identify \"${_setting_name}\")\"\n    else\n      cat <<HEREDOC\n$(_settings list)\n\nEnter the number or name of the setting to change, or $(_color_primary 'q') to quit.\nHEREDOC\n\n      while true\n      do\n        local __setting=\n        IFS='' read -r -e -d $'\\n' -p \\\n\"$(_color_primary \"Number or Name: \")\" __setting\n\n        if [[ -n \"${__setting}\" ]]\n        then\n          case \"${__setting}\" in\n            q|quit|exit)\n              printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n              return 0\n              ;;\n            *)\n              _setting_name=\"$(\n                _settings_identify \"${__setting}\"\n              )\" && break\n              ;;\n          esac\n        fi\n      done\n    fi\n\n    printf \"\\\\n\"\n\n    if [[ \"${_setting_name}\" == \"NB_COLOR_PRIMARY\"    ]] ||\n       [[ \"${_setting_name}\" == \"NB_COLOR_SECONDARY\"  ]]\n    then\n      printf \"%s\\\\n\\\\n\" \"$(_settings_colors)\"\n    fi\n\n    _settings show \"${_setting_name}\"\n\n    local _hi_unset= && _hi_unset=\"$(_color_primary 'unset')\"\n    local _hi_q=     && _hi_q=\"$(_color_primary 'q')\"\n\n    cat <<HEREDOC\n\nEnter a new value, ${_hi_unset} to set to the default value, or ${_hi_q} to quit.\nHEREDOC\n\n    while true\n    do\n      local __value=\n      IFS='' read -r -e -d $'\\n' -p \"$(_color_primary \"Value: \")\" __value\n\n      if [[ -n \"${__value}\" ]]\n      then\n        case \"${__value}\" in\n          q|quit|exit)\n            printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n            return 0\n            ;;\n          unset|default|reset)\n            _settings_unset \"${_setting_name}\"              || continue\n\n            break\n            ;;\n          *)\n            _settings_set   \"${_setting_name}\" \"${__value}\" || continue\n\n            break\n            ;;\n        esac\n      fi\n    done\n  }\n\n  # Usage: _settings_set (<number> | <name>) <value>\n  _settings_set() {\n    local _entry=\n    local _value=\"${2:-}\"\n\n    local _setting_name=\n    _setting_name=\"$(_settings_identify \"${1:-}\")\"\n\n    if _contains \"${2:-}\" \"unset\" \"default\" \"reset\"\n    then\n      _settings_unset \"${_setting_name}\"\n\n      return 0\n    fi\n\n    _settings_validate_value \"${_setting_name}\" \"${2:-}\"    || return 1\n\n    if [[ \"${_value:-}\"       =~ ^~       ]]\n    then\n      # shellcheck disable=SC2016\n      _value=\"$(printf \"%s\\\\n\" \"${_value}\" | LC_ALL=C sed \"s|~|${HOME}|g\")\"\n    fi\n\n    local _attribution=\n    _attribution=\"# Set by \\`${_ME}\\` • $(date)\"\n\n    if [[ \"${_setting_name}\"  == \"EDITOR\" ]]\n    then\n      _entry=\"export ${_setting_name}=\\\"${_value}\\\" ${_attribution}\"\n    else\n      _entry=\"export ${_setting_name}=\\\"\\${${_setting_name}:-${_value}}\\\" ${_attribution}\"\n    fi\n\n    _settings_unset \"${_setting_name}\" > /dev/null 2>&1     || return 1\n\n    printf \"\\\\n%s\\\\n\" \"${_entry}\" >> \"${NBRC_PATH}\"\n\n    if [[   \"${_setting_name}\" == \"NB_COLOR_PRIMARY\"    ]]  ||\n       [[   \"${_setting_name}\" == \"NB_COLOR_SECONDARY\"  ]]\n    then\n      _setting_name=\"$(_tput setaf \"${_value}\")${_setting_name}${_TPUT_SGR0}\"\n      _value=\"$(_tput setaf \"${_value}\")${_value}${_TPUT_SGR0}\"\n    elif [[ \"${_setting_name}\" == \"NB_COLOR_THEME\"      ]]\n    then\n      local _new_color=\n      _new_color=\"$(\n        NB_COLOR_THEME=\"${_value}\" NB_COLOR_PRIMARY=''  \\\n          \"${_MY_PATH}\" settings get NB_COLOR_PRIMARY\n      )\"\n\n      _setting_name=\"$(_tput setaf \"${_new_color}\")${_setting_name}${_TPUT_SGR0}\"\n      _value=\"$(_tput setaf \"${_new_color}\")${_value}${_TPUT_SGR0}\"\n    else\n      _setting_name=\"$(_color_primary \"${_setting_name}\")\"\n      _value=\"$(_color_primary \"${_value}\")\"\n    fi\n\n    printf \"%s set to %s\\\\n\" \"${_setting_name}\" \"${_value}\"\n  }\n\n  # Usage: _settings_unset (<number> | <name>)\n  _settings_unset() {\n    local _setting_name=\n    _setting_name=\"$(_settings_identify \"${1:-}\")\"\n\n    _sed_i                                              \\\n      -e \"/^export ${_setting_name}.*Added by.*$/d\"     \\\n      -e \"/^export ${_setting_name}.*Set by.*$/d\"       \\\n      \"${NBRC_PATH}\"\n\n    local _stripped=\n    _stripped=$(<\"${NBRC_PATH}\")\n\n    printf \"%s\\\\n\" \"${_stripped}\" > \"${NBRC_PATH}\"\n\n    local _default_value=\n    _default_value=\"$(\n      eval \"${_setting_name}='' \\\"${_MY_PATH}\\\" settings get ${_setting_name}\"\n    )\"\n\n    if [[   \"${_setting_name}\" == \"NB_COLOR_SECONDARY\"  ]]\n    then\n      _setting_name=\"$(_color_primary \"${_setting_name}\")\"\n      _default_value=\"$(_tput setaf \"${_default_value}\")${_default_value}${_TPUT_SGR0}\"\n    elif [[ \"${_setting_name}\" == \"NB_COLOR_PRIMARY\"    ]]\n    then\n      _setting_name=\"$(_tput setaf \"${_default_value}\")${_setting_name}${_TPUT_SGR0}\"\n      _default_value=\"$(_tput setaf \"${_default_value}\")${_default_value}${_TPUT_SGR0}\"\n    elif [[ \"${_setting_name}\" == \"NB_COLOR_THEME\"      ]]\n    then\n      _new_hi_color=\"$(\n        NB_COLOR_THEME=\"${_ME}\" NB_COLOR_PRIMARY=''     \\\n          \"${_MY_PATH}\" settings get NB_COLOR_PRIMARY\n      )\"\n\n      _setting_name=\"$(_tput setaf \"${_new_hi_color}\")${_setting_name}${_TPUT_SGR0}\"\n      _default_value=\"$(_tput setaf \"${_new_hi_color}\")${_default_value}${_TPUT_SGR0}\"\n    else\n      _setting_name=\"$(_color_primary \"${_setting_name}\")\"\n      _default_value=\"$(_color_primary \"${_default_value}\")\"\n    fi\n\n    printf \"%s restored to the default: %s\\\\n\"          \\\n      \"${_setting_name}\"                                \\\n      \"${_default_value}\"\n  }\n\n  # Usage: _settings_validate_value (<number> | <name>) <value>\n  _settings_validate_value() {\n    if [[ \"${1:-}\" == 'EDITOR'                ]]  ||\n       [[ \"${1:-}\" == 'NB_DEFAULT_EXTENSION'  ]]\n    then\n      if [[ -n \"${2:-}\"                       ]]\n      then\n        return 0\n      else\n        _warn printf                \\\n          \"%s requires a value.\\\\n\" \\\n          \"${1:-}\"\n\n        return 1\n      fi\n    elif [[ \"${1:-}\" == 'NB_AUTO_SYNC'        ]]  ||\n         [[ \"${1:-}\" == 'NB_FOOTER'           ]]\n    then\n      if [[ \"${2:-}\" =~ (^0$|^1$)             ]]\n      then\n        return 0\n      else\n        _warn printf                              \\\n          \"%s must be either \\\"0\\\" or \\\"1\\\".\\\\n\"  \\\n          \"${1}\"\n\n        return 1\n      fi\n    elif [[ \"${1:-}\" == 'NB_HEADER'           ]]\n    then\n      if [[ \"${2:-}\" =~ (^0$|^1$|^2$|^3$)     ]]\n      then\n        return 0\n      else\n        _warn printf                                      \\\n          \"%s must be \\\"0\\\", \\\"1\\\", \\\"2\\\", or \\\"3\\\".\\\\n\"  \\\n          \"${1}\"\n\n        return 1\n      fi\n    elif [[ \"${1:-}\" == 'NB_LIMIT'                ]]\n    then\n      if [[ \"${2:-}\" =~ ^[0-9]+$                  ]]  ||\n         [[ \"${2:-}\" =~ ^auto$                    ]]  ||\n         [[ \"${2:-}\" =~ ^auto[+|-][0-9]+$         ]]  ||\n         [[ \"${2:-}\" =~ ^auto[+|-][0-9]+\\^[0-9]+$ ]]  ||\n         [[ \"${2:-}\" =~ ^auto\\^[0-9]+$            ]]\n      then\n        return 0\n      else\n        _warn printf                                                                                \\\n\"%s must be a number or valid \\\"auto\\\" value.\\\\n\"  \\\n\"${1}\"\n\n        return 1\n      fi\n    elif [[ \"${1:-}\" == 'NB_DIR'              ]]\n    then\n      if [[ -z  \"${2:-}\"                      ]]  ||\n         [[ \"${2}\"   == \"/\"                   ]]  ||\n         {\n           [[   -e \"${2}\"                     ]]  &&\n           [[ ! -w \"${2}\"                     ]]\n         }\n      then\n        _warn printf                                      \\\n          \"\\\"%s\\\" is not a valid location for NB_DIR.\\\\n\" \\\n          \"${2:-}\"\n\n        return 1\n      fi\n    elif [[ \"${1:-}\" == 'NB_ENCRYPTION_TOOL'  ]]\n    then\n      if [[ \"${2:-}\" =~ (^openssl$|^gpg$)     ]]\n      then\n        return 0\n      else\n        _warn printf \\\n          \"NB_ENCRYPTION_TOOL must be either \\\"openssl\\\" or \\\"gpg\\\".\\\\n\"\n\n          return 1\n      fi\n    elif [[ \"${1:-}\" == 'NB_COLOR_PRIMARY'    ]]  ||\n         [[ \"${1:-}\" == 'NB_COLOR_SECONDARY'  ]]\n    then\n      if [[ \"${2:-}\" =~ ^[0-9]                ]]\n      then\n        return 0\n      else\n        _warn printf                \\\n          \"%s must be a number.\\\\n\" \\\n          \"${1}\"\n\n        return 1\n      fi\n    elif [[ \"${1:-}\" == 'NB_COLOR_THEME'      ]]\n    then\n      if _contains \"${2:-}\" \"${_NB_COLOR_THEMES[@]}\"\n      then\n        return 0\n      else\n        _warn printf                                    \\\n          \"%s must be one of the available themes.\\\\n\"  \\\n          \"${1}\"\n\n        return 1\n      fi\n    elif [[ \"${1:-}\" == 'NB_SYNTAX_THEME'     ]]\n    then\n      if ! _bat --command-exists\n      then\n        printf \"bat required: https://github.com/sharkdp/bat\\\\n\"\n      elif [[ -z \"${2:-}\"                     ]]\n      then\n        return 1\n      else\n        local _theme_list=\n        _theme_list=($(_bat --list-themes --color never))\n\n        local __theme=\n        for   __theme in \"${_theme_list[@]}\"\n        do\n          if [[ \"${2}\" =~ \\(                  ]]\n          then\n            if [[ \"${2}\" == \"${__theme:-}\"    ]]\n            then\n              return 0\n            fi\n          elif [[ \"${2}\" =~ ^${__theme%% (*}  ]]\n          then\n            return 0\n          fi\n        done\n\n        _warn printf                                    \\\n          \"%s must be one of the available themes.\\\\n\"  \\\n          \"${1}\"\n\n        return 1\n      fi\n    else\n      return 0\n    fi\n  }\n\n  local _settings_list_items=()\n  local _settings_help_items=()\n\n  _settings_list_items+=(\"$(_color_brackets '1')  auto_sync\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" ---------\")\n     By default, operations that trigger a git commit like \\`add\\`, \\`edit\\`,\n     and \\`delete\\` will sync notebook changes to the remote repository, if\n     the notebook's remote is set. To disable this behavior, set this to \\\"0\\\".\n\n     • Default Value: $(_color_primary \"1\")\")\n\n  _settings_list_items+=(\"$(_color_brackets '2')  color_primary\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" -------------\")\n     The primary color used to highlight identifiers and messages.\n\n     • Supported Values: xterm color numbers 0 through 255.\n     • Default Value:    $(_color_primary \"68\") (blue) for 256 color terminals,\n                         $(_color_primary \"4\")  (blue) for  8  color terminals.\")\n\n  _settings_list_items+=(\"$(_color_brackets '3')  color_secondary\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" ---------------\")\n     The color used for lines and footer elements.\n\n     • Supported Values: xterm color numbers 0 through 255.\n     • Default Value:    $(_color_primary \"8\")\")\n\n  _settings_list_items+=(\"$(_color_brackets '4')  color_theme\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" -----------\")\n     The color theme.\n\n     To view screenshots of the built-in themes, visit:\n\n         $(_color_primary \"https://git.io/nb-docs-color-themes\")\n\n     \\`${_ME}\\` supports custom, user-defined themes. To learn more, run:\n\n         $(_color_primary \"${_ME} help --colors\")\n\n     To change the syntax highlighting theme, use:\n\n         $(_color_primary \"${_ME} set syntax_theme\")\n\n     • Available themes:\n\n$(\n  local __theme=\n  for   __theme in \"${_NB_COLOR_THEMES[@]}\"\n  do\n    printf \"         %s\\\\n\" \"$(_color_primary \"${__theme}\")\"\n  done\n)\n\n     • Default Value: $(_color_primary \"${_ME}\")\")\n\n  _settings_list_items+=(\"$(_color_brackets '5')  default_extension\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" -----------------\")\n     The default extension to use for note files. Change to \\\"org\\\" for Emacs\n     Org mode files, \\\"rst\\\" for reStructuredText, \\\"txt\\\" for plain text, or\n     whatever you prefer.\n\n     • Default Value: $(_color_primary \"md\")\")\n\n  _settings_list_items+=(\"$(_color_brackets '6')  editor\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" ------\")\n     The command line text editor used by \\`${_ME}\\`.\n\n     • Example Values:\n\n$(\n  local __editor=\n  for   __editor in atom code emacs hx macdown mate micro nano pico subl vi vim\n  do\n    if _command_exists \"${__editor}\"\n    then\n      printf \"         %s\\\\n\" \"$(_color_primary \"${__editor}\")\"\n    fi\n  done\n)\")\n\n  _settings_list_items+=(\"$(_color_brackets '7')  encryption_tool\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" ---------------\")\n     The tool used for encrypting notes.\n\n     • Supported Values: $(_color_primary \"openssl\"), $(_color_primary \"gpg\")\n     • Default Value:    $(_color_primary \"openssl\")\")\n\n  _settings_list_items+=(\"$(_color_brackets '8')  footer\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" ------\")\n     By default, \\`${_ME}\\` and \\`${_ME} ls\\` include a footer with example commands.\n     To hide this footer, set this to \\\"0\\\".\n\n     • Default Value: $(_color_primary \"1\")\")\n\n  _settings_list_items+=(\"$(_color_brackets '9')  header\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" ------\")\n     By default, \\`${_ME}\\` and \\`${_ME} ls\\` include a header listing available notebooks.\n     Set the alignment, or hide the header with \\\"0\\\".\n\n     • Supported Values:\n\n       $(_color_primary \"0\")  Hide Header\n       $(_color_primary \"1\")  Dynamic Alignment\n            - Left justified when list is shorter than terminal width.\n            - Center aligned when list is longer than terminal width.\n       $(_color_primary \"2\")  Center Aligned (default)\n       $(_color_primary \"3\")  Left Justified\n\n     • Default Value: $(_color_primary \"2\")\")\n\n  _settings_list_items+=(\"$(_color_brackets '10') limit\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" -----\")\n     The maximum number of items included in the \\`${_ME}\\` and \\`${_ME} ls\\` lists.\n     Set to \\`auto\\` to automatically limit output to the current terminal height.\n     Set a maximum auto limit with \\`auto^<max>\\`, e.g., \\`auto^15\\`.\n     Subtract an auto limit offset for multiline prompts with \\`auto-<offset>\\`.\n     Add an auto limit offet with \\`auto+<offset>\\`.\n     Combine both modifiers with \\`auto-<offset>^<max>\\` or \\`auto+<offset>^<max>\\`.\n\n     • Example Values:\n\n       15\n       auto\n       auto^15\n       auto-2\n       auto+2\n       auto-2^15\n       auto+2^15\n\n     • Default Value: $(_color_primary \"15\")\")\n\n  _settings_list_items+=(\"$(_color_brackets '11') nb_dir\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" ------\")\n     The location of the directory that contains the notebooks.\n\n     For example, to sync all notebooks with Dropbox, create a folder at\n     \\`~/Dropbox/Notes\\` and run: \\`${_ME} settings set nb_dir ~/Dropbox/Notes\\`\n\n     • Default Value: $(_color_primary \"~/.${_ME}\")\")\n\n  _settings_list_items+=(\"$(_color_brackets '12') syntax_theme\")\n  _settings_help_items+=(\"\\\n    $(_color_secondary \" ------------\")\n     The syntax highlighting theme. View examples with:\n\n         $(_color_primary \"${_BAT_COMMAND} --list-themes\")\n\n$(\n  if ! _bat --command-exists\n  then\n    printf \"     Install \\`bat\\` to enable themes: https://github.com/sharkdp/bat\\\\n\"\n  else\n    printf \"     • Available themes:\\\\n\"\n    printf \"\\\\n\"\n\n    local __theme=\n    for   __theme in $(_bat --list-themes --color never)\n    do\n      printf \"         %s\\\\n\" \"$(_color_primary \"${__theme}\")\"\n    done\n  fi\n)\n\n     • Default Value: $(_color_primary 'base16')\")\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      color|colors)\n        _settings_colors \"${2:-}\"\n\n        return 0\n        ;;\n      edit)\n        _edit_file \"${NBRC_PATH}\" --no-wait\n\n        return 0\n        ;;\n      get)\n        if [[ -z  \"${2:-}\"              ]]\n        then\n          _exit_1 _help settings\n        fi\n\n        _settings_get_value \"${2:-}\"\n\n        return 0\n        ;;\n      list)\n        if [[     \"${2:-}\" == \"--long\"  ]]\n        then\n          local _counter=0\n\n          local __setting=\n          for   __setting in \"${_settings_list_items[@]}\"\n          do\n            ((_counter)) && printf \"\\\\n\"\n            _counter=\"$((_counter+1))\"\n\n            _settings show \"${_counter}\"\n          done\n        else\n          printf \"%s\\\\n\" \"${_settings_list_items[@]}\"\n        fi\n\n        return 0\n        ;;\n      set)\n        if [[ -z \"${2:-}\" ]] || [[ -z \"${3:-}\" ]]\n        then\n          _exit_1 _help \"settings\"\n        fi\n\n        _settings_set \"${2:-}\" \"${3:-}\"\n\n        return 0\n        ;;\n      show|help|about|info|more)\n        if [[ -z \"${2:-}\" ]]\n        then\n          _exit_1 _help \"settings\"\n        fi\n\n        local _setting_id=\n        _setting_id=\"$(_settings_identify --id \"${2:-}\")\"\n\n        local _setting_name=\n        _setting_name=\"$(_settings_identify \"${2:-}\")\"\n\n        local _index=\n        _index=\"$((_setting_id-1))\"\n\n        printf \"%s\\\\n%s\\\\n\"                       \\\n          \"${_settings_list_items[${_index}]}\"    \\\n          \"${_settings_help_items[${_index}]}\"\n\n        printf \"\\\\n%s is currently set to %s\\\\n\"  \\\n          \"$(_color_primary \"${_setting_name}\")\"  \\\n          \"$(_color_primary \"$(_settings_get_value \"${_setting_name}\")\")\"\n\n        return 0\n        ;;\n      reset|unset)\n        if [[ -z \"${2:-}\" ]]\n        then\n          _exit_1 _help \"settings\"\n        fi\n\n        _settings_unset \"${2:-}\"\n\n        return 0\n        ;;\n      *)\n        local _setting_name=\n\n        case \"${1:-}\" in\n          '')       :                                             ;;\n          remote)   shift; _remote set \"${@}\"; return 0           ;;\n          *)        _setting_name=\"$(_settings_identify \"${1}\")\"  ;;\n        esac\n\n        if [[   -n \"${_setting_name:-}\" ]]\n        then\n          if [[ -n \"${2:-}\"             ]]\n          then\n            _settings_set \"${_setting_name}\" \"${2}\"\n          else\n            _settings_prompt \"${_setting_name}\"\n          fi\n        else\n          _settings_prompt\n        fi\n\n        return 0\n        ;;\n    esac\n\n    shift\n  done\n}\n_alias_subcommand \"settings\" \"config\"\n_alias_subcommand \"settings\" \"set\"\n\n# shell ################################################################# shell\n\n_describe_shell() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} shell [<subcommand> [<options>...] | --clear-history]\n\n$(_color_primary \"Options\"):\n  --clear-history  Clear the \\`${_ME}\\` shell history.\n\n$(_color_primary \"Description\"):\n  Start the \\`${_ME}\\` interactive shell. Type \"exit\" to exit.\n\n  \\`${_ME} shell\\` recognizes all \\`${_ME}\\` subcommands and options, providing\n  a streamlined, distraction-free approach for working with \\`${_ME}\\`.\n\n  When <subcommand> is present, the command will run as the shell is opened.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-interactive-shell\n\n$(_color_primary \"See Also\"):\n  ${_ME} help run\n\n$(_color_primary \"Example\"):\n  $ ${_ME} shell\n  ${_ME}> ls 3\n  [3] Example\n\n  ${_ME}> edit 3 --content \"New content.\"\n  Updated [3] Example\n\n  ${_ME}> notebook\n  home\n\n  ${_ME}> exit\n  $\nHEREDOC\n}\n_shell() {\n  HISTFILE=\"${NB_HIST:-${HOME}/.${_ME}_history}\"\n  set -o history\n\n  local _initial_command=\n  local _prompt=\n  _prompt=\"$(_color_primary \"${_ME}\")$(_color_secondary \"${_CHEVRON_RIGHT}\") \"\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg}\" in\n      --clear-history)\n        if [[ -e \"${HISTFILE}\"  ]]\n        then\n          rm \"${HISTFILE:?}\"\n\n          printf \"History cleared.\\\\n\"\n\n          return 0\n        fi\n        ;;\n      *)\n        if [[ -n \"${__arg}\"     ]]\n        then\n          _initial_command+=\" ${__arg}\"\n        fi\n        ;;\n    esac\n  done\n\n  printf \"%s\" \"${_TPUT_COLOR_PRIMARY}\"\n  cat <<HEREDOC\n__          _\n\\ \\   _ __ | |__\n \\ \\ | '_ \\| '_ \\\\\n / / | | | | |_) |\n/_/  |_| |_|_.__/\n$(_color_secondary \"------------------\")\n$(_color_primary \"${_ME} shell\") started. Enter $(_color_primary \"ls\") to list notes and notebooks.\nEnter $(_color_primary \"help\") for usage information. Enter $(_color_primary \"exit\") to exit.\nHEREDOC\n\n  if [[ -n \"${_initial_command:-}\"            ]]\n  then\n    eval \"\\\"${_MY_PATH}\\\" ${_initial_command}\"\n  fi\n\n  local __input=\n  while IFS='' read -r -e -d $'\\n' -p \"${_prompt}\" __input\n  do\n    history -s \"${__input}\"\n\n    if [[ \"${__input}\" =~ (^exit$|^quit$|^q$) ]]\n    then\n      return 0\n    elif [[ \"${__input}\" =~ ^clear$           ]]\n    then\n      clear\n    else\n      # Strip leading 'n', 'nb', or 'notes'.\n      local _normalized_input=\n      _normalized_input=\"$(\n        printf \"%s\\\\n\" \"${__input}\"           \\\n          | LC_ALL=C sed -e 's/^notes$//'     \\\n          | LC_ALL=C sed -e 's/^notes //'\n      )\"\n\n      if [[ \"${_normalized_input}\" =~ ^nb\\ .* ]]\n      then\n        local _candidate_subcommand_or_notebook=\n        _candidate_subcommand_or_notebook=\"$(\n          printf \"%s\\\\n\" \"${_normalized_input:-}\" \\\n            | LC_ALL=C sed -E -e 's/nb? ([^[:space:]]*)/\\1/'\n        )\"\n\n        local _notebook_names=()\n        _notebook_names=($(_notebooks --names --no-color --unarchived))\n\n        local _notebook_subcommand_names=(\n          a add create new ar archive author config configure current\n          d delete rm trash export import init o open p peek\n          rename move mv select st status s show unar unarchive u use\n        )\n\n        if  ! _contains     \\\n              \"${_candidate_subcommand_or_notebook:-}\"  \\\n              \"${_notebook_names[@]:-}\"                 \\\n            && ! _contains  \\\n              \"${_candidate_subcommand_or_notebook:-}\"  \\\n              \"${_notebook_subcommand_names[@]}\"\n        then\n          _normalized_input=\"$(\n            printf \"%s\\\\n\" \"${__input}\" \\\n              | LC_ALL=C sed -e 's/^nb //'\n          )\"\n        fi\n      fi\n\n      local _command_name=\n\n      if [[ \"${_normalized_input}\" =~ ^help   ]] ||\n         [[ \"${_normalized_input}\" =~ ^help\\  ]] ||\n         [[ \"${_normalized_input}\" =~ ^h$     ]] ||\n         [[ \"${_normalized_input}\" =~ ^h\\     ]]\n      then\n        eval \"\\\"${_MY_PATH}\\\" ${_normalized_input}\" --shell   || :\n      elif [[ \"${_normalized_input}\" =~ ^u\\ .+|^use\\ |^notebooks\\ use|^notebooks\\ u  ]]\n      then\n        eval \"_${_normalized_input}\"\n      elif [[ \"${_normalized_input}\" =~ ^echo\\ .*   ]]        ||\n           [[ \"${_normalized_input}\" =~ ^printf\\ .* ]]\n      then\n        eval \"${_normalized_input}\"\n      elif _command_name=\"$(\n        printf \"%s\\\\n\" \"${_normalized_input}\" \\\n          | grep                              \\\n              --only-matching                 \\\n              -e '^code'                      \\\n              -e '^emacs'                     \\\n              -e '^gvim'                      \\\n              -e '^hx'                        \\\n              -e '^macdown'                   \\\n              -e '^mate'                      \\\n              -e '^mvim'                      \\\n              -e '^nano'                      \\\n              -e '^nvim'                      \\\n              -e '^subl'                      \\\n              -e '^vim'\n      )\"\n      then\n        _normalized_input=\"$(\n          printf \"%s\\\\n\" \"${_normalized_input}\"     \\\n            | LC_ALL=C sed -e \"s/^${_command_name} //\"\n        )\"\n\n        eval \"\\\"${_MY_PATH}\\\" edit --editor \\\"${_command_name}\\\" ${_normalized_input}\"\n      else\n        eval \"\\\"${_MY_PATH}\\\" ${_normalized_input}\" || :\n      fi\n    fi\n  done\n}\n\n# status ############################################################### status\n\n_describe_status() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} status [<notebook>]\n\n$(_color_primary \"Description\"):\n  Print archival, git, and remote status for the current notebook or <notebook>.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-git-sync\n  ${_README_URL}#-revision-history\n\n$(_color_primary \"See Also\"):\n  ${_ME} help archive\n  ${_ME} help history\n  ${_ME} help notebooks\n  ${_ME} help remote\n  ${_ME} help sync\n  ${_ME} help unarchive\n\n$(_color_primary \"Examples\"):\n  ${_ME} status\n  ${_ME} status example\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} st\nHEREDOC\n}\n_status() {\n  local _notebook_name=\"${1%%:*}\"\n  local _notebook_path=\n\n  if [[   -n \"${_notebook_name:-}\" ]]\n  then\n    _notebook_path=\"$(\n      _notebooks show \"${_notebook_name:-}\" --path 2>/dev/null || :\n    )\"\n\n    if [[ -z \"${_notebook_path:-}\" ]]\n    then\n      _warn printf \"Notebook not found: %s\\\\n\" \\\n        \"$(_color_primary \"${_notebook_name:-}\")\"\n\n      return 1\n    fi\n  else\n    _notebook_name=\"$(_notebooks current --name)\"\n    _notebook_path=\"$(_notebooks current --path)\"\n  fi\n\n  _notebooks select \"${_notebook_path}\"\n\n  printf \"%s\\\\n\" \"$(_color_primary \"${_notebook_name}\")\"\n  _print_line \"${_notebook_name}\"\n\n  printf \"status: \"\n\n  if [[ \"$(_notebooks status \"${_notebook_name}\")\" =~ not\\ archived ]]\n  then\n    printf \"unarchived\\\\n\"\n  else\n    printf \"archived\\\\n\"\n  fi\n\n  printf \"remote: \"\n\n  _remote 2>/dev/null || printf \"none\\\\n\"\n\n  printf \"git:    \"\n\n  local _git_status_files=\n  _git_status_files=\"$(git -C \"${_notebook_path}\" status --porcelain)\"\n\n  if [[ -n \"${_git_status_files:-}\" ]]\n  then\n    printf \"dirty\\\\n\\\\nchanges\\\\n\"\n\n    _print_line \"changes\"\n\n    git -C \"${_notebook_path}\" status --porcelain\n  else\n    printf \"clean\\\\n\"\n  fi\n}\n_alias_subcommand \"status\" \"st\"\n_alias_subcommand \"status\" \"stat\"\n\n# sync ################################################################### sync\n\n_describe_sync() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} sync [-a | --all]\n\n$(_color_primary \"Options\"):\n  -a, --all   Sync all unarchived notebooks.\n\n$(_color_primary \"Description\"):\n  Sync the current notebook with its remote.\n\n$(_color_primary \"Private Repositories and Git Credentials\"):\n  Syncing with private repositories requires configuring git to not prompt\n  for credentials.\n\n  For repositories cloned over HTTPS, credentials can be cached with git.\n  For repositories cloned over SSH, keys can be added to the ssh-agent.\n\n  More Information:\n    ${_README_URL}#private-repositories-and-git-credentials\n\n$(_color_primary \"Sync Conflict Resolution\"):\n  When \\`${_ME} sync\\` encounters a conflict in a text file and can't merge\n  overlapping local and remote changes, both versions are saved in the\n  file, separated by git conflict markers. Use \\`${_ME} edit\\` to remove the\n  conflict markers and delete any unwanted text.\n\n  When \\`${_ME} sync\\` encounters a conflict in a binary file, such as an\n  encrypted note or bookmark, both versions of the file are saved in the\n  notebook as individual files, one with \\`--conflicted-copy\\` appended to\n  the filename.\n\n  More Information:\n    ${_README_URL}#sync-conflict-resolution\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-git-sync\n  ${_README_URL}#-revision-history\n\n$(_color_primary \"See Also\"):\n  ${_ME} help history\n  ${_ME} help notebooks\n  ${_ME} help remote\n  ${_ME} help status\n\n$(_color_primary \"Examples\"):\n  ${_ME} sync\n  ${_ME} sync --all\nHEREDOC\n}\n_sync() {\n  local _notebooks=()\n  local _sync_all=0\n\n  if [[ \"${1:-}\" =~ (^-a$|^--all$) ]]\n  then\n    _sync_all=1\n\n    local _notebook_names=()\n    _notebooks=($(_notebooks --names --no-color --unarchived))\n  else\n    _notebooks=($(_notebooks current))\n  fi\n\n  local _sync_successful=0\n  local _sync_started=0\n  local _syncable_count=0\n\n  local __notebook=\n  for   __notebook in \"${_notebooks[@]:-}\"\n  do\n    if [[ \"${__notebook}\" == \"local\"      ]] &&\n       [[ -n \"${_LOCAL_NOTEBOOK_PATH:-}\"  ]]\n    then\n      NB_NOTEBOOK_PATH=\"${_LOCAL_NOTEBOOK_PATH}\"\n    else\n      NB_NOTEBOOK_PATH=\"${NB_DIR}/${__notebook}\"\n    fi\n\n    if ((_sync_all))\n    then\n      _remote &>/dev/null || continue\n    else\n      _remote 1>/dev/null || {\n        cat <<HEREDOC\n\nSet the remote for the current notebook:\n\n  $(_color_primary \"${_ME} remote set <url>\")\n\nSet the remote for a notebook named \"example\":\n\n  $(_color_primary \"${_ME} example:remote set <url>\")\n\nHEREDOC\n\n        return 1\n      }\n    fi\n\n    if ! ((_sync_started))\n    then\n      printf \"Syncing: \"\n      _sync_started=1\n    fi\n\n    printf \"%s...\" \"$(_color_primary \"${__notebook}\")\"\n\n    local _notebook_sync_successful=0\n\n    _syncable_count=\"$((_syncable_count+1))\"\n\n    if ((_sync_all))\n    then # sync without prompt in background\n      GIT_TERMINAL_PROMPT=0 NB_AUTO_SYNC=1 \\\n        _git checkpoint \"${NB_NOTEBOOK_PATH}\" \"[${_ME}] Sync\" --wait\n    else # sync with prompt in foreground\n      GIT_TERMINAL_PROMPT=1 NB_AUTO_SYNC=0 \\\n        _git checkpoint \"${NB_NOTEBOOK_PATH}\" \"[${_ME}] Sync\" --wait\n\n      _git sync \"${NB_NOTEBOOK_PATH}\"\n\n      if ! _index verify \"${NB_NOTEBOOK_PATH}\" &>/dev/null\n      then\n        _index reconcile \"${NB_NOTEBOOK_PATH}\" --commit\n\n        while [[ -n \"$(git -C \"${NB_NOTEBOOK_PATH}\" status --porcelain)\" ]]\n        do\n          sleep 1\n        done\n\n        _git sync \"${NB_NOTEBOOK_PATH}\"\n      fi\n    fi && _notebook_sync_successful=1\n\n    if ! ((_notebook_sync_successful))            ||\n       _git dirty           \"${NB_NOTEBOOK_PATH}\" ||\n       _git out_of_sync     \"${NB_NOTEBOOK_PATH}\"\n    then\n      _exit_1 cat <<HEREDOC\nSync failed.\n\nReason unknown, but likely one of the following:\n\n- Authentication error or credentials not configured.\n- Network unavailable.\n- Misconfigured remote URL.\n\nConfiguring Git Credentials:\n  ${_README_URL}#private-repositories-and-git-credentials\nHEREDOC\n    fi\n  done && ((_syncable_count)) && _sync_successful=1\n\n  if ((_sync_successful))\n  then\n    printf \"Done!\\\\n\"\n  elif ! ((_syncable_count))\n  then\n    _exit_1 cat <<HEREDOC\nNo unarchived notebooks with remotes found.\n\nSet the remote for the current notebook:\n\n  $(_color_primary \"${_ME} remote set <url>\")\n\nSet the remote for a notebook named \"example\":\n\n  $(_color_primary \"${_ME} example:remote set <url>\")\n\nHEREDOC\n  else\n    printf \"\\\\n\"\n\n    _exit_1 printf \"Sync failed.\\\\n\"\n  fi\n}\n\n# tasks ################################################################# tasks\n\n_describe_tasks() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n           [open | closed] [--pager]\n\n$(_color_primary \"Options\"):\n  --pager  Display output in the pager.\n\n$(_color_primary \"Description\"):\n  List tasks in todos, notebooks, folders, and other items.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#%EF%B8%8F-tasks\n  ${_README_URL}#-todos\n\n$(_color_primary \"See Also\"):\n  ${_ME} help do\n  ${_ME} help todo\n  ${_ME} help undo\n\n$(_color_primary \"Examples\"):\n  ${_ME} tasks\n  ${_ME} tasks open\n  ${_ME} tasks closed\n  ${_ME} tasks 123\n  ${_ME} example:tasks open\n  ${_ME} tasks closed sample/\n  ${_ME} tasks closed demo:456\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} t\nHEREDOC\n}\n_tasks() {\n  _todo \"tasks\" \"${@:-}\"\n}\n_alias_subcommand \"tasks\" \"task\"\n\n# todo ################################################################### todo\n\n_describe_todo() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} todo add [<notebook>:][<folder-path>/][<filename>] <title>\n              [--description <description>] [--due <date>]\n              [-r (<url> | <selector>) | --related (<url> | <selector>)]\n              [--tags <tag1>,<tag2>...] [--task <title>...]\n  ${_ME} todo delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  ${_ME} todo do   ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  ${_ME} todo undo ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n               [<task-number>]\n  ${_ME} todos [<notebook>:][<folder-path>/] [open | closed] [--pager]\n               [--tags <tag1>,<tag2>...]\n  ${_ME} todos tasks ([<notebook>:][<folder-path>/][<id> | <filename> | <description>])\n                 [open | closed] [--pager]\n\n$(_color_primary \"Options\"):\n  --description <description>         Description for the todo.\n  --due <date>                        Due date and / or time for the todo.\n  --pager                             Display output in the pager.\n  -r, --related (<url> | <selector>)  Related URL or selector.\n  --tags <tag1>,<tag2>...             Comma-separated list of tags.\n  --task <title>                      Task to add to the tasklist.\n\n$(_color_primary \"Subcommands\"):\n  (default)   List todos.\n  add         Add a new todo.\n              Shortcut Aliases: \\`${_ME} todo a\\`, \\`${_ME} todo +\\`\n  delete      Delete a todo.\n              Shortcut Alias: \\`${_ME} todo -\\`\n  do          Mark a todo or task as done.\n  tasks       List tasks in todos, notebooks, folders, and other item.\n  undo        Unmark a todo or task as done.\n\n$(_color_primary \"Description\"):\n  Manage todos and tasks.\n\n$(_color_primary \"Read More:\"):\n  ${_README_URL}#-todos\n\n$(_color_primary \"See Also\"):\n  ${_ME} help do\n  ${_ME} help tasks\n  ${_ME} help undo\n\n$(_color_primary \"Examples\"):\n  ${_ME} todo add \"Example todo title.\"\n  ${_ME} todo add Example todo title.\n  ${_ME} todo add \"Sample title.\" --tags tag1,tag2 --related demo:567\n  ${_ME} todos\n  ${_ME} todos open\n  ${_ME} todos closed\n  ${_ME} example:todos open\n  ${_ME} todos closed sample/\n\n$(_color_primary \"Alias\"):\n  ${_ME} todos\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} to\nHEREDOC\n}\n_todo() {\n  # Usage: _todo_get_task <path> <task-number>\n  _todo_get_task() {\n    local _counter=0\n    local _item_path=\"${1:?}\"\n    local _task_number=\"${2:?}\"\n\n    {\n      cat \"${_item_path:-}\"\n    } | {\n      local         __line=\n      while read -r __line\n      do\n        if [[ \"${__line}\" =~ (\\-\\ \\[\\]|\\-\\ \\[\\ \\]|\\-\\ \\[\\x\\]) ]]\n        then\n          _counter=\"$((_counter+1))\"\n\n          if [[ \"${_counter:-}\" == \"${_task_number:-}\" ]]\n          then\n            printf \"%s\\\\n\" \"${__line}\"\n\n            return 0\n          fi\n        fi\n      done\n\n      return 1\n    }\n  }\n\n  # Usage: _todo_update_task <path> <number> <action>\n  _todo_update_task() {\n    local _action=\"${3:?}\"\n    local _counter=0\n    local _item_path=\"${1:?}\"\n    local _task_number=\"${2:?}\"\n\n    local _temp_file_path=\n    _temp_file_path=\"$(_temp file)\"\n\n    case \"${_action:-}\" in\n      do)   local _replacement_box=\"- [x]\" ;;\n      undo) local _replacement_box=\"- [ ]\" ;;\n    esac\n\n    {\n      cat \"${_item_path:-}\"\n    } | {\n      local         __line=\n      while read -r __line\n      do\n        if [[ \"${__line}\" =~ (\\-\\ \\[\\]|\\-\\ \\[\\ \\]|\\-\\ \\[\\x\\]) ]]\n        then\n          _counter=\"$((_counter+1))\"\n\n          if [[ \"${_counter:-}\" ==  \"${_task_number:-}\"     ]]\n          then\n            printf \"%s\\\\n\" \"${__line}\"                      \\\n              | LC_ALL=C sed                                \\\n                  -e \"s/- \\[\\]/${_replacement_box}/\"        \\\n                  -e \"s/- \\[ \\]/${_replacement_box}/\"       \\\n                  -e \"s/- \\[x\\]/${_replacement_box}/\"\n          else\n            printf \"%s\\\\n\" \"${__line}\"\n          fi\n        else\n          printf \"%s\\\\n\" \"${__line}\"\n        fi\n      done\n\n      if [[ \"${_task_number:-}\" -gt \"${_counter:-}\"         ]]\n      then\n        _exit_1 printf \"Task not found.\\\\n\"\n      fi\n    } | {\n      cat > \"${_temp_file_path}\"\n    }\n\n    cat \"${_temp_file_path}\"  > \"${_item_path}\"\n\n    [[ -f \"${_temp_file_path:?}\" ]] && rm -rf \"${_temp_file_path:?}\"\n  }\n\n  local _action=\n  local _arguments=()\n  local _description=\n  local _due_datetime=\n  local _filter=\n  local _maybe_title_arguments=()\n  local _only_todos=0\n  local _option_title=\n  local _related_identifiers=()\n  local _tag_list_with_commas=\n  local _tag_list_with_spaces=\n  local _tags=()\n  local _task_list_options=()\n  local _tasks=()\n  local _use_pager=0\n\n  while ((${#}))\n  do\n    case \"${1:-}\" in\n      --description)\n        _description=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --due)\n        _due_datetime=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      --pager|--less)\n        _use_pager=1\n        ;;\n      --recursive|--tree)\n        _task_list_options+=(\"--recursive\")\n        ;;\n      -r|--via|--also|--related)\n        _related_identifiers+=(\"$(_option_get_value \"${1:-}\" \"${2:-}\")\")\n\n        shift\n        ;;\n      --tag*|\\#*)\n        [[ -n \"${_tag_list_with_commas:-}\"  ]] && _tag_list_with_commas+=\",\"\n        [[ -n \"${_tag_list_with_spaces:-}\"  ]] && _tag_list_with_spaces+=\" \"\n\n        if [[ \"${1:-}\" =~ ^-- ]]\n        then\n          _tag_list_with_commas+=\"$(_option_get_tags \"${1}\" \"${2:-}\")\"\n          _tag_list_with_spaces+=\"$(_option_get_tags \"${1}\" \"${2:-}\")\"\n          _tags+=(\"${2:-}\")\n\n          shift\n        else\n          _tag_list_with_commas+=\"${1:-}\"\n          _tag_list_with_spaces+=\"${1:-}\"\n          _tags+=(\"${1:-}\")\n        fi\n        ;;\n      --task)\n        _tasks+=(\"$(_option_get_value \"${1:-}\" \"${2:-}\")\")\n\n        shift\n        ;;\n      --title)\n        _option_title=\"$(_option_get_value \"${1:-}\" \"${2:-}\")\"\n\n        shift\n        ;;\n      *)\n        if [[ \"${_action:-}\" == \"add\"       ]]\n        then\n          case \"${1:-}\" in\n            --edit) _arguments+=(\"${1:-}\")  ;;\n            -*)\n              _arguments+=(\"${1:-}\")\n\n              if _option_value_is_present \"${2:-}\"\n              then\n                _arguments+=(\"${2:-}\")\n\n                shift\n              fi\n              ;;\n            *)\n              _maybe_title_arguments+=(\"${1:-}\")\n              ;;\n          esac\n        fi\n\n        case \"${1:-}\" in\n          add|+|a)\n            if [[ -z \"${_action:-}\"     ]]  ||  [[ \"${_action:-}\" == \"tasks\" ]]\n            then\n              _action=\"add\"\n            fi\n            ;;\n          c|closed|checked|completed|done|finished)\n            _filter=\"closed\"\n            ;;\n          delete|remove|rm|trash|-)\n            if [[ -z \"${2:-}\" ]]\n            then\n              _help \"todo\"\n\n              return 1\n            fi\n\n            _delete \"${2:-}\" \"${3:-}\"\n\n            return 0\n            ;;\n          d|do|close|complete|finish|check)\n            if [[ -z \"${_action:-}\"     ]]  ||  [[ \"${_action:-}\" == \"tasks\" ]]\n            then\n              _action=\"do\"\n            fi\n            ;;\n          l|list)\n            if [[ -z \"${_action:-}\"     ]]\n            then\n              _action=\"list\"\n            fi\n            ;;\n          o|open|incomplete|unchecked|undone|unfinished)\n            _filter=\"open\"\n            ;;\n          tasks)\n            if [[ -z \"${_action:-}\"     ]]\n            then\n              _action=\"tasks\"\n            fi\n            ;;\n          todos)\n            _only_todos=1\n            ;;\n          u|undo|uncomplete|unfinish|uncheck)\n            if [[ -z \"${_action:-}\"     ]]  ||  [[ \"${_action:-}\" == \"tasks\" ]]\n            then\n              _action=\"undo\"\n            fi\n            ;;\n          *)\n            [[ \"${_action:-}\" != \"add\"  ]]  &&  _arguments+=(\"${1:-}\")\n            ;;\n        esac\n        ;;\n    esac\n\n    shift\n  done\n\n  if [[ -z \"${_action:-}\" ]]\n  then\n    _action=\"list\"\n  fi\n\n  if [[ \"${_SUBCOMMAND:-}\"  == \"t\"      ]]  &&\n     [[ \"${_action:-}\"      == \"list\"   ]]  &&\n     ! ((_only_todos))\n  then\n    _action=\"tasks\"\n  fi\n\n  case \"${_action:-}\" in\n    add)\n      local _first=1\n      local _title=\n\n      local __argument=\n      for   __argument in \"${_maybe_title_arguments[@]:-}\"\n      do\n        if ((_first))\n        then\n          if [[ \"${__argument:-}\" =~ (:$|/$) ]]\n          then\n            _arguments+=(\"${__argument}\")\n          else\n            _title+=\"${__argument}\"\n          fi\n\n          _first=0\n        else\n          [[ -n \"${_title:-}\"       ]] && _title+=\" \"\n\n          _title+=\"${__argument}\"\n        fi\n      done\n\n      if [[ -n \"${_option_title:-}\" ]]\n      then\n        if [[ -n \"${_title:-}\"      ]]\n        then\n          _title=\"${_option_title} ${_MD} ${_title}\"\n        else\n          _title=\"${_option_title}\"\n        fi\n      fi\n\n      if [[ -z \"${_title:-}\"        ]]\n      then\n        _exit_1 _help \"todo\"\n      fi\n\n      local _todo_content=\"# [ ] ${_title:-}${_NEWLINE}\"\n\n      if [[ -n \"${_due_datetime:-}\" ]]\n      then\n        _todo_content+=\"${_NEWLINE}## Due${_NEWLINE}\"\n        _todo_content+=\"${_NEWLINE}${_due_datetime:-}${_NEWLINE}\"\n      fi\n\n      if [[ -n \"${_description:-}\"  ]]\n      then\n        _todo_content+=\"${_NEWLINE}## Description${_NEWLINE}\"\n        _todo_content+=\"${_NEWLINE}${_description}${_NEWLINE}\"\n      fi\n\n      if ((${#_tasks[@]}))\n      then\n        _todo_content+=\"${_NEWLINE}## Tasks${_NEWLINE}${_NEWLINE}\"\n\n        local __task=\n        for   __task in \"${_tasks[@]:-}\"\n        do\n          _todo_content+=\"- [ ] ${__task}${_NEWLINE}\"\n        done\n      fi\n\n      if ((${#_related_identifiers[@]}))\n      then\n        _todo_content+=\"${_NEWLINE}## Related${_NEWLINE}${_NEWLINE}\"\n        _todo_content+=\"$(_build_related_list \"${_related_identifiers[@]:-}\")\"\n        _todo_content+=\"${_NEWLINE}\"\n      fi\n\n      if [[ -n \"${_tag_list_with_spaces:-}\" ]]\n      then\n        _todo_content+=\"${_NEWLINE}## Tags${_NEWLINE}\"\n        _todo_content+=\"${_NEWLINE}${_tag_list_with_spaces}${_NEWLINE}\"\n      fi\n\n      _add                                  \\\n        --content \"${_todo_content:-}\"      \\\n        --type    \"todo.md\"                 \\\n        --no-template                       \\\n        \"${_arguments[@]:-}\"\n      ;;\n    do|undo)\n      local _selector=\"${_arguments[0]:-}\"\n      local _task_number=\"${_arguments[1]:-}\"\n\n      if [[ -z \"${_selector:-}\"         ]]\n      then\n        _exit_1 _help \"todo\"\n      fi\n\n      local _selector_path=\n      _selector_path=\"$(_show \"${_selector:-}\" --path 2>/dev/null || :)\"\n\n      if [[ -z \"${_selector_path:-}\"    ]]\n      then\n        _exit_1 printf \"Todo not found.\\\\n\"\n      fi\n\n      local _notebook_path=\n      _notebook_path=\"$(\n        _notebooks show \"${_selector:-}\" --path 2>/dev/null ||\n          _notebooks current --path 2>/dev/null\n      )\"\n\n      if [[ !  \"${_selector_path}\" =~ todo\\.md$   ]]        &&\n         [[ -z \"${_task_number:-}\"                ]]\n      then\n        _exit_1 printf \"Not a todo.\\\\n\"\n      fi\n\n      case \"${_action:-}\" in\n        do)\n          if [[ -n \"${_task_number:-}\"  ]]\n          then\n            _todo_update_task \"${_selector_path:-}\" \"${_task_number:-}\" \"do\"\n\n            local _updated_task=\n            _updated_task=\"$(\n              _todo_get_task \"${_selector_path:-}\" \"${_task_number:-}\"\n            )\"\n\n            if [[ ! \"${_updated_task:-}\" =~ ^[[:space:]]*-\\ \\[x\\] ]]\n            then\n              _warn cat \"${_selector_path}\"\n              _exit_1 printf                      \\\n                \"Unable to mark done: %s\\\\n\"      \\\n                \"$(_todos tasks \"${_selector:-}\" \"${_task_number}\")\"\n            else\n              _todos tasks \"${_selector:-}\" \"${_task_number}\"     \\\n                | LC_ALL=C sed \"3s/^/Done: /\"\n\n              _git checkpoint \"${_notebook_path}\" \\\n                \"[${_ME}] Task Done: $(_show \"${_selector:-}\" --relative-path) ${_task_number}\"\n            fi\n          else\n            _sed_i -e \"s/# \\[ \\]/# \\[x\\]/\" \"${_selector_path}\"\n\n            if ! grep -q \"# \\[x\\]\" \"${_selector_path}\"\n            then\n              _exit_1 printf                      \\\n                \"Unable to mark done: %s\\\\n\"      \\\n                \"$(_color_primary \"${_selector:-}\")\"\n            else\n              printf \"Done: %s\\\\n\" \"$(_list \"${_selector}\")\"\n\n              _git checkpoint \"${_notebook_path}\" \\\n                \"[${_ME}] Done: $(_show \"${_selector:-}\" --relative-path)\"\n            fi\n          fi\n          ;;\n        undo)\n          if [[ -n \"${_task_number:-}\"            ]]\n          then\n            _todo_update_task \"${_selector_path}\" \"${_task_number:-}\" \"undo\"\n\n            local _updated_task=\n            _updated_task=\"$(\n              _todo_get_task \"${_selector_path:-}\" \"${_task_number:-}\"\n            )\"\n\n            if [[ ! \"${_updated_task:-}\" =~ ^[[:space:]]*-\\ \\[\\ \\]  ]]\n            then\n              _exit_1 printf                      \\\n                \"Unable to undo: %s\\\\n\"           \\\n                \"$(_todos tasks \"${_selector:-}\" \"${_task_number}\")\"\n            else\n              _todos tasks \"${_selector:-}\" \"${_task_number}\"       \\\n                | LC_ALL=C sed \"3s/^/Undone: /\"\n\n              _git checkpoint \"${_notebook_path}\" \\\n                \"[${_ME}] Task Undone: $(_show \"${_selector:-}\" --relative-path) ${_task_number}\"\n            fi\n          else\n            _sed_i -e \"s/# \\[x\\]/# \\[ \\]/\" \"${_selector_path}\"\n\n            if ! grep -q \"# \\[ \\]\" \"${_selector_path}\"\n            then\n              _exit_1 printf                      \\\n                \"Unable to undo: %s\\\\n\"           \\\n                \"$(_color_primary \"${_selector:-}\")\"\n            else\n              printf \"Undone: %s\\\\n\" \"$(_list \"${_selector}\")\"\n\n              _git checkpoint \"${_notebook_path}\" \\\n                \"[${_ME}] Undone: $(_show \"${_selector:-}\" --relative-path)\"\n            fi\n          fi\n          ;;\n      esac\n      ;;\n    list)\n      {\n        if [[ -n \"${_tag_list_with_commas:-}\"   ]]\n        then\n          _search                               \\\n            \"${_arguments[@]:-}\"                \\\n            --tags \"${_tag_list_with_commas:-}\" \\\n            --type todo                         \\\n            --list 2>/dev/null\n        else\n          _list                   \\\n            \"${_arguments[@]:-}\"  \\\n            --error-on-empty      \\\n            --type todo           \\\n            2>/dev/null\n        fi\n      } | {\n        case \"${_filter:-}\" in\n          closed)\n            LC_ALL=C sed -E -e \"/${NB_INDICATOR_TODO:-} .*\\[\\ \\].*/d\"\n            ;;\n          open)\n            LC_ALL=C sed -E -e \"/${NB_INDICATOR_TODO_DONE:-} .*\\[.*x.*\\].*/d\"\n            ;;\n          *)\n            cat\n            ;;\n        esac\n      } | {\n        local _counter=0\n\n        local         __line=\n        while read -r __line\n        do\n          _counter=$((_counter+1))\n\n          printf \"%s\\\\n\" \"${__line:-}\"\n        done\n\n        if ! ((_counter))\n        then\n          local _empty_message=\"No\"\n\n          if [[ -n \"${_filter:-}\"     ]]\n          then\n            _empty_message+=\" ${_filter:-}\"\n          fi\n\n          _exit_1 printf \"%s todos found.\\\\n\" \"${_empty_message}\"\n        fi\n      }\n      ;;\n    tasks)\n      local _selector=\"${_arguments[0]:-}\"\n      local _task_number=\"${_arguments[1]:-}\"\n\n      local _maybe_padded_empty_qualifier=\n\n      if [[ -n \"${_filter:-}\"         ]]\n      then\n        _maybe_padded_empty_qualifier=\"${_filter:-} \"\n      elif [[ -n \"${_task_number:-}\"  ]]\n      then\n        _maybe_padded_empty_qualifier=\"matching \"\n      fi\n\n      local _notebook_path=\n      local _selector_path=\n\n      if [[ -n \"${_selector:-}\"       ]]\n      then\n        _notebook_path=\"$(\n          _notebooks _show \"${_selector:-}\" --path 2>/dev/null ||\n            _notebooks current --path\n        )\"\n\n        _selector_path=\"$(\n          _show \"${_selector:-}\" --path 2>/dev/null || :\n        )\"\n      fi\n\n      if [[ -z \"${_selector_path:-}\"  ]]\n      then\n        _selector_path=\"$(_notebooks current --path)\"\n      fi\n\n      local _selector_is_item=1\n\n      if [[ -d \"${_selector_path:-}\"  ]]\n      then\n        _selector_is_item=0\n        _selector_path=\"${_selector_path:-}/\"\n      fi\n\n      local _task_closed_patterns=(\n        -e \"- \\[x\\]\"\n      )\n      local _task_open_patterns=(\n        -e \"- \\[ \\]\"\n        -e \"^- \\[\\]\"\n        -e \"[[:space:]]- \\[\\]\"\n      )\n\n      local _todo_closed_patterns=(\n        -e \"# \\[x\\]\"\n      )\n      local _todo_open_patterns=(\n        -e \"# \\[ \\]\"\n        -e \"# \\[\\]\"\n      )\n\n      {\n        if [[ -n \"${_tag_list_with_commas:-}\"   ]]\n        then\n          _search                               \\\n            \"${_selector_path:-}\"               \\\n            \"${_task_list_options[@]:-}\"        \\\n            --tags \"${_tag_list_with_commas:-}\" \\\n            --type todo                         \\\n            --path\n        else\n          _list \"${_selector_path:-}\"     \\\n            --error-on-empty              \\\n            --no-id                       \\\n            --no-indicator                \\\n            --path                        \\\n            --type md                     \\\n            \"${_task_list_options[@]:-}\"  \\\n            2>/dev/null || printf \"\"\n        fi\n      } | {\n        local _first=1\n        local _in_task_list_item=0\n\n        local         __item_path=\n        while read -r __item_path\n        do\n          [[ -z \"${__item_path:-}\"    ]]    && continue\n          [[ -d \"${__item_path:-}\"    ]]    && continue\n\n          grep -q                           \\\n            \"${_task_closed_patterns[@]:-}\" \\\n            \"${_task_open_patterns[@]:-}\"   \\\n            \"${_todo_closed_patterns[@]:-}\" \\\n            \"${_todo_open_patterns[@]:-}\"   \\\n            \"${__item_path}\" || continue\n\n          local _item_listing_no_color=\n          _item_listing_no_color=\"$(\n            _list \"${__item_path:-}\" --no-color --no-indicator\n          )\"\n\n          local _item_selector=\"${_item_listing_no_color#[}\"\n          _item_selector=\"${_item_selector%%]*}\"\n\n          local _is_todo=0\n          local _todo_done=0\n\n          if _file_is_todo \"${__item_path:-}\"\n          then\n            _is_todo=1\n\n            if [[ \"${_item_listing_no_color:-}\" =~ \\[x\\]  ]]\n            then\n              _todo_done=1\n            fi\n          fi\n\n          local _filtered_task_patterns=()\n\n          case \"${_filter:-}\" in\n            closed) _filtered_task_patterns=(\"${_task_closed_patterns[@]:-}\") ;;\n            open)   _filtered_task_patterns=(\"${_task_open_patterns[@]:-}\")   ;;\n            *)\n              _filtered_task_patterns=(\n                \"${_task_closed_patterns[@]:-}\"\n                \"${_task_open_patterns[@]:-}\"\n              )\n              ;;\n          esac\n\n          local _contains_filtered_tasks=0\n\n          if grep -q                          \\\n            \"${_filtered_task_patterns[@]:-}\" \\\n            \"${__item_path}\"\n          then\n            _contains_filtered_tasks=1\n          fi\n\n          local _print_listing=1\n\n          if ! ((_contains_filtered_tasks))\n          then\n            if ! ((_is_todo))\n            then\n              _print_listing=0\n            fi\n\n            case \"${_filter:-}\" in\n              closed) ((_todo_done)) || _print_listing=0 ;;\n              open)   ((_todo_done)) && _print_listing=0 ;;\n            esac\n\n            if ((_selector_is_item))\n            then\n              _print_listing=1\n            fi\n          fi\n\n          if ! ((_print_listing))\n          then\n            continue\n          fi\n\n          if ((_contains_filtered_tasks))\n          then\n            _in_task_list_item=1\n\n            ((_first)) || printf \"\\\\n\"\n          elif ((_in_task_list_item))\n          then\n            _in_task_list_item=0\n\n            ((_first)) || printf \"\\\\n\"\n          fi\n\n          _list \"${__item_path:-}\"\n\n          _first=0\n\n          if ! ((_contains_filtered_tasks)) && ! ((_selector_is_item))\n          then\n            continue\n          fi\n\n          local _info_line_no_color=\n          _info_line_no_color=\"$(\n            _list \"${__item_path:-}\" --no-color\n          ) \"\n\n          local _extra_length=0\n\n          case \"${_info_line_no_color:-}\" in\n            *${_NB_INDICATOR_TODO_DONE}*) _extra_length=\"0\"   ;;\n            *${_NB_INDICATOR_TODO}*)      _extra_length=\"-3\"  ;;\n            *)                            _extra_length=\"-1\"  ;;\n          esac\n\n          _print_line \"${_info_line_no_color:-}\"  \\\n            --no-wrap                             \\\n            --visible-length \"${_extra_length:-0}\"\n\n          {\n            grep                        \\\n              -e \"- \\[[[:space:]]*\\] \"  \\\n              -e \"- \\[x\\] \"             \\\n              \"${__item_path:-}\" || :\n          } | {\n            local _counter=0\n            local _printed_task_counter=0\n\n            local         __task=\n            while read -r __task\n            do\n              _counter=\"$((_counter+1))\"\n\n              local _print_task=0\n\n              case \"${_filter:-}\" in\n                closed)\n                  if [[ \"${__task}\" =~ \\-\\ \\[x\\]              ]]\n                  then\n                    _print_task=1\n                  fi\n                  ;;\n                open)\n                  if [[ \"${__task}\" =~ (\\-\\ \\[\\ \\]|\\-\\ \\[\\])  ]]\n                  then\n                    _print_task=1\n                  fi\n                  ;;\n                *)\n                  _print_task=1\n                  ;;\n              esac\n\n              if [[ \"${_task_number:-${_counter:-}}\" != \"${_counter:-}\" ]]\n              then\n                _print_task=0\n              fi\n\n              if ((_print_task))\n              then\n                local _formatted_task=\"${__task#- }\"\n                _formatted_task=\"${_formatted_task//\\[x\\]/$(_color_brackets \"$(_color_primary \"x\")\")}\"\n                _formatted_task=\"${_formatted_task//\\[\\]/$(_color_brackets \" \")}\"\n                _formatted_task=\"${_formatted_task//\\[ \\]/$(_color_brackets \" \")}\"\n\n                if [[ -z \"${_task_number:-}\" ]]\n                then\n                  _wrap off\n                fi\n\n                printf \"%s %s\"                                          \\\n                  \"$(_color_brackets \"${_item_selector} ${_counter}\")\"  \\\n                  \"${_formatted_task}\"\n\n                if [[ -z \"${_task_number:-}\" ]]\n                then\n                  printf '\\033[?7h'\n                fi\n\n                printf \"\\\\n\"\n\n                _printed_task_counter=\"$((_printed_task_counter+1))\"\n              fi\n            done\n\n            if ! ((_printed_task_counter))\n            then\n              printf \"0 %stasks.\\\\n\" \"${_maybe_padded_empty_qualifier:-}\"\n            fi\n          }\n        done\n      } | {\n        local _printed_line_counter=0\n\n        local         __task_line=\n        while read -r __task_line\n        do\n          printf \"%s\\\\n\" \"${__task_line:-}\"\n          _printed_line_counter=\"$((_printed_line_counter+1))\"\n        done\n\n        if ! ((_printed_line_counter))\n        then\n          _warn printf \"0 %stasks.\\\\n\" \"${_maybe_padded_empty_qualifier:-}\"\n\n          return 1\n        fi\n      } | if ((_use_pager))\n      then\n        _pager\n      else\n        cat\n      fi\n      ;;\n  esac\n}\n_alias_subcommand \"todo\" \"t\"\n_alias_subcommand \"todo\" \"to\"\n_alias_subcommand \"todo\" \"todos\"\n\n# unarchive ######################################################### unarchive\n\n_describe_unarchive() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} unarchive [<name>]\n\n$(_color_primary \"Description\"):\n  Remove \"archived\" status from the current notebook or notebook <name>.\n\n  This is an alias for \\`${_ME} notebooks unarchive\\`.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#archiving-notebooks\n\n$(_color_primary \"See Also\"):\n  ${_ME} help archive\n  ${_ME} help notebooks\n  ${_ME} help status\n\n$(_color_primary \"Examples\"):\n  ${_ME} unarchive\n  ${_ME} unarchive example\n\n$(_color_primary \"Shortcut Alias\"):\n  ${_ME} unar\nHEREDOC\n}\n_unarchive() {\n  _notebooks unarchive \"${@:-}\"\n}\n_alias_subcommand \"unarchive\" \"unar\"\n\n# undo ################################################################### undo\n\n_describe_undo() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} undo ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n          [<task-number>]\n\n$(_color_primary \"Description\"):\n  Mark a todo or task as not done.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#-todos\n\n$(_color_primary \"See Also\"):\n  ${_ME} help do\n  ${_ME} help tasks\n  ${_ME} help todo\n\n$(_color_primary \"Examples\"):\n  ${_ME} undo 123\n  ${_ME} undo example:sample/321\n  ${_ME} undo 543 7\nHEREDOC\n}\n_undo() {\n  _todo \"undo\" \"${@:-}\"\n}\n_alias_subcommand \"undo\" \"undone\"\n\n# unset ################################################################# unset\n\n_describe_unset() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} unset (<name> | <number>)\n\n$(_color_primary \"Description\"):\n  Unset a setting, returning it to the default value.\n\n  This is an alias for \\`${_ME} settings unset\\`.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#%EF%B8%8F-set--settings\n\n$(_color_primary \"See Also\"):\n  ${_ME} help settings\n\n$(_color_primary \"Examples\"):\n  ${_ME} unset color_primary\n  ${_ME} unset 2\n\n$(_color_primary \"Alias\"):\n  ${_ME} reset\nHEREDOC\n}\n_unset() {\n  case \"${1:-}\" in\n    '')     _exit_1   _help \"unset\" ; return 1 ;;\n    remote) _remote   unset         ; return 0 ;;\n    *)      _settings unset \"${@:-}\"; return 0 ;;\n  esac\n}\n_alias_subcommand \"unset\" \"reset\"\n\n# update ############################################################### update\n\n_describe_update() {\n  cat <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} update\n\n$(_color_primary \"Description\"):\n  Update \\`${_ME}\\` to the latest version. You will be prompted for\n  your password if administrator privileges are required.\n\n  If \\`${_ME}\\` was installed using a package manager like npm or\n  Homebrew, use the package manager's upgrade functionality instead\n  of this command.\n\n$(_color_primary \"Read More\"):\n  ${_README_URL}#installation\n\n$(_color_primary \"See Also\"):\n  ${_ME} help env\n  ${_ME} help version\nHEREDOC\n}\n_update() {\n  local _current_path=\n  _current_path=\"${BASH_SOURCE[0]}\"\n\n  if [[ -n \"${_current_path}\" ]]  &&\n     [[ -L \"${_current_path}\" ]]\n  then\n    _current_path=\"$(_resolve_symlink \"${_current_path}\")\"\n  fi\n\n  if hash npm 2>/dev/null         &&\n     npm list | grep -q notes.sh  &&\n     [[ \"${_current_path}\"    =~ (\\/node\\/|\\/node_modules\\/)  ]]\n  then # installed with npm\n    cat <<HEREDOC\nInstalled with npm. To update, run:\n  npm update -g notes.sh\nHEREDOC\n  elif hash npm 2>/dev/null       &&\n       npm list | grep -q nb.sh   &&\n       [[ \"${_current_path}\"  =~ (\\/node\\/|\\/node_modules\\/)  ]]\n  then # installed with npm\n    cat <<HEREDOC\nInstalled with npm. To update, run:\n  npm update -g nb.sh\nHEREDOC\n  elif [[ \"${OSTYPE}\"         =~ ^darwin  ]] &&\n       [[ \"${_current_path}\"  =~ Cellar   ]]\n  then\n    cat <<HEREDOC\nInstalled with Homebrew. To update, run:\n  brew upgrade nb\nHEREDOC\n  else\n    local _nb_url=\"${_REPO_RAW_URL}/nb\"\n\n    local _temp_file=\n    _temp_file=\"$(_temp file)\"\n\n    if ! _download_from \"${_nb_url}\" \"${_temp_file}\" --no-chrome\n    then\n      _exit_1 printf \"Unable to download update.\\\\n\"\n    fi\n\n    if [[ \"$(_get_hash \"${_temp_file}\")\" != \"$(_get_hash \"${_current_path}\")\" ]]\n    then\n      while true\n      do\n        printf \"Updating %s in place. \" \"$(_color_primary \"${_ME}\")\"\n\n        local __yn=\n        IFS='' read -r -e -d $'\\n' -p \\\n\"$(_color_primary \"Proceed?\") $(_color_brackets \"y/N\") \" __yn\n\n        case \"${__yn}\" in\n          [Yy]*)\n            break\n            ;;\n          *)\n            printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n            exit 0\n            ;;\n        esac\n      done\n\n      if [[ -w \"${_current_path}\" ]]\n      then\n        cat \"${_temp_file}\" > \"${_current_path}\"\n      else\n        cat \"${_temp_file}\" | sudo tee \"${_current_path}\" > /dev/null\n      fi\n\n      printf \"%s updated to the latest version.\\\\n\" \"$(_color_primary \"${_ME}\")\"\n\n      exit 0\n    else\n      printf \"Already at the latest version.\\\\n\"\n    fi\n\n    if [[ -n \"${_temp_file:-}\" ]] && [[ -f \"${_temp_file}\" ]]\n    then\n      rm \"${_temp_file:?}\"\n    fi\n  fi\n}\n_alias_subcommand \"update\" \"upgrade\"\n\n###############################################################################\n# Call Deferred Command: Group 3                 Call Deferred Command: Group 3\n###############################################################################\n# --------------------------------------------------------------------------- #\n\n_call_deferred_command --group 3\n\nexit 0\n"
  },
  {
    "path": "nb.go/README.md",
    "content": "# `nb.go`\n\n`nb.go` is an implementation of [`nb`](https://github.com/xwmx/nb) written in\n[Go](https://golang.org/).\n\n## Objectives\n\n- Improved Windows support. Runnable with no dependencies on a default Windows\n  install, or as close to default as possible.\n- 1 to 1 feature parity with `nb`, passing the same test suite.\n- Continuously usable during development, falling back to `nb` for\n  functionality not yet implemented in Go.\n- Automatic, zero-configuration performance improvements for `nb` when `nb.go` is installed.\n- Minimal dependencies.\n- Single file.\n\n## Tests\n\nThe `nb.go` test suite consists of Go tests for internal functionality and\nbats tests to verify external behavior of the executable. Tests from the\nprimary bats test suite are symlinked into\n[nb.go/test](https://github.com/xwmx/nb/tree/master/nb.go/test)\nin order to run against `nb.go`. \n\n---\n\n<p align=\"center\">\n  <a href=\"https://github.com/xwmx/nb\">github.com/xwmx/nb</a>\n</p>\n"
  },
  {
    "path": "nb.go/configure_notebook_paths_test.go",
    "content": "// revive:disable:error-strings Errors should match existing `nb` formatting.\n\npackage main\n\nimport (\n\t\"path/filepath\"\n\t\"testing\"\n)\n\nfunc TestConfigureNotebookPathsSetsNotebookPathFields(t *testing.T) {\n\toriginalCfg := config{\n\t\tnbDir: filepath.Join(\"tmp\", \"example-nb-dir\"),\n\t}\n\n\texpectedPath := filepath.Join(originalCfg.nbDir, \"home\")\n\n\tvar returnedCfg config\n\n\treturnedCfg = configureNotebookPaths(originalCfg)\n\n\tif returnedCfg.nbNotebookPath != expectedPath {\n\t\tt.Errorf(\n\t\t\t\"configureNotebookPaths() cfg.nbNotebookPath = %s; want: %s.\",\n\t\t\treturnedCfg.nbNotebookPath,\n\t\t\texpectedPath,\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "nb.go/configure_test.go",
    "content": "// revive:disable:error-strings Errors should match existing `nb` formatting.\n\npackage main\n\nimport (\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestConfigureSetsCurrentWorkingDir(t *testing.T) {\n\n\tpwdOutput, err := exec.Command(\"pwd\").Output()\n\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"exec.Command(\\\"pwd\\\") error = %s\",\n\t\t\terr,\n\t\t)\n\t}\n\n\tpwd := string(pwdOutput)\n\tpwd = strings.TrimSuffix(pwd, \"\\n\")\n\n\texpectedCfg := config{\n\t\tcurrentWorkingDir: pwd,\n\t}\n\n\treturnedCfg, err := configure()\n\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"configure() error = %s\",\n\t\t\terr,\n\t\t)\n\t}\n\n\tif returnedCfg.currentWorkingDir != expectedCfg.currentWorkingDir {\n\t\tt.Errorf(\n\t\t\t\"configure() cfg.currentWorkingDir\\ngot:  '%s'\\nwant: '%s'\",\n\t\t\treturnedCfg.currentWorkingDir,\n\t\t\texpectedCfg.currentWorkingDir,\n\t\t)\n\t}\n\n\tos.Setenv(\"NB_DIR\", \"\")\n}\n\nfunc TestConfigureSetsNbDir(t *testing.T) {\n\tos.Setenv(\"NB_DIR\", filepath.Join(\"tmp\", \"example-nb-dir\"))\n\n\texpectedCfg := config{\n\t\tnbDir: filepath.Join(\"tmp\", \"example-nb-dir\"),\n\t}\n\n\treturnedCfg, err := configure()\n\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"configure() error = %s\",\n\t\t\terr,\n\t\t)\n\t}\n\n\tif returnedCfg.nbDir != expectedCfg.nbDir {\n\t\tt.Errorf(\n\t\t\t\"configure() cfg.nbDir\\ngot:  '%s'\\nwant: '%s'\",\n\t\t\treturnedCfg.nbDir,\n\t\t\texpectedCfg.nbDir,\n\t\t)\n\t}\n\n\tos.Setenv(\"NB_DIR\", \"\")\n}\n"
  },
  {
    "path": "nb.go/contains_test.go",
    "content": "// revive:disable:error-strings Errors should match existing `nb` formatting.\n\npackage main\n\nimport (\n\t\"testing\"\n)\n\nfunc TestContainsWithMatchReturnsTrue(t *testing.T) {\n\tslice := []string{\"one\", \"two\", \"three\"}\n\tquery := \"two\"\n\n\tif !contains(slice, query) {\n\t\tt.Errorf(\n\t\t\t\"contains() expected match not found. slice: %v; element: %v.\",\n\t\t\tslice,\n\t\t\tquery,\n\t\t)\n\t}\n}\n\nfunc TestContainsWithNoMatchReturnsFalse(t *testing.T) {\n\tslice := []string{\"one\", \"two\", \"three\"}\n\tquery := \"not-valid\"\n\n\tif contains(slice, query) {\n\t\tt.Errorf(\n\t\t\t\"contains() unexpected match found. slice: %v; element: %v.\",\n\t\t\tslice,\n\t\t\tquery,\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "nb.go/go.mod",
    "content": "module nb.go\n\ngo 1.23.0\n\ntoolchain go1.23.4\n\nrequire golang.org/x/sys v0.31.0\n"
  },
  {
    "path": "nb.go/go.sum",
    "content": "golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=\ngolang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=\n"
  },
  {
    "path": "nb.go/helpers_test.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"log\"\n\t\"os\"\n)\n\n// https://stackoverflow.com/a/26806093\nfunc captureLogOutput(f func()) string {\n\tvar buf bytes.Buffer\n\tlog.SetOutput(&buf)\n\tf()\n\tlog.SetOutput(os.Stderr)\n\treturn buf.String()\n}\n"
  },
  {
    "path": "nb.go/main.go",
    "content": "// __          _\n// \\ \\   _ __ | |__       __ _  ___\n//  \\ \\ | '_ \\| '_ \\     / _` |/ _ \\\n//  / / | | | | |_) | _ | (_| | (_) |\n// /_/  |_| |_|_.__/ (_) \\__, |\\___/\n//                       |___/\n//\n// [nb.go] An implementation of `nb` in go.\n//\n// ❯ https://github.com/xwmx/nb\n// ❯ https://xwmx.github.io/nb\n//\n// Copyright (c) 2020-present William Melody ┯ hi@williammelody.com\n//                                           ┕ https://www.williammelody.com\n//\n// AGPLv3\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\n// revive:disable:error-strings Errors should match existing `nb` formatting.\n\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\ntype config struct {\n\tcolorEnabled       bool\n\tcurrentWorkingDir  string\n\teditor             string\n\tgitEnabled         bool\n\tglobalNotebookPath string\n\tlocalNotebookPath  string\n\tnbAutoSync         bool\n\tnbColorPrimary     int\n\tnbColorSecondary   int\n\tnbColorTheme       string\n\tnbColorThemes      []string\n\tnbDefaultExtension string\n\tnbDir              string\n\tnbEncryptionTool   string\n\tnbFooter           bool\n\tnbHeader           int\n\tnbLimit            int\n\tnbNotebookPath     string\n\tnbPath             string\n\tnbrcPath           string\n\tnbSyntaxTheme      string\n}\n\n// configure loads the configuration from the environment.\nfunc configure() (config, error) {\n\tvar err error\n\n\tcfg := config{}\n\n\t// currentWorkingDir / PWD\n\t//\n\t// The current working directory in which the program was invoked.\n\n\tif cfg.currentWorkingDir, err = os.Getwd(); err != nil {\n\t\treturn cfg, err\n\t}\n\n\t// `nb` (.sh) path\n\t//\n\t// The path to the `nb` executable.\n\n\tif cfg.nbPath, err = exec.LookPath(\"nb\"); err != nil {\n\t\tadjacentNbPath := filepath.Join(cfg.currentWorkingDir, \"..\", \"nb\")\n\n\t\tif _, err := os.Stat(adjacentNbPath); err == nil {\n\t\t\tcfg.nbPath = adjacentNbPath\n\t\t} else {\n\t\t\treturn cfg, err\n\t\t}\n\t}\n\n\t// $NBRC_PATH\n\t//\n\t// Default: `$HOME/.nbrc`\n\t//\n\t// The location of the .nbrc configuration file.\n\n\tif cfg.nbrcPath = os.Getenv(\"NBRC_PATH\"); cfg.nbrcPath == \"\" {\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\t// TODO\n\t\t} else {\n\t\t\tcfg.nbrcPath = filepath.Join(os.Getenv(\"HOME\"), \".nbrc\")\n\n\t\t\t// TODO: Handle symlinks.\n\t\t\t// TODO: Source rc file.\n\t\t}\n\t}\n\n\t// $NB_DIR\n\t//\n\t// Default: `$HOME/.nb`\n\t//\n\t// The location of the directory that contains the notebooks.\n\n\tif cfg.nbDir = os.Getenv(\"NB_DIR\"); cfg.nbDir == \"\" {\n\t\tvar parentDir string\n\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\t// TODO:\n\t\t\t// - Validate directory.\n\t\t\t// - Confirm directory locations.\n\t\t\t//\n\t\t\t// See also:\n\t\t\t// https://stackoverflow.com/a/49148866\n\n\t\t\tparentDir = os.Getenv(\"APPDATA\")\n\n\t\t\tif parentDir == \"\" {\n\t\t\t\tparentDir = filepath.Join(\n\t\t\t\t\tos.Getenv(\"USERPROFILE\"), \"Application Data\",\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tcfg.nbDir = filepath.Join(parentDir, \"nb\")\n\t\t} else {\n\t\t\tcfg.nbDir = filepath.Join(os.Getenv(\"HOME\"), \".nb\")\n\n\t\t\t// https://godoc.org/golang.org/x/sys/unix#Access\n\t\t\t// https://stackoverflow.com/a/20026945\n\t\t\tif cfg.nbDir == \"\" || cfg.nbDir == \"/\" || unix.Access(cfg.nbDir, unix.W_OK) != nil {\n\t\t\t\terrorString := fmt.Sprintf(`\\\nNB_DIR is not valid:\n  %s\n\nRemove any NB_DIR settings in .nbrc to reset to default:\n  %s\n\nNB_DIR settings prompt:\n  %s settings nb_dir`, cfg.nbDir, cfg.nbrcPath, \"nb\")\n\n\t\t\t\treturn cfg, errors.New(errorString)\n\t\t\t}\n\t\t}\n\t}\n\n\tif cfg.nbDir != \"\" {\n\t\tos.Setenv(\"NB_DIR\", cfg.nbDir)\n\t}\n\n\t// $_GIT_ENABLED\n\t//\n\t// Default: '1'\n\t//\n\t// Supported Values: '0' '1'\n\n\tif os.Getenv(\"_GIT_ENABLED\") == \"0\" {\n\t\tcfg.gitEnabled = false\n\t\tos.Setenv(\"_GIT_ENABLED\", \"0\")\n\t} else {\n\t\tcfg.gitEnabled = true\n\t\tos.Setenv(\"_GIT_ENABLED\", \"1\")\n\t}\n\n\tif cfg.gitEnabled {\n\t\tos.Setenv(\"NB_DIR\", cfg.nbDir)\n\t}\n\n\t// $NB_AUTO_SYNC\n\t//\n\t// Default: '1'\n\t//\n\t// When set to '1', each `_git checkpoint()` call will automativally run\n\t// `$_ME sync`. To disable this behavior, set the value to '0'.\n\n\tif os.Getenv(\"NB_AUTO_SYNC\") == \"0\" {\n\t\tcfg.nbAutoSync = false\n\t\tos.Setenv(\"NB_AUTO_SYNC\", \"0\")\n\t} else {\n\t\tcfg.nbAutoSync = true\n\t\tos.Setenv(\"NB_AUTO_SYNC\", \"1\")\n\t}\n\n\t// $NB_DEFAULT_EXTENSION\n\t//\n\t// Default: 'md'\n\t//\n\t// Example Values: 'md' 'org'\n\n\tif cfg.nbDefaultExtension = os.Getenv(\"NB_DEFAULT_EXTENSION\"); cfg.nbDefaultExtension == \"\" {\n\t\tcfg.nbDefaultExtension = \"md\"\n\t}\n\n\tos.Setenv(\"NB_DEFAULT_EXTENSION\", cfg.nbDefaultExtension)\n\n\t// $NB_ENCRYPTION_TOOL\n\t//\n\t// Default: 'openssl'\n\t//\n\t// Supported Values: 'gpg' 'openssl'\n\n\tif cfg.nbEncryptionTool = os.Getenv(\"NB_ENCRYPTION_TOOL\"); cfg.nbEncryptionTool == \"\" {\n\t\tcfg.nbEncryptionTool = \"openssl\"\n\t}\n\n\tos.Setenv(\"NB_ENCRYPTION_TOOL\", cfg.nbEncryptionTool)\n\n\t// $NB_FOOTER\n\t//\n\t// Default: '1'\n\t//\n\t// Supported Values: '0' '1'\n\n\tif os.Getenv(\"NB_FOOTER\") == \"0\" {\n\t\tcfg.nbFooter = false\n\t\tos.Setenv(\"NB_FOOTER\", \"0\")\n\t} else {\n\t\tcfg.nbFooter = true\n\t\tos.Setenv(\"NB_FOOTER\", \"1\")\n\t}\n\n\t// $NB_HEADER\n\t//\n\t// Default: '2'\n\t//\n\t// Supported Values: '0' '1' '2' '3'\n\n\tif cfg.nbHeader, err = strconv.Atoi(os.Getenv(\"NB_HEADER\")); err != nil {\n\t\tcfg.nbHeader = 2\n\t}\n\n\tos.Setenv(\"NB_HEADER\", strconv.Itoa(cfg.nbHeader))\n\n\t// $NB_LIMIT\n\t//\n\t// Default: '20'\n\t//\n\t// Supported Values: any positive number\n\n\tif cfg.nbLimit, err = strconv.Atoi(os.Getenv(\"NB_LIMIT\")); err != nil {\n\t\tcfg.nbLimit = 20\n\t}\n\n\tos.Setenv(\"NB_HEADER\", strconv.Itoa(cfg.nbLimit))\n\n\t// $NB_SYNTAX_THEME\n\t//\n\t// Default: 'base16'\n\t//\n\t// Supported Values: Theme names listed with `bat --list-themes`\n\n\tif cfg.nbSyntaxTheme = os.Getenv(\"NB_SYNTAX_THEME\"); cfg.nbSyntaxTheme == \"\" {\n\t\tcfg.nbSyntaxTheme = \"base16\"\n\t}\n\n\tos.Setenv(\"NB_SYNTAX_THEME\", cfg.nbSyntaxTheme)\n\n\t// Notebook Paths\n\n\tcfg = configureNotebookPaths(cfg)\n\n\t// return\n\n\treturn cfg, nil\n}\n\n// configureNotebookPaths takes a configuration and returns a copy with\n// notebook path fields set to values derived from the environment.\nfunc configureNotebookPaths(cfg config) config {\n\t// TODO\n\n\tcfg.nbNotebookPath = filepath.Join(cfg.nbDir, \"home\")\n\n\treturn cfg\n}\n\n// contains takes a slice of strings and a string and returns a boolean\n// indicating whether the slice contains the string.\nfunc contains(slice []string, query string) bool {\n\tfor _, e := range slice {\n\t\tif e == query {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// run loads the configuration and environment, then runs the subcommand.\nfunc run() (io.Reader, chan int, error) {\n\tvar cfg config\n\tvar err error\n\tvar exitStatusChannel chan int\n\tvar outputReader io.Reader\n\n\tif cfg, err = configure(); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\targs := os.Args\n\tenv := os.Environ()\n\n\tif len(args) > 1 && args[1] == \"run\" {\n\t\toutputReader, exitStatusChannel, err = runSubCmdRun(\n\t\t\tsubCmdCall{\n\t\t\t\targs:        args[2:],\n\t\t\t\tcfg:         cfg,\n\t\t\t\tenv:         env,\n\t\t\t\tinputReader: os.Stdin,\n\t\t\t\toptions:     map[string]string{\"execType\": \"forkexec\"},\n\t\t\t\t// options: map[string]string{\"execType\": \"goroutine\"},\n\t\t\t},\n\t\t)\n\t\tif err != nil {\n\t\t\treturn outputReader, exitStatusChannel, err\n\t\t}\n\t} else {\n\t\tif err := syscall.Exec(cfg.nbPath, args, env); err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t}\n\n\treturn outputReader, exitStatusChannel, nil\n}\n\n// main is the primary entry point for the program.\nfunc main() {\n\tos.Exit(present(run()))\n}\n\nfunc pipedInputIsPresent() bool {\n\t// Resources:\n\t// https://flaviocopes.com/go-shell-pipes/\n\t// https://coderwall.com/p/zyxyeg/golang-having-fun-with-os-stdin-and-shell-pipes\n\tinfo, err := os.Stdin.Stat()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tif info.Mode()&os.ModeCharDevice != 0 || info.Size() <= 0 {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n// present prints the output to standard out or standard error and returns the\n// appropriate exit code.\nfunc present(output io.Reader, exitStatusChannel chan int, err error) int {\n\texitStatus := 0\n\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"%v\\n\", err)\n\n\t\treturn 1\n\t}\n\n\tif output != nil {\n\t\tio.Copy(os.Stdout, output)\n\t}\n\n\tif exitStatusChannel != nil {\n\t\texitStatus = <-exitStatusChannel\n\t}\n\n\treturn exitStatus\n}\n\ntype subCmd struct {\n\taliasFor    string\n\tdocumented  bool\n\tfunction    subCmdFunc\n\tname        string\n\ttriggersGit bool\n\tusage       string\n}\n\ntype subCmdCall struct {\n\targs        []string\n\tcfg         config\n\tenv         []string\n\tinputReader io.Reader\n\toptions     map[string]string\n}\n\ntype subCmdFunc func(subCmdCall) (io.Reader, chan int, error)\n\nvar subCmdList = subCmd{\n\tdocumented:  true,\n\tfunction:    runSubCmdList,\n\tname:        \"list\",\n\ttriggersGit: true,\n}\n\n// runSubCmdList runs the `list` subcommand.\nfunc runSubCmdList(call subCmdCall) (io.Reader, chan int, error) {\n\treturn nil, nil, nil\n}\n\nvar subCmdLs = subCmd{\n\tdocumented:  true,\n\tfunction:    runSubCmdLs,\n\tname:        \"ls\",\n\ttriggersGit: true,\n}\n\n// runSubCmdLs runs the `ls` subcommand.\nfunc runSubCmdLs(call subCmdCall) (io.Reader, chan int, error) {\n\treturn nil, nil, nil\n}\n\nvar subCmdRun = subCmd{\n\tdocumented:  true,\n\tfunction:    runSubCmdRun,\n\tname:        \"run\",\n\ttriggersGit: true,\n}\n\n// runSubCmdRun runs the `run` subcommand.\nfunc runSubCmdRun(call subCmdCall) (io.Reader, chan int, error) {\n\tif len(call.args) == 0 {\n\t\treturn nil, nil, errors.New(\"Command required.\")\n\t}\n\n\texitStatusChannel := make(chan int)\n\texitStatus := 0\n\n\tvar outputReader io.ReadCloser\n\tvar outputWriter io.WriteCloser\n\n\tif call.options[\"execType\"] == \"forkexec\" {\n\t\tpid, err := syscall.ForkExec(\n\t\t\t\"/usr/bin/env\",\n\t\t\t[]string{\"/usr/bin/env\", \"bash\", \"-c\", strings.Join(call.args, \" \")},\n\t\t\t&syscall.ProcAttr{\n\t\t\t\tDir:   call.cfg.nbNotebookPath,\n\t\t\t\tEnv:   call.env,\n\t\t\t\tFiles: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()},\n\t\t\t},\n\t\t)\n\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tproc, err := os.FindProcess(pid)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tstate, err := proc.Wait()\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tif status, ok := state.Sys().(syscall.WaitStatus); ok {\n\t\t\texitStatus = status.ExitStatus()\n\t\t}\n\n\t\tgo func() {\n\t\t\texitStatusChannel <- exitStatus\n\t\t}()\n\t} else {\n\t\toutputReader, outputWriter = io.Pipe()\n\n\t\tgo func() {\n\t\t\tcmd := exec.Command(call.args[0], call.args[1:]...)\n\n\t\t\tcmd.Dir = call.cfg.nbNotebookPath\n\t\t\tcmd.Stderr = os.Stderr\n\t\t\tcmd.Stdout = outputWriter\n\n\t\t\tcmd.Start()\n\n\t\t\t// https://stackoverflow.com/a/10385867\n\t\t\tif err := cmd.Wait(); err != nil {\n\t\t\t\texitStatus = 1\n\n\t\t\t\tif exiterr, ok := err.(*exec.ExitError); ok {\n\t\t\t\t\t// The program has exited with an exit code != 0\n\n\t\t\t\t\t// This works on both Unix and Windows. Although package\n\t\t\t\t\t// syscall is generally platform dependent, WaitStatus is\n\t\t\t\t\t// defined for both Unix and Windows and in both cases has\n\t\t\t\t\t// an ExitStatus() method with the same signature.\n\t\t\t\t\tif status, ok := exiterr.Sys().(syscall.WaitStatus); ok {\n\t\t\t\t\t\texitStatus = status.ExitStatus()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\toutputWriter.Close()\n\n\t\t\texitStatusChannel <- exitStatus\n\t\t}()\n\t}\n\n\treturn outputReader, exitStatusChannel, nil\n}\n"
  },
  {
    "path": "nb.go/present_test.go",
    "content": "// revive:disable:error-strings Errors should match existing `nb` formatting.\n\npackage main\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"testing\"\n)\n\n// present\n\nfunc TestPresentWithErrorReturns1(t *testing.T) {\n\tos.Stderr = nil\n\texitCode := present(nil, nil, errors.New(\"Test error.\"))\n\tif exitCode != 1 {\n\t\tt.Errorf(\"present() exitCode = %d; want: %d.\", exitCode, 1)\n\t}\n}\n\nfunc TestPresentWithNoErrorReturns0(t *testing.T) {\n\texitCode := present(nil, nil, nil)\n\tif exitCode != 0 {\n\t\tt.Errorf(\"present() exitCode = %d; want: %d.\", exitCode, 1)\n\t}\n}\n"
  },
  {
    "path": "nb.go/run_sub_cmd_run_test.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t// \"path/filepath\"\n\t\"testing\"\n)\n\nfunc TestRunSubCmdRunPrintsOutput(t *testing.T) {\n\t// TODO: Create temp directories.\n\t// cfg := config{\n\t//   nbDir:          filepath.Join(\"tmp\", \"example-nb-dir\"),\n\t//   nbNotebookPath: filepath.Join(\"tmp\", \"example-nb-dir\", \"home\"),\n\t// }\n\n\tcfg, err := configure()\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() configure() err = %s\",\n\t\t\terr,\n\t\t)\n\t}\n\n\trunCmdResponse, exitStatusChannel, err := runSubCmdRun(\n\t\tsubCmdCall{\n\t\t\targs:        []string{\"echo\", \"example output\"},\n\t\t\tcfg:         cfg,\n\t\t\tenv:         os.Environ(),\n\t\t\tinputReader: nil,\n\t\t\toptions:     map[string]string{\"execType\": \"goroutine\"},\n\t\t},\n\t)\n\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() err = %s; %v\",\n\t\t\terr,\n\t\t\tcfg.nbNotebookPath,\n\t\t)\n\t}\n\n\tvar bytes []byte\n\n\tif runCmdResponse == nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() 'echo example output' response\\ngot:  nil\\nwant: 'example output'\",\n\t\t)\n\t} else {\n\t\tbytes, err = ioutil.ReadAll(runCmdResponse)\n\t}\n\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() ioutil.ReadAll(runCmdResponse) err = %s\",\n\t\t\terr,\n\t\t)\n\t}\n\n\tif len(bytes) == 0 {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() ioutil.ReadAll(runCmdResponse) was empty / blank.\",\n\t\t)\n\t}\n\n\tgot := string(bytes)\n\n\tif got != \"example output\\n\" {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() output = %s; want: %s; len(bytes): %d\",\n\t\t\tgot,\n\t\t\t\"example output\\n\",\n\t\t\tlen(bytes),\n\t\t)\n\t}\n\n\tif exitStatusChannel == nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() 'echo example output' exitStatusChannel = nil; want: not nil\",\n\t\t)\n\t} else {\n\t\texitStatus := <-exitStatusChannel\n\n\t\tif exitStatus != 0 {\n\t\t\tt.Errorf(\n\t\t\t\t\"runSubCmdRun() 'echo example output' exitStatus = %v; want: 0\",\n\t\t\t\texitStatus,\n\t\t\t)\n\t\t}\n\t}\n}\n\nfunc TestRunSubCmdRunRequiresCommand(t *testing.T) {\n\t// cfg := config{\n\t//   nbDir:          filepath.Join(\"tmp\", \"example-nb-dir\"),\n\t//   nbNotebookPath: filepath.Join(\"tmp\", \"example-nb-dir\", \"home\"),\n\t// }\n\n\tcfg, err := configure()\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() configure() err = %s\",\n\t\t\terr,\n\t\t)\n\t}\n\n\trunCmdResponse, exitStatusChannel, err := runSubCmdRun(\n\t\tsubCmdCall{\n\t\t\tcfg:         cfg,\n\t\t\tinputReader: nil,\n\t\t\targs:        []string{},\n\t\t\tenv:         os.Environ(),\n\t\t\t// options:     map[string]string{\"execType\": \"goroutine\"},\n\t\t},\n\t)\n\n\terrMessage := fmt.Sprintf(\"%s\", err)\n\n\tif errMessage != \"Command required.\" {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() (no command) errMessage = %s; want: %s.\",\n\t\t\terrMessage,\n\t\t\t\"Command required.\",\n\t\t)\n\t}\n\n\tif exitStatusChannel != nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() (no command) exitStatusChannel = %v; want: nil\",\n\t\t\texitStatusChannel,\n\t\t)\n\t}\n\n\tif runCmdResponse != nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() (no command) standard output should be nil.\",\n\t\t)\n\t}\n}\n\n// TODO: Test for current notebook directory.\nfunc TestRunSubCmdRunRunsInNbNotebookPath(t *testing.T) {\n\t// TODO: Create temp directories.\n\t// cfg := config{\n\t//   nbDir:          filepath.Join(\"tmp\", \"example-nb-dir\"),\n\t//   nbNotebookPath: filepath.Join(\"tmp\", \"example-nb-dir\", \"home\"),\n\t// }\n\n\tcfg, err := configure()\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() configure() err = %s\",\n\t\t\terr,\n\t\t)\n\t}\n\n\trunCmdResponse, exitStatusChannel, err := runSubCmdRun(\n\t\tsubCmdCall{\n\t\t\tcfg:         cfg,\n\t\t\tinputReader: nil,\n\t\t\targs:        []string{\"pwd\"},\n\t\t\tenv:         os.Environ(),\n\t\t\t// options:     map[string]string{\"execType\": \"goroutine\"},\n\t\t},\n\t)\n\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() err = %s\",\n\t\t\terr,\n\t\t)\n\t}\n\n\tif runCmdResponse == nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() 'pwd' response = nil; want: `pwd`\",\n\t\t)\n\t}\n\n\tbytes, err := ioutil.ReadAll(runCmdResponse)\n\n\tif err != nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() ioutil.ReadAll(runCmdResponse) err = %s\",\n\t\t\terr,\n\t\t)\n\t}\n\n\tif len(bytes) == 0 {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() ioutil.ReadAll(runCmdResponse) was empty / blank.\",\n\t\t)\n\t}\n\n\t// TODO: Requires temp notebook path.\n\t// got := string(bytes)\n\t//\n\t// if got != cfg.nbNotebookPath {\n\t//   t.Errorf(\n\t//     \"runSubCmdRun() output = %s; want: %s; len(bytes): %d\",\n\t//     got,\n\t//     cfg.nbNotebookPath,\n\t//     len(bytes),\n\t//   )\n\t// }\n\n\tif exitStatusChannel == nil {\n\t\tt.Errorf(\n\t\t\t\"runSubCmdRun() 'pwd' exitStatusChannel = nil; want: not nil\",\n\t\t)\n\t} else {\n\t\texitStatus := <-exitStatusChannel\n\n\t\tif exitStatus != 0 {\n\t\t\tt.Errorf(\n\t\t\t\t\"runSubCmdRun() 'pwd' exitStatus = %v; want: 0\",\n\t\t\t\texitStatus,\n\t\t\t)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "nb.go/test/nb-go.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'nb.go' with no arguments exits with status 0 and prints ls output.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NBGO}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"%s\\\\n\" \"${_NBGO}\"\n  printf \"%s\\\\n\" \"${_NB}\"\n  printf \"%s\\\\n\" \"${NB_TEST_BASE_PATH}\"\n  printf \"%s\\\\n\" \"${BATS_TEST_DIRNAME}\"\n  printf \"%s\\\\n\" \"${NB_DIR}\"\n\n  [[ \"${status}\"  -eq 0       ]]\n  [[ \"${output}\"  =~  nb\\ add ]]\n}\n"
  },
  {
    "path": "nb.go/test/test_helper.bash",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# nb.go/test/test_helper.bash\n#\n# Test helper for Bats: Bash Automated Testing System.\n#\n# https://github.com/bats-core/bats-core\n# https://github.com/sstephenson/bats\n###############################################################################\n\nsource \"${BATS_TEST_DIRNAME}/../../test/test_helper.bash\"\n\nsetup() {\n  _setup \"${BATS_TEST_DIRNAME}/../../test\"\n\n  # $_NBGO\n  #\n  # The location of the `nb.go` executable being tested.\n  export _NBGO\n  _NBGO=\"$(which nb.go)\"\n  export _NB=\"${_NBGO}\"\n\n  if [[ -z \"${_NBGO:-}\" ]] || [[ ! -e \"${_NBGO}\" ]]\n  then\n    printf \"nb.go executable not found\\\\n.\" 1>&2\n    return 1\n  fi\n}\n"
  },
  {
    "path": "nb.ksh/README.md",
    "content": "# `nb.ksh`\n\n---\n\n<p align=\"center\">\n  <a href=\"https://github.com/xwmx/nb\">github.com/xwmx/nb</a>\n</p>\n"
  },
  {
    "path": "nb.ksh/nb",
    "content": "#!/usr/bin/env ksh\n\nalias local=\"typeset\"\n\n# no-op placeholder for Bash `shopt`.\nshopt() { :; }\n\nsource \"$(cd \"$(dirname \"${0}\")\"; pwd)/../nb\"\n"
  },
  {
    "path": "nb.ksh/test/nb-ksh.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'nb.ksh' with no arguments exits with status 0 and prints ls output.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB_KSH}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # printf \"%s\\\\n\" \"${_NB_KSH}\"\n  # printf \"%s\\\\n\" \"${_NB}\"\n  # printf \"%s\\\\n\" \"${NB_TEST_BASE_PATH}\"\n  # printf \"%s\\\\n\" \"${BATS_TEST_DIRNAME}\"\n  # printf \"%s\\\\n\" \"${NB_DIR}\"\n\n  [[ \"${status}\"  -eq 0       ]]\n  [[ \"${output}\"  =~  nb\\ add ]]\n}\n"
  },
  {
    "path": "nb.ksh/test/test_helper.bash",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# nb.go/test/test_helper.bash\n#\n# Test helper for Bats: Bash Automated Testing System.\n#\n# https://github.com/bats-core/bats-core\n# https://github.com/sstephenson/bats\n###############################################################################\n\nsource \"${BATS_TEST_DIRNAME}/../../test/test_helper.bash\"\n\nsetup() {\n  _setup \"${BATS_TEST_DIRNAME}/../../test\"\n\n  # $_NB_KSH\n  #\n  # The location of the `nb.ksh` executable being tested.\n  export _NB_KSH\n  _NB_KSH=\"${BATS_TEST_DIRNAME}/../nb\"\n  export _NB=\"${_NB_KSH}\"\n}\n"
  },
  {
    "path": "nb.zsh/README.md",
    "content": "# `nb.zsh`\n\n---\n\n<p align=\"center\">\n  <a href=\"https://github.com/xwmx/nb\">github.com/xwmx/nb</a>\n</p>\n"
  },
  {
    "path": "nb.zsh/nb",
    "content": "#!/usr/bin/env zsh\n\nsetopt BASH_REMATCH\nsetopt KSH_ARRAYS\n\n# no-op placeholder for Bash `shopt`.\nshopt() { :; }\n\nsource \"$(cd \"$(dirname \"${0}\")\"; pwd)/../nb\"\n"
  },
  {
    "path": "nb.zsh/test/nb-zsh.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'nb.ksh' with no arguments exits with status 0 and prints ls output.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB_ZSH}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # printf \"%s\\\\n\" \"${_NB_ZSH}\"\n  # printf \"%s\\\\n\" \"${_NB}\"\n  # printf \"%s\\\\n\" \"${NB_TEST_BASE_PATH}\"\n  # printf \"%s\\\\n\" \"${BATS_TEST_DIRNAME}\"\n  # printf \"%s\\\\n\" \"${NB_DIR}\"\n\n  [[ \"${status}\"  -eq 0       ]]\n  [[ \"${output}\"  =~  nb\\ add ]]\n}\n"
  },
  {
    "path": "nb.zsh/test/test_helper.bash",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# nb.go/test/test_helper.bash\n#\n# Test helper for Bats: Bash Automated Testing System.\n#\n# https://github.com/bats-core/bats-core\n# https://github.com/sstephenson/bats\n###############################################################################\n\nsource \"${BATS_TEST_DIRNAME}/../../test/test_helper.bash\"\n\nsetup() {\n  _setup \"${BATS_TEST_DIRNAME}/../../test\"\n\n  # $_NB_ZSH\n  #\n  # The location of the `nb.zsh` executable being tested.\n  export _NB_ZSH\n  _NB_ZSH=\"${BATS_TEST_DIRNAME}/../nb\"\n  export _NB=\"${_NB_ZSH}\"\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"nb.sh\",\n  \"version\": \"7.25.3\",\n  \"description\": \"CLI and local web note-taking, bookmarking, and archiving with encryption, search, Git-backed versioning and syncing, tagging, and more in a single portable script.\",\n  \"global\": true,\n  \"install\": \"make install\",\n  \"directories\": {\n    \"test\": \"test\"\n  },\n  \"bin\": {\n    \"nb\": \"nb\",\n    \"nb.sh\": \"nb\",\n    \"bookmark\": \"bin/bookmark\"\n  },\n  \"scripts\": {\n    \"test\": \"bats test\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/xwmx/nb.git\"\n  },\n  \"keywords\": [\n    \"notes\",\n    \"bash\",\n    \"shell\",\n    \"productivity\",\n    \"cli\",\n    \"terminal\",\n    \"command-line\",\n    \"prompt\",\n    \"note-taking\",\n    \"vim\",\n    \"emacs\",\n    \"vscode\",\n    \"git\",\n    \"versioning\",\n    \"syncing\",\n    \"sync\",\n    \"encryption\",\n    \"pandoc\",\n    \"bookmarks\",\n    \"bookmarking\",\n    \"tagging\",\n    \"tags\",\n    \"archive\"\n  ],\n  \"author\": \"William Melody\",\n  \"license\": \"AGPL-3.0-or-later\",\n  \"bugs\": {\n    \"url\": \"https://github.com/xwmx/nb/issues\"\n  },\n  \"homepage\": \"https://github.com/xwmx/nb#readme\"\n}\n"
  },
  {
    "path": "package.sh",
    "content": "###############################################################################\n# package.sh\n#\n# Configuration for basher, a package manager for shell scripts.\n#\n# https://github.com/basherpm/basher\n###############################################################################\n\nexport BINS=nb\nexport BASH_COMPLETIONS=etc/nb-completion.bash\nexport ZSH_COMPLETIONS=etc/nb-completion.zsh\n"
  },
  {
    "path": "plugins/annotate.dev.nb-plugin",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# annotate.dev.nb-plugin\n#\n# An annotate plugin for `nb`.\n#\n# Install with:\n#   nb plugin install https://github.com/xwmx/nb/blob/master/plugins/annotate.dev.nb-plugin\n#\n# https://github.com/xwmx/nb\n###############################################################################\n\n# Add the new subcommand name with `_subcommands add <name>`.\n_subcommands add \"annotate\"\n_subcommands add \"annotations\"\n\n# Define help and usage text with `_subcommands describe <subcommand> <usage>`.\n_subcommands describe \"annotate\" <<HEREDOC\n$(_color_primary \"Usage\"):\n  nb annotate ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb annotate delete ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n  nb annotate show ([<notebook>:][<folder-path>/][<id> | <filename> | <title>])\n\n$(_color_primary \"Subcommands\"):\n  (default) Add or edit annotations for an item.\n  delete    Delete annotations for an item.\n  show      Show annotations for an item.\n\n$(_color_primary \"Description\"):\n  Add, edit, show, or delete annotations for an item.\nHEREDOC\n\n# Define the subcommand as a function, named with a leading underscore.\n_annotate() {\n  local _selector=\n  local _subcommand=\"edit\"\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg:-}\" in\n      '')\n        :\n        ;;\n      add|edit)\n        _subcommand=\"edit\"\n        ;;\n      delete)\n        _subcommand=\"delete\"\n        ;;\n      show)\n        _subcommand=\"show\"\n        ;;\n      *)\n        _selector=\"${__arg}\"\n        ;;\n    esac\n  done\n\n  local _selector_path=\n  _selector_path=\"$(_show \"${_selector:-}\" --path 2>/dev/null || :)\"\n\n  local _selector_info_line=\n  _selector_info_line=\"$(_show \"${_selector:-}\" --info-line 2>/dev/null || :)\"\n\n  local _annotations_basename=\n  _annotations_basename=\".$(basename \".${_selector_path:-}\").annotations.md\"\n\n  local _annotations_directory_path=\n  _annotations_directory_path=\"$(dirname \"${_selector_path}\")\"\n\n  local _annotations_path=\"${_annotations_directory_path}/${_annotations_basename}\"\n\n  if [[ ! -e \"${TMPDIR}/nb-annotate-dev-plugin-enabled\" ]]\n  then\n    cat <<HEREDOC\nThis plugin is experimental and the implementation could change without notice.\nHEREDOC\n\n    while true\n    do\n      local __yn=\n      IFS='' read -r -e -d $'\\n' -p \\\n\"$(_color_primary \"Proceed?\") $(_color_brackets \"y/N\") \" __yn\n\n      case \"${__yn}\" in\n        [Yy]*)\n          touch \"${TMPDIR}/nb-annotate-dev-plugin-enabled\"\n\n          break\n          ;;\n        *)\n          printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n\n          exit 0\n          ;;\n      esac\n    done\n  fi\n\n  case \"${_subcommand:-}\" in\n    edit)\n      if [[ ! -e \"${_annotations_path:-}\"     ]]\n      then\n        _add                                  \\\n          --edit                              \\\n          --filename \"${_annotations_path:-}\" \\\n          --no-template                       \\\n          --quiet                             &&\n          printf \"Annotated: %s\\\\n\" \"${_selector_info_line}\"\n      else\n        _edit \"${_annotations_path:-}\"        \\\n          --quiet                             &&\n          printf \"Annotated: %s\\\\n\" \"${_selector_info_line}\"\n      fi\n      ;;\n    delete)\n      if [[ -e \"${_annotations_path:-}\"       ]]\n      then\n        _delete \"${_annotations_path:-}\"      \\\n          --quiet                             &&\n          printf \"Annotations deleted: %s\\\\n\" \"${_selector_info_line}\"\n      else\n        _warn printf \"No annotations found: %s\\\\n\" \\\n          \"$(_color_primary \"${_selector:-}\")\"\n\n        return 1\n      fi\n      ;;\n    show)\n      if [[ -e \"${_annotations_path:-}\" ]]\n      then\n        _show \"${_annotations_path:-}\"\n      else\n        _warn printf \"No annotations found: %s\\\\n\" \\\n          \"$(_color_primary \"${_selector:-}\")\"\n\n        return 1\n      fi\n      ;;\n  esac\n}\n_alias_subcommand \"annotate\" \"annotations\"\n"
  },
  {
    "path": "plugins/backlink.nb-plugin",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# backlink.nb-plugin\n#\n# Add backlinks to notes.\n#\n# Depends on note-link-janitor:\n#   https://github.com/andymatuschak/note-link-janitor\n#\n# Install with:\n#   nb plugin install https://github.com/xwmx/nb/blob/master/plugins/backlink.nb-plugin\n#\n# https://github.com/xwmx/nb\n###############################################################################\n\n# Add the new subcommand name with `_subcommands add <name>`.\n_subcommands add \"backlink\"\n\n# Define help and usage text with `_subcommands describe <subcommand> <usage>`.\n_subcommands describe \"backlink\" <<HEREDOC\nUsage:\n  nb backlink [--force]\n\nDescription:\n  Add backlinks to notes. Crawl notes in a notebook for [[wiki-style links]]\n  and append a \"Backlinks\" section to each linked file that lists passages\n  referencing the note.\n\n  To link to a note from within another note, surround the title of the\n  target note in double square brackets:\n\n      Example with link to [[Target Note Title]] in content.\n\n  Depends on note-link-janitor:\n    https://github.com/andymatuschak/note-link-janitor\n\n    Requirement: every note in the notebook must have a title.\nHEREDOC\n\n# Define the subcommand as a function, named with a leading underscore.\n_backlink() {\n  if ! hash \"note-link-janitor\" 2>/dev/null\n  then\n    printf \"\\\nnote-link-janitor required:\n  https://github.com/andymatuschak/note-link-janitor\\\\n\" 1>&2\n    exit 1\n  fi\n\n  if ! [[ \"${1:-}\" == \"--force\" ]]\n  then\n    printf \"Adding backlinks to notes. This could update multiple files.\\\\n\"\n\n    while true\n    do\n      local __yn=\n      IFS='' read -r -e -d $'\\n' -p \"Proceed? [y/N] \" __yn\n      case ${__yn} in\n        [Yy]*)\n          break\n          ;;\n        *)\n          printf \"Exiting...\\\\n\"\n          exit 0\n          ;;\n      esac\n    done\n  fi\n\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  note-link-janitor \"${_notebook_path}\"\n\n  if [[ -n \"$(_git status --porcelain)\" ]]\n  then\n    _git checkpoint \"[nb] Backlinked\"\n    printf \"Backlinked!\\\\n\"\n  else\n    printf \"No new links found.\\\\n\"\n  fi\n}\n"
  },
  {
    "path": "plugins/bump.nb-plugin",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# bump.nb-plugin\n#\n# Bump an item to the top of the list.\n#\n# Install with:\n#   nb plugin install https://github.com/xwmx/nb/blob/master/plugins/bump.nb-plugin\n#\n# A plugin for `nb`.\n#   https://github.com/xwmx/nb\n###############################################################################\n\n# Add the new subcommand name with `_subcommands add <name>`.\n_subcommands add \"bump\"\n_subcommands add \"touch\"\n\n# Define help and usage text with `_subcommands describe <subcommand> <usage>`.\n_subcommands describe \"bump\" <<HEREDOC\nUsage:\n  nb bump [<notebook>:][<folder-path>/][<id>][<filename>][<title>]\n\nDescription:\n  Bump an item to the top of the list.\n\n  \\`bump\\` updates the item's modification timestamp without editing the item\n  or creating a new commit.\n\nExamples:\n  nb bump 123\n  nb bump example:sample/456\n\nAlias:\n  nb touch\nHEREDOC\n\n# Define the subcommand as a function, named with a leading underscore.\n_bump() {\n  local _selector=\"${1:-}\"\n\n  local _target_path=\n  _target_path=\"$(_show \"${_selector}\" --path)\"\n\n  if [[ ! -e \"${_target_path:-}\"  ]]\n  then\n    _help \"bump\"\n\n    return 1\n  fi\n\n  touch \"${_target_path}\"\n\n  _wrap off\n\n  printf \"%s to top%s %s\"         \\\n    \"$(_color_primary \"Bumped\")\"  \\\n    \"$(_color_muted   \":\")\"       \\\n    \"$(_show \"${_selector}\" --info-line)\"\n\n  _wrap on\n\n  printf \"\\\\n\"\n}\n\n_alias_subcommand \"bump\" \"touch\"\n"
  },
  {
    "path": "plugins/clip.nb-plugin",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# clip\n#\n# A plugin for `nb` providing clipboard functionality.\n#\n# Author: hyb (https://github.com/ohyhyb)\n###############################################################################\n\n# Add the new subcommand names with `_subcommands add <name>`.\n_subcommands add \"clip\"\n\n# Define help and usage text with `_subcommands describe <subcommand> <usage>`.\n_subcommands describe \"clip\" <<HEREDOC\nUsage:\n  nb clip [<notebook>:][<id> | <filename> | <path> | <title> | <extension>]\n\nDescription:\n  Save the clipboard contents and copy contents of text or markdown items to\n  the clipboard.\n\n  When called with no arguments or when no matching file is found, the text\n  content on the clipboard is saved to a new file, pending a prompt.\n\nExamples:\n  # copy the content of item 123 to the clipboard\n  nb clip 123\n\n  # save the clipboard contents to a new file with a \\`.js\\` file extension\n  nb clip .js\n\n  # save the clipboard contents as a new \\`.cr\\` file in the \"snippets\" notebook\n  nb snippets:clip .cr\nHEREDOC\n\n# Define the subcommand as a function, named with a leading underscore.\n_clip() {\n  local _force=0\n  local _selector=\n\n  local __arg=\n  for   __arg in \"${@:-}\"\n  do\n    case \"${__arg:-}\" in\n      '')       :                     ;;\n      --force)  _force=1              ;;\n      *)        _selector=\"${__arg}\"  ;;\n    esac\n  done\n\n  local _source_relative_path=\n\n  if [[ -n \"${_selector:-}\" ]]\n  then\n    _source_relative_path=\"$(\n      _show \"${_selector:-}\" --relative-path 2>/dev/null || :\n    )\"\n  fi\n\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  if _command_exists \"_color_dim\" && ! _command_exists \"_color_muted\"\n  then\n    _color_muted() { _color_dim \"${@:-}\"; }\n  fi\n\n  if [[   -z  \"${_source_relative_path:-}\"                    ]] ||\n     [[ ! -e  \"${_notebook_path}/${_source_relative_path}\"    ]]\n  then\n    printf \"Saving clipboard contents%s\\\\n\" \"$(_color_muted \"...\")\"\n\n    if ! ((_force))\n    then\n      while true\n      do\n        local __yn=\n        IFS='' read -r -e -d $'\\n' -p \"\\\n$(_color_primary \"Proceed?\")  $(_color_brackets \"y/N\") \" __yn\n\n        case ${__yn} in\n          [Yy]*)\n            break\n            ;;\n          *)\n            printf \"Exiting%s\\\\n\" \"$(_color_muted \"...\")\"\n            exit 0\n            ;;\n        esac\n      done\n    fi\n\n    {\n      if _command_exists \"xclip\" && [[ ! \"${OSTYPE}\" =~ ^darwin ]]\n      then\n        xclip -o\n      elif _command_exists \"pbpaste\"\n      then\n        pbpaste\n      fi\n    } | {\n      _add \"${_selector}\"\n    }\n\n    return 0\n  elif [[ ! -f \"${_notebook_path}/${_source_relative_path}\"   ]]\n  then\n    printf \"Not a file: %s\\\\n\" \"${_selector}\"\n    exit 1\n  fi\n\n  if _show \"${_source_relative_path}\" --type text ||\n     _show \"${_source_relative_path}\" --type md\n  then\n    if _command_exists \"xclip\" && [[ ! \"${OSTYPE}\" =~ ^darwin ]]\n    then\n      cat \"${_notebook_path}/${_source_relative_path}\" | xclip -sel clip\n    elif _command_exists \"pbcopy\"\n    then\n      cat \"${_notebook_path}/${_source_relative_path}\" | pbcopy\n    fi && printf \"Copied $(_color_primary \"${_source_relative_path}\") contents to clipboard.%s\\\\n\"\n  else\n    _exit_1 printf \"Not a text or markdown file.%s\\\\n\"\n  fi\n}\n"
  },
  {
    "path": "plugins/daily.nb-plugin",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# daily.nb-plugin\n#\n# Write to a daily log.\n#\n# Install with:\n#   nb plugin install https://github.com/xwmx/nb/blob/master/plugins/daily.nb-plugin\n#\n# A plugin for `nb`.\n#   https://github.com/xwmx/nb\n###############################################################################\n\n# Add the new subcommand name with `_subcommands add <name>`.\n_subcommands add \"daily\"\n\n# Define help and usage text with `_subcommands describe <subcommand> <usage>`.\n_subcommands describe \"daily\" <<HEREDOC\n$(_color_primary \"Usage\"):\n  ${_ME} daily [<content>] [--prev [<number>]]\n\n$(_color_primary \"Options\"):\n  --prev [<number>]   List previous days and show day by previous <number>.\n\n$(_color_primary \"Description\"):\n  Add notes to a daily log. When called without arguments, the current day's\n  log is displayed. When passed \\`<content>\\`, a new timestamped entry is added\n  to the current day's log, which is created if it doesn't yet exist.\n\n  Previous day's logs can be listed with the \\`--prev\\` option. View a previous\n  day's log by passing its \\`<number>\\` in the list.\n\n$(_color_primary \"Examples\"):\n  ${_ME} daily \"Example note content.\"\n  ${_ME} daily\n  ${_ME} daily --prev\n  ${_ME} daily --prev 3\nHEREDOC\n\n# Define the subcommand as a function, named with a leading underscore.\n_daily() {\n  # Usage: _daily_show <path>\n  _daily_show() {\n    local _info_line=\n    local _target_path=\"${1:-}\"\n\n    [[ -n \"${_target_path:-}\" ]] || return 1\n\n    _info_line=\"$(_show \"${_target_path:-}\" --info-line)\"\n\n    if [[ \"${_info_line}\" =~ Daily ]]\n    then\n      _info_line=\"${_info_line%% \\\"Daily*}\"\n    else\n      _info_line=\"${_info_line%% \\\" · \\\"*}\"\n    fi\n\n    printf \"%s\\\\n\" \"${_info_line}:\"\n\n    _show \"${_target_path:-}\" --print\n\n    return 0\n  }\n\n  local _content=(\"${@:-}\")\n\n  local _notebook_path=\n  _notebook_path=\"$(_notebooks current --path)\"\n\n  local _target_filename=\n  _target_filename=\"$(date \"+%Y%m%d\").md\"\n\n  local _target_path=\n  _target_path=\"${_notebook_path}/${_target_filename}\"\n\n  if [[ -z \"${_content[*]:-}\"       ]]\n  then\n    if [[ ! -e \"${_target_path:-}\"  ]]\n    then\n      printf \"Add the first note of the day: %s daily <content>\\\\n\" \"${_ME}\"\n\n      return 0\n    else\n      _daily_show \"${_target_path:-}\"\n    fi\n  elif _contains \"${_content[0]:-}\" \\\n    \"--all\" \"--ago\" \"--day\" \"--days\" \"--prev\" \"--previous\"\n  then\n    local _daily_note_paths=()\n\n    _daily_note_paths=($(\n      find \"${_notebook_path:-}\"                                  \\\n        -maxdepth 1                                               \\\n        -type     f                                               \\\n        -name     \"[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].md\"   \\\n        | sort                                                    \\\n        | sed '1!G;h;$!d' # https://stackoverflow.com/a/744093\n    ))\n\n    if ! ((${#_daily_note_paths[@]}))\n    then\n      printf \"Add the first daily note: %s daily <content>\\\\n\" \"${_ME}\"\n\n      return 0\n    fi\n\n    if [[ \"${2:-}\" =~ ^[0-9]+$ ]]\n    then\n      local _note_number=\"${2:-0}\"\n\n      if [[ \"${_note_number:-}\" -ge \"${#_daily_note_paths[@]}\" ]]\n      then\n        _exit_1 printf \"Not found.\\\\n\"\n      fi\n\n      _target_path=\"${_daily_note_paths[${_note_number}]}\"\n\n      _daily_show \"${_target_path:-}\"\n    else\n      {\n        printf \"%s\\\\n\" \"${_daily_note_paths[@]:-}\"\n      } | {\n        local _counter=0\n\n        local               __line=\n        while IFS= read -r  __line || [[ -n \"${__line:-}\" ]]\n        do\n          {\n            _list \"${__line}\" --no-color\n          } | {\n            printf \"%s %s\\\\n\"                       \\\n              \"$(_color_brackets \"${_counter:-0}\")\" \\\n              \"$(cat)\"\n          }\n\n          _counter=$((_counter + 1))\n        done\n      }\n    fi\n  else\n    local _timestamp=\n    _timestamp=\"$(date \"${NB_DAILY_TIMESTAMP_FORMAT:-\"+%H:%M:%S\"}\")\"\n\n    local _datestamp=\n    _datestamp=\"$(date \"${NB_DAILY_DATESTAMP_FORMAT:-\"+%Y-%m-%d\"}\")\"\n\n    local _formatted_content=\n    _formatted_content=\"$(_join \" \" \"${_content[@]}\")\"\n\n    local _timestamped_content=\"\\\n## ${_timestamp}\n\n${_formatted_content}\"\n\n    if [[ ! -e \"${_target_path:-}\"  ]]\n    then\n      _add                                  \\\n        --content \"${_timestamped_content}\" \\\n        --filename \"${_target_filename}\"    \\\n        --title     \"Daily ${_datestamp:-}\"\n    else\n      _edit \"${_target_filename}\" --append \"${_NEWLINE}${_timestamped_content}\"\n    fi\n  fi\n}\n"
  },
  {
    "path": "plugins/ebook.nb-plugin",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# ebook.nb-plugin\n#\n# Ebook authoring with `nb`.\n#\n# Based on:\n#   https://pandoc.org/epub.html\n#\n# Install with:\n#   nb plugin install https://github.com/xwmx/nb/blob/master/plugins/ebook.nb-plugin\n#\n# https://github.com/xwmx/nb\n###############################################################################\n\n# Add the new subcommand name with `_subcommands add <name>`.\n_subcommands add \"ebook\"\n\n# Define help and usage text with `_subcommands describe <subcommand> <usage>`.\n_subcommands describe \"ebook\" <<HEREDOC\nUsage:\n  nb ebook init [<name>] [--force]\n  nb ebook publish\n\nSubcommands:\n  ebook init     Initialize the current notebook or notebook <name> with\n                 placeholder files for authoring an ebook, creating the\n                 notebook if it does not yet exist.\n  ebook publish  Generate a .epub file using the current notebook contents.\n\nDescription:\n  Ebook authoring with \\`nb\\`.\n\n  \\`nb ebook init\\` populates an existing or new notebook with initial\n  placeholder files for creating an ebook. Edit the title page and\n  chapters using normal \\`nb\\` commands, then use \\`nb ebook publish\\`\n  to generate an epub file.\n\n  Chapters are expected to be markdown files with sequential numeric\n  filename prefixes for ordering:\n\n    01-example.md\n    02-sample.md\n    03-demo.md\n\n  Create new chapters with \\`nb add\\`:\n\n    nb add --filename \"04-chapter4.md\"\n\n  title.txt contains the book metadata in a YAML block. For more information\n  about the fields for this file, visit:\n\n    https://pandoc.org/MANUAL.html#epub-metadata\n\n  stylesheet.css contains base styling for the generated ebook. It can be used\n  as it is and can also be edited using \\`nb edit\\`.\n\n  As with all \\`nb\\` notebooks, changes are recorded automatically in git,\n  providing automatic version control for all ebook content, source, and\n  metadata files.\n\n  Generated epub files are saved in the notebook and can be previewed in the\n  terminal with \\`nb show\\`. Export a generated epub file with \\`nb export\\`:\n\n    nb export 12 .\n\nMore info:\n  https://pandoc.org/epub.html\nHEREDOC\n\n__get_sub_files() {\n  local _chapter_filenames=($(_list_files \"${_folder_path}\"))\n  local _files=()\n  local _folder_path=\"${1:-}\"\n\n  local __filename=\n  for   __filename in \"${_chapter_filenames[@]:-}\"\n  do\n    if [[ -d \"${_folder_path}/${__filename}\" ]]\n    then\n      _files+=($(\n        __get_sub_files \"${_folder_path}/${__filename}\"\n      ))\n    else\n      _files+=(\"${_folder_path}/${__filename}\")\n    fi\n  done\n\n  printf \"%s\\\\n\" \"${_files[@]:-}\"\n}\n\n# Define the subcommand as a function, named with a leading underscore.\n_ebook() {\n  local _force=0\n  local _name=\n  local _notebook_path=\n  local _prompt=0\n  local _subcommand=\n\n  local __arg=\n  for   __arg in \"${@}\"\n  do\n    case \"${__arg}\" in\n      --force)\n        _force=1\n        ;;\n      *)\n        if [[ -z \"${_subcommand:-}\" ]]\n        then\n          _subcommand=\"${__arg}\"\n        else\n          _name=\"${__arg}\"\n        fi\n        ;;\n    esac\n  done\n\n\n  [[ -z \"${_subcommand:-}\" ]] && _help \"ebook\" 1>&2 && exit 1\n\n  case \"${_subcommand:-}\" in\n    a|add|c|create|init|n|new)\n\n      if [[ -z \"${_name:-}\" ]]\n      then\n        _prompt=1\n        cat <<HEREDOC\nAdding the following files to the current notebook:\n  title.txt\n  stylesheet.css\n  01-chapter1.md\nHEREDOC\n\n        _notebook_path=\"$(_notebooks current --path)\"\n      elif _notebook_path=\"$(_notebooks show \"${_name}\" --path 2>/dev/null)\"\n      then\n        _prompt=1\n        cat <<HEREDOC\nAdding the following files to ${_name}:\n  title.txt\n  stylesheet.css\n  01-chapter1.md\nHEREDOC\n      fi\n\n      if ((_prompt)) && ! ((_force))\n      then\n        while true\n        do\n          local __yn=\n          IFS='' read -r -e -d $'\\n' -p \"Proceed?  [y/N] \" __yn\n          case ${__yn} in\n            [Yy]*)\n              break\n              ;;\n            *)\n              printf \"Exiting...\\\\n\"\n              exit 0\n              ;;\n          esac\n        done\n      fi\n\n      if [[ -n \"${_name:-}\" ]] && [[ -z \"${_notebook_path:-}\" ]]\n      then\n        _notebooks add \"${_name}\"\n        _notebook_path=\"$(_notebooks show \"${_name}\" --path)\"\n      fi\n\n      cat <<HEREDOC | NB_NOTEBOOK_PATH=\"${_notebook_path}\" _add \"title.txt\"       &&\n---\ntitle: Placeholder Title\nauthor: Placeholder Name\nrights:  Creative Commons Non-Commercial Share Alike 3.0\nlanguage: en-US\n---\nHEREDOC\n      cat <<HEREDOC | NB_NOTEBOOK_PATH=\"${_notebook_path}\" _add \"stylesheet.css\"  &&\n/* This defines styles and classes used in the book */\nbody { margin: 5%; text-align: justify; font-size: medium; }\ncode { font-family: monospace; }\nh1 { text-align: left; }\nh2 { text-align: left; }\nh3 { text-align: left; }\nh4 { text-align: left; }\nh5 { text-align: left; }\nh6 { text-align: left; }\n/* For title, author, and date on the cover page */\nh1.title { }\np.author { }\np.date { }\nnav#toc ol,\nnav#landmarks ol { padding: 0; margin-left: 1em; }\nnav#toc ol li,\nnav#landmarks ol li { list-style-type: none; margin: 0; padding: 0; }\na.footnote-ref { vertical-align: super; }\nem, em em em, em em em em em { font-style: italic;}\nem em, em em em em { font-style: normal; }\ncode{ white-space: pre-wrap; }\nspan.smallcaps{ font-variant: small-caps; }\nspan.underline{ text-decoration: underline; }\nq { quotes: \"“\" \"”\" \"‘\" \"’\"; }\ndiv.column{ display: inline-block; vertical-align: top; width: 50%; }\ndiv.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}\n@media screen { /* Workaround for iBooks issue; see #6242 */\n  .sourceCode {\n    overflow: visible !important;\n    white-space: pre-wrap !important;\n  }\n}\nHEREDOC\n      NB_NOTEBOOK_PATH=\"${_notebook_path}\" _add \\\n        \"01-chapter1.md\" --content \"# Chapter One\" &&\n          printf \"Ebook initialized: %s\\\\n\" \"$(basename \"${_notebook_path}\")\"\n      ;;\n    p|publish|g|generate|b|build)\n      if ! hash pandoc 2>/dev/null\n      then\n        printf \"Install Pandoc to generate an ebook: https://pandoc.org/\\\\n\" 1>&2\n        exit 1\n      fi\n\n      local _pandoc_arguments=()\n\n      local _notebook_path=\n      _notebook_path=\"$(_notebooks current --path)\"\n\n      local _notebook_name=\n      _notebook_name=\"$(_notebooks current --name)\"\n\n      local _stylesheet_path=\"${_notebook_path}/stylesheet.css\"\n\n      if [[ -f \"${_stylesheet:-}\" ]]\n      then\n        _pandoc_arguments+=(\"--css\" \"${_stylesheet_path}\")\n      fi\n\n      local _title_page_path=\"${_notebook_path}/title.txt\"\n\n      if [[ -f \"${_title_page_path}\" ]]\n      then\n        _pandoc_arguments+=(\"${_title_page_path}\")\n      else\n        printf \"title.txt required.\\\\n\"\n        exit 1\n      fi\n\n      local _chapter_filenames=($(\n        _list '^[0-9]{1,}-' --sort --filenames --no-id --no-indicator | sort -n\n      ))\n\n      if [[ -z \"${_chapter_filenames[*]:-}\" ]]\n      then\n        printf \"No chapters found.\\\\n\" 1>&2\n        exit 1\n      fi\n\n      local __filename=\n      for   __filename in \"${_chapter_filenames[@]:-}\"\n      do\n        if [[ -d \"${_notebook_path}/${__filename}\" ]]\n        then\n          _pandoc_arguments+=($(\n            __get_sub_files \"${_notebook_path}/${__filename}\"\n          ))\n        else\n          _pandoc_arguments+=(\"${_notebook_path}/${__filename}\")\n        fi\n      done\n\n      local _output_filename=\n      _output_filename=\"$(\n        _notebooks current --filename \"${_notebook_name}.epub\"\n      )\"\n\n      local _output_path=\"${_notebook_path}/${_output_filename}\"\n\n      pandoc -o \"${_output_path}\" \"${_pandoc_arguments[@]}\"       &&\n        _index add \"${_output_filename}\"                          &&\n          _git checkpoint \"[nb] Added: %s\" \"${_output_filename}\"  &&\n            printf \"Added: %s\\\\n\" \"$(_show \"${_output_filename}\" --info-line)\"\n      ;;\n    *)\n      _help \"ebook\" 1>&2 && exit 1\n      ;;\n  esac\n}\n"
  },
  {
    "path": "plugins/example.nb-plugin",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# example.nb-plugin\n#\n# An example plugin for `nb`.\n#\n# Install with:\n#   nb plugin install https://github.com/xwmx/nb/blob/master/plugins/example.nb-plugin\n#\n# https://github.com/xwmx/nb\n###############################################################################\n\n# Add the new subcommand name with `_subcommands add <name>`.\n_subcommands add \"example\"\n\n# Define help and usage text with `_subcommands describe <subcommand> <usage>`.\n_subcommands describe \"example\" <<HEREDOC\nUsage:\n  nb example\n\nDescription:\n  Print \"Hello, World!\"\nHEREDOC\n\n# Define the subcommand as a function, named with a leading underscore.\n_example() {\n  printf \"Hello, World!\\\\n\"\n}\n"
  },
  {
    "path": "plugins/turquoise.nb-theme",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# turquoise.nb-theme\n#\n# A blue and green theme for `nb`.\n#\n# Install with:\n#   nb plugin install https://github.com/xwmx/nb/blob/master/plugins/turquoise.nb-theme\n#\n# https://github.com/xwmx/nb\n###############################################################################\n\nif [[ \"${NB_COLOR_THEME}\" == \"turquoise\" ]]\nthen\n  export NB_COLOR_PRIMARY=43\n  export NB_COLOR_SECONDARY=38\nfi\n"
  },
  {
    "path": "plugins/weather.nb-plugin",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# weather.nb-plugin\n#\n# Display weather information from wttr.in.\n#\n# Install with:\n#   nb plugin install https://github.com/xwmx/nb/blob/master/plugins/weather.nb-plugin\n#\n# https://github.com/xwmx/nb\n###############################################################################\n\n_subcommands add \"weather\"\n_subcommands add \"w\"\n_subcommands add \"wttr\"\n\n_subcommands describe \"weather\" <<HEREDOC\nUsage:\n  nb weather [<option>...]\n\nDescription:\n  Display weather information from wttr.in.\n\nMore Info:\n  https://github.com/chubin/wttr.in\n  https://wttr.in\n\nExamples:\n  nb weather\n  nb weather Tokyo\n  nb weather lax\n\nShortcut Alias:\n  nb w\nHEREDOC\n\n_weather() {\n  curl \"https://wttr.in/$(_join \"+\" \"${@:-}\")\"\n}\n\n_alias_subcommand \"weather\" \"w\"\n_alias_subcommand \"weather\" \"wttr\"\n"
  },
  {
    "path": "test/add-template.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031,SC2063\n\nload test_helper\n\n# --no-template ###############################################################\n\n@test \"'add --template \\\"\\\"' with path NB_DEFAULT_TEMPLATE assigned in .nbrc and blank <template> creates note without template.\" {\n  {\n    \"${_NB}\" init\n\n    declare _template_path=\"${_TMP_DIR}/example-template\"\n\n    cat <<HEREDOC > \"${_template_path}\"\n{{title_prefix}} - Example Template Title - {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n\\$(printf \"Example command substitution output.\")\n\n## Full Content\n\n{{content}}\n\n## Selector Content\n\n{{selector_content}}\n\n## Option Content\n\n{{option_content}}\n\n## Piped Content\n\n{{piped_content}}\n\n## Tag List\n\n{{tags}}\nHEREDOC\n\n    printf \"export NB_DEFAULT_TEMPLATE=\\\"%s\\\"\\\\n\" \"${_template_path}\" >> \"${NBRC_PATH}\"\n  }\n\n  run \"${_NB}\" add                      \\\n    \"Argument content one.\"             \\\n    --content \"Example option content.\" \\\n    --tags    one,two,three             \\\n    --title   \"Example Title\"           \\\n    --template \"\"                       \\\n    \"Argument content two.\" <<< \"Example piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  printf \"File content: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/example_title.md\")\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\n#one #two #three\n\nArgument content one. Argument content two.\n\nExample option content.\n\nExample piped content.\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add --template \\\"\\\"' with blank <template> creates note without template.\" {\n  {\n    \"${_NB}\" init\n\n    declare _template_path=\"${_TMP_DIR}/example-template\"\n\n    cat <<HEREDOC > \"${_template_path}\"\n{{title_prefix}} - Example Template Title - {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n\\$(printf \"Example command substitution output.\")\n\n## Full Content\n\n{{content}}\n\n## Selector Content\n\n{{selector_content}}\n\n## Option Content\n\n{{option_content}}\n\n## Piped Content\n\n{{piped_content}}\n\n## Tag List\n\n{{tags}}\nHEREDOC\n  }\n\n  run \"${_NB}\" add                      \\\n    \"Argument content one.\"             \\\n    --content \"Example option content.\" \\\n    --tags    one,two,three             \\\n    --title   \"Example Title\"           \\\n    --template \"\"                       \\\n    \"Argument content two.\" <<< \"Example piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  printf \"File content: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/example_title.md\")\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\n#one #two #three\n\nArgument content one. Argument content two.\n\nExample option content.\n\nExample piped content.\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add --template <template> --no-template' with path <template> creates note without template.\" {\n  {\n    \"${_NB}\" init\n\n    declare _template_path=\"${_TMP_DIR}/example-template\"\n\n    cat <<HEREDOC > \"${_template_path}\"\n{{title_prefix}} - Example Template Title - {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n\\$(printf \"Example command substitution output.\")\n\n## Full Content\n\n{{content}}\n\n## Selector Content\n\n{{selector_content}}\n\n## Option Content\n\n{{option_content}}\n\n## Piped Content\n\n{{piped_content}}\n\n## Tag List\n\n{{tags}}\nHEREDOC\n  }\n\n  run \"${_NB}\" add                      \\\n    \"Argument content one.\"             \\\n    --content \"Example option content.\" \\\n    --tags    one,two,three             \\\n    --title   \"Example Title\"           \\\n    \"Argument content two.\"             \\\n    --template \"${_template_path}\"      \\\n    --no-template <<< \"Example piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  printf \"File content: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/example_title.md\")\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\n#one #two #three\n\nArgument content one. Argument content two.\n\nExample option content.\n\nExample piped content.\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add --no-template' with path NB_DEFAULT_TEMPLATE assigned in .nbrc creates note without template.\" {\n  {\n    \"${_NB}\" init\n\n    declare _template_path=\"${_TMP_DIR}/example-template\"\n\n    cat <<HEREDOC > \"${_template_path}\"\n{{title_prefix}} - Example Template Title - {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n\\$(printf \"Example command substitution output.\")\n\n## Full Content\n\n{{content}}\n\n## Selector Content\n\n{{selector_content}}\n\n## Option Content\n\n{{option_content}}\n\n## Piped Content\n\n{{piped_content}}\n\n## Tag List\n\n{{tags}}\nHEREDOC\n\n    printf \"export NB_DEFAULT_TEMPLATE=\\\"%s\\\"\\\\n\" \"${_template_path}\" >> \"${NBRC_PATH}\"\n  }\n\n  run \"${_NB}\" add                      \\\n    \"Argument content one.\"             \\\n    --content \"Example option content.\" \\\n    --tags    one,two,three             \\\n    --title   \"Example Title\"           \\\n    \"Argument content two.\"             \\\n    --no-template <<< \"Example piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  printf \"File content: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/example_title.md\")\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\n#one #two #three\n\nArgument content one. Argument content two.\n\nExample option content.\n\nExample piped content.\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# NB_DEFAULT_TEMPLATE #########################################################\n\n@test \"'add' with string NB_DEFAULT_TEMPLATE assigned in .nbrc creates note based on template.\" {\n  {\n    \"${_NB}\" init\n\n    declare _template_path=\"${_TMP_DIR}/example-template\"\n\n    cat <<HEREDOC > \"${NBRC_PATH}\"\nexport NB_DEFAULT_TEMPLATE=\"\\\n{{title_prefix}} - Example Template Title - {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n\\$(printf \"Example command substitution output.\")\n\n## Full Content\n\n{{content}}\n\n## Selector Content\n\n{{selector_content}}\n\n## Option Content\n\n{{option_content}}\n\n## Piped Content\n\n{{piped_content}}\n\n## Tag List\n\n{{tags}}\"\nHEREDOC\n  }\n\n  run \"${_NB}\" add                      \\\n    \"Argument content one.\"             \\\n    --content \"Example option content.\" \\\n    --tags    one,two,three             \\\n    --title   \"Example Title\"           \\\n    \"Argument content two.\" <<< \"Example piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  printf \"File content: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/example_title.md\")\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# - Example Template Title - Example Title\n\n$(date +\"%Y-%m-%d\")\n\nExample command substitution output.\n\n## Full Content\n\nArgument content one. Argument content two.\n\nExample option content.\n\nExample piped content.\n\n## Selector Content\n\nArgument content one. Argument content two.\n\n## Option Content\n\nExample option content.\n\n## Piped Content\n\nExample piped content.\n\n## Tag List\n\n#one #two #three\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with path NB_DEFAULT_TEMPLATE assigned in .nbrc creates note based on template.\" {\n  {\n    \"${_NB}\" init\n\n    declare _template_path=\"${_TMP_DIR}/example-template\"\n\n    cat <<HEREDOC > \"${_template_path}\"\n{{title_prefix}} - Example Template Title - {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n\\$(printf \"Example command substitution output.\")\n\n## Full Content\n\n{{content}}\n\n## Selector Content\n\n{{selector_content}}\n\n## Option Content\n\n{{option_content}}\n\n## Piped Content\n\n{{piped_content}}\n\n## Tag List\n\n{{tags}}\nHEREDOC\n\n    printf \"export NB_DEFAULT_TEMPLATE=\\\"%s\\\"\\\\n\" \"${_template_path}\" >> \"${NBRC_PATH}\"\n  }\n\n  run \"${_NB}\" add                      \\\n    \"Argument content one.\"             \\\n    --content \"Example option content.\" \\\n    --tags    one,two,three             \\\n    --title   \"Example Title\"           \\\n    \"Argument content two.\" <<< \"Example piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  printf \"File content: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/example_title.md\")\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# - Example Template Title - Example Title\n\n$(date +\"%Y-%m-%d\")\n\nExample command substitution output.\n\n## Full Content\n\nArgument content one. Argument content two.\n\nExample option content.\n\nExample piped content.\n\n## Selector Content\n\nArgument content one. Argument content two.\n\n## Option Content\n\nExample option content.\n\n## Piped Content\n\nExample piped content.\n\n## Tag List\n\n#one #two #three\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# --template ##################################################################\n\n@test \"'add --template <template>' with path <template> creates note based on template.\" {\n  {\n    \"${_NB}\" init\n\n    declare _template_path=\"${_TMP_DIR}/example-template\"\n\n    cat <<HEREDOC > \"${_template_path}\"\n{{title_prefix}} - Example Template Title - {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n\\$(printf \"Example command substitution output.\")\n\n## Full Content\n\n{{content}}\n\n## Selector Content\n\n{{selector_content}}\n\n## Option Content\n\n{{option_content}}\n\n## Piped Content\n\n{{piped_content}}\n\n## Tag List\n\n{{tags}}\nHEREDOC\n  }\n\n  run \"${_NB}\" add                      \\\n    \"Argument content one.\"             \\\n    --content \"Example option content.\" \\\n    --tags    one,two,three             \\\n    --title   \"Example Title\"           \\\n    \"Argument content two.\"             \\\n    --template \"${_template_path}\" <<< \"Example piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  printf \"File content: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/example_title.md\")\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# - Example Template Title - Example Title\n\n$(date +\"%Y-%m-%d\")\n\nExample command substitution output.\n\n## Full Content\n\nArgument content one. Argument content two.\n\nExample option content.\n\nExample piped content.\n\n## Selector Content\n\nArgument content one. Argument content two.\n\n## Option Content\n\nExample option content.\n\n## Piped Content\n\nExample piped content.\n\n## Tag List\n\n#one #two #three\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add --template <template>' with string <template> creates note based on template.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add                      \\\n    \"Argument content one.\"             \\\n    --content \"Example option content.\" \\\n    --tags    one,two,three             \\\n    --title   \"Example Title\"           \\\n    \"Argument content two.\"             \\\n    --template \"$(cat <<HEREDOC\n{{title_prefix}} - Example Template Title - {{title}}\n\n{{date +\"%Y-%m-%d\"}}\n\n\\$(printf \"Example command substitution output.\")\n\n## Full Content\n\n{{content}}\n\n## Selector Content\n\n{{selector_content}}\n\n## Option Content\n\n{{option_content}}\n\n## Piped Content\n\n{{piped_content}}\n\n## Tag List\n\n{{tags}}\nHEREDOC\n    )\" <<< \"Example piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  printf \"File content: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/example_title.md\")\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# - Example Template Title - Example Title\n\n$(date +\"%Y-%m-%d\")\n\nExample command substitution output.\n\n## Full Content\n\nArgument content one. Argument content two.\n\nExample option content.\n\nExample piped content.\n\n## Selector Content\n\nArgument content one. Argument content two.\n\n## Option Content\n\nExample option content.\n\n## Piped Content\n\nExample piped content.\n\n## Tag List\n\n#one #two #three\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n"
  },
  {
    "path": "test/add.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031,SC2063\n\nload test_helper\n\n# --quiet #####################################################################\n\n@test \"'add --quiet' creates new note without printing output.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:+  \\\n    --title     \"Example Title\"     \\\n    --filename  \"File One.md\"       \\\n    --quiet\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                              ]]\n\n  # Prints output:\n\n  [[ -z \"${output:-}\" ]]\n\n  # Creates a new file:\n\n  [[ !  -f \"${NB_DIR}/home/File One.md\"             ]]\n  [[    -f \"${NB_DIR}/Example Notebook/File One.md\" ]]\n\n  diff                                              \\\n    <(cat \"${NB_DIR}/Example Notebook/File One.md\") \\\n    <(cat <<HEREDOC\n# Example Title\n\n# mock_editor ${NB_DIR}/Example Notebook/File One\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n\n# encoding ####################################################################\n\n@test \"'add --filename <filename>' with non-ASCII decomposed filename normalizes it to precomposed format.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  # NOTE: filename is in decomposed format for normalization testing.\n  run \"${_NB}\" add          \\\n        --content   \"#тест\" \\\n        --filename  \"тестовый.md\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n\n  [[    \"${#lines[@]}\"  -eq 1                                   ]]\n  [[    \"${lines[0]}\"   =~  Added:\\ .*[.*1.*].*\\ .*тестовый.md  ]]\n\n  [[ -f \"${NB_DIR}/home/тестовый.md\"      ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/тестовый.md\")   \\\n    <(cat <<HEREDOC\n#тест\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# extension setting ###########################################################\n\n@test \"'add' extension set to .adoc creates AsciiDoc file with formatted title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set default_extension \"adoc\"\n  }\n\n  run \"${_NB}\" add --content \"Example content.\" --title \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                          ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.adoc\"     ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example_title.adoc\")  \\\n    <(cat <<HEREDOC\n= Example Title\n\nExample content.\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' extension set to .asciidoc creates AsciiDoc file with formatted title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set default_extension \"asciidoc\"\n  }\n\n  run \"${_NB}\" add --content \"Example content.\" --title \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                              ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.asciidoc\"     ]]\n\n  diff                                              \\\n    <(cat \"${NB_DIR}/home/example_title.asciidoc\")  \\\n    <(cat <<HEREDOC\n= Example Title\n\nExample content.\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' extension set to .md creates Markdown file with formatted title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set default_extension \"md\"\n  }\n\n  run \"${_NB}\" add --content \"Example content.\" --title \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample content.\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' extension set to .org creates AsciiDoc file with formatted title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set default_extension \"org\"\n  }\n\n  run \"${_NB}\" add --content \"Example content.\" --title \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                          ]]\n\n  [[ -f \"${NB_DIR}/home/example_title.org\"      ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example_title.org\")   \\\n    <(cat <<HEREDOC\n#+TITLE: Example Title\n\nExample content.\nHEREDOC\n)\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# option parsing ##############################################################\n\n@test \"'add --content' with content containing a leading dash (-) successfully creates note.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add                                    \\\n    --content   \"-Example content with leading dash.\" \\\n    --filename  \"Example Filename.org\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/Example Filename.org\" ]]\n\n  diff                                            \\\n    <(cat \"${NB_DIR}/home/Example Filename.org\")  \\\n    <(echo \"-Example content with leading dash.\")\n\n# mock_editor %s/home/Example File\\\\n\" \"${NB_DIR}\")\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with content containing a leading dash (-) successfully creates note.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add                        \\\n    \"-Example content with leading dash.\" \\\n    --filename  \"Example Filename.org\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  [[ -f \"${NB_DIR}/home/Example Filename.org\" ]]\n\n  diff                                            \\\n    <(cat \"${NB_DIR}/home/Example Filename.org\")  \\\n    <(echo \"-Example content with leading dash.\")\n\n# mock_editor %s/home/Example File\\\\n\" \"${NB_DIR}\")\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# aliases ####################################################################\n\n@test \"'<notebook>:+' creates new note with editor.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:+  \\\n    --title     \"Example Title\"     \\\n    --filename  \"File One.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                              ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~  \\\nAdded:\\ .*\\[.*Example\\ Notebook:1.*\\].*\\ .*Example\\ Notebook:File\\ One\\.md.*\\ \\\"Example\\ Title\\\"  ]]\n\n  # Creates a new file:\n\n  [[ !  -f \"${NB_DIR}/home/File One.md\"             ]]\n  [[    -f \"${NB_DIR}/Example Notebook/File One.md\" ]]\n\n  diff                                              \\\n    <(cat \"${NB_DIR}/Example Notebook/File One.md\") \\\n    <(cat <<HEREDOC\n# Example Title\n\n# mock_editor ${NB_DIR}/Example Notebook/File One\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'<notebook>:+ --content <content>' creates new note without opening editor.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:+  \\\n    --title     \"Example Title\"     \\\n    --filename  \"File One.md\"       \\\n    --content   \"Content one.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                              ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~  \\\nAdded:\\ .*\\[.*Example\\ Notebook:1.*\\].*\\ .*Example\\ Notebook:File\\ One\\.md.*\\ \\\"Example\\ Title\\\"  ]]\n\n  # Creates a new file:\n\n  [[ !  -f \"${NB_DIR}/home/File One.md\"             ]]\n  [[    -f \"${NB_DIR}/Example Notebook/File One.md\" ]]\n\n  diff                                              \\\n    <(cat \"${NB_DIR}/Example Notebook/File One.md\") \\\n    <(cat <<HEREDOC\n# Example Title\n\nContent one.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'+' creates new note.\" {\n  {\n    run \"${_NB}\" init\n  }\n\n  run \"${_NB}\" +                \\\n    --title     \"Example Title\" \\\n    --filename  \"File One.md\"   \\\n    --content   \"Content one.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ .*File\\ One\\.md.*\\ \\\"Example\\ Title\\\"  ]]\n\n  # Creates a new file:\n\n  [[ -f \"${NB_DIR}/home/File One.md\"      ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/File One.md\")   \\\n    <(cat <<HEREDOC\n# Example Title\n\nContent one.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'a' with no arguments creates new note file created with \\$EDITOR.\" {\n  {\n    run \"${_NB}\" init\n  }\n\n  run \"${_NB}\" a\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\"      -eq 0                     ]]\n\n  # Prints output:\n\n  [[ \"${output}\"      =~ Added:\\ .*\\[.*1.*\\].*  ]]\n\n  # Creates a new note file with $EDITOR:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  -eq 1                     ]]\n\n  grep -q '# mock_editor' \"${NB_DIR}/home\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n\n@test \"'create' with no arguments creates new note file created with \\$EDITOR.\" {\n  {\n    run \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\"      -eq 0                     ]]\n\n  # Prints output:\n\n  [[ \"${output}\"      =~ Added:\\ .*\\[.*1.*\\].*  ]]\n\n  # Creates a new note file with $EDITOR:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  -eq 1                     ]]\n\n  grep -q '# mock_editor' \"${NB_DIR}/home\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n\n@test \"'new' with no arguments creates new note file created with \\$EDITOR.\" {\n  {\n    run \"${_NB}\" init\n  }\n\n  run \"${_NB}\" new\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\"      -eq 0                     ]]\n\n  # Prints output:\n\n  [[ \"${output}\"      =~ Added:\\ .*\\[.*1.*\\].*  ]]\n\n  # Creates a new note file with $EDITOR:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  -eq 1                     ]]\n\n  grep -q '# mock_editor' \"${NB_DIR}/home\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# --browse ####################################################################\n\n@test \"'add --browse <item-selector>' creates new file with populated content and selector filename field.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" add --browse Example\\ Folder/Example\\ File.md --print  \\\n    --title     \"Example Title\"                                       \\\n    --content   \"Example content.\"                                    \\\n    --tags      tag1,tag2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                    ]]\n\n  [[    \"${output}\"  =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/home:?--columns=.*&--limit=.*\\\">home</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\".*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"action=\\\"/home:Example%20Folder/Example%20File.md?--add&--columns=.*&--limit=.*\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"add\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"rows=\\\".*\\\"># Example Title${_NEWLINE}${_NEWLINE}#tag1 #tag2${_NEWLINE}${_NEWLINE}Example content.${_NEWLINE}</textarea>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<input type=\\\"hidden\\\" name=\\\"--title\\\"\"\n}\n\n# --title option ##############################################################\n\n@test \"'add --title' with .adoc file creates file with AsciiDoc title.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --title \"Example Title\" --filename \"Example File.adoc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  [[ -f \"${NB_DIR}/home/Example File.adoc\" ]]\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/Example File.adoc\") \\\n    <(printf \"\\\n= Example Title\n\n# mock_editor %s/home/Example File\\\\n\" \"${NB_DIR}\")\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add --title' with .asciidoc file creates file with AsciiDoc title.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --title \"Example Title\" --filename \"Example File.asciidoc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0  ]]\n\n  [[ -f \"${NB_DIR}/home/Example File.asciidoc\"    ]]\n\n  diff                                            \\\n    <(cat \"${NB_DIR}/home/Example File.asciidoc\") \\\n    <(printf \"\\\n= Example Title\n\n# mock_editor %s/home/Example File\\\\n\" \"${NB_DIR}\")\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add --title' with .adocx123 file (partially matching non-recognized extension) creates file with default markdown title.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --title \"Example Title\" --filename \"Example File.adocx\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  [[ -f \"${NB_DIR}/home/Example File.adocx\"     ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example File.adocx\")  \\\n    <(printf \"\\\n# Example Title\n\n# mock_editor %s/home/Example File\\\\n\" \"${NB_DIR}\")\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add --title' with .org file creates file with .org title.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --title \"Example Title\" --filename \"Example File.org\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  [[ -f \"${NB_DIR}/home/Example File.org\" ]]\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/Example File.org\")  \\\n    <(printf \"\\\n#+TITLE: Example Title\n\n# mock_editor %s/home/Example File\\\\n\" \"${NB_DIR}\")\n\n  cd \"${NB_DIR}/home\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add --title <title>' exits with 0, creates new note with \\$EDITOR, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \\\n    --title \" [ ] Example Title: A*string•with/a\\\\bunch|of?invalid<filename\\\"characters>\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  [[ -n \"$(\n    ls example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md\n  )\" ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")  \\\n    <(printf \"\\\n#  [ ] Example Title: A*string•with/a\\\\\\\\bunch|of?invalid<filename\\\"characters>\n\n# mock_editor %s/home/%s\\\\n\" \"${NB_DIR}\" \"${_files[0]%.md}\")\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with empty --title option exits with 1\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --title\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 1      ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  ls \"${NB_DIR}/home/\"\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0  ]]\n}\n\n@test \"'add --title <title> --content <content>' with colons successfully creates note without \\$EDITOR.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add                                                                          \\\n    --title   \" [ ] Example Title: A*string•with/a\\\\bunch|of?invalid<filename\\\"characters>\" \\\n    --content \"Example: content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  [[ -n \"$(\n    ls example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md\n  )\" ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")  \\\n    <(printf \"\\\n#  [ ] Example Title: A*string•with/a\\\\\\\\bunch|of?invalid<filename\\\"characters>\n\nExample: content.\\\\n\")\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# content #####################################################################\n\n@test \"'add' with piped content includes content from --title and multiple --tags, --content, and arguments separated by newlines.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add                  \\\n    \"Argument content one.\"         \\\n    --tags    tag1,tag2             \\\n    --title   \"Example Title\"       \\\n    --content \"Option content one.\" \\\n    --tags    tag3,tag4             \\\n    --content \"Option content two.\" \\\n    \"Argument content two.\" <<< \"Piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  # Creates new note file:\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\n#tag1 #tag2 #tag3 #tag4\n\nArgument content one. Argument content two.\n\nOption content one.\n\nOption content two.\n\nPiped content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log --stat\n  git log | grep -q '\\[nb\\] Add: example_title.md'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"           ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home\")                \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example_title.md.*\\ \\\"Example\\ Title\\\" ]]\n}\n\n@test \"'add' with piped content includes content from --title and multiple --tags, --content, and arguments separated by newlines and names file to value in --filename when it starts with a '.' (period).\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add                  \\\n    \"Argument content one.\"         \\\n    --tags    tag1,tag2             \\\n    --title   \"Example Title\"       \\\n    --content \"Option content one.\" \\\n    --tags    tag3,tag4             \\\n    --content \"Option content two.\" \\\n    \"Argument content two.\"         \\\n    --filename \"example.markdown\" <<< \"Piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                        ]]\n\n  # Creates new note file:\n\n  [[ -f \"${NB_DIR}/home/example.markdown\"     ]]\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example.markdown\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\n#tag1 #tag2 #tag3 #tag4\n\nArgument content one. Argument content two.\n\nOption content one.\n\nOption content two.\n\nPiped content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log --stat\n  git log | grep -q \"\\[nb\\] Add: example.markdown\"\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"           ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home\")                \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*                   ]]\n  [[ \"${lines[0]}\" =~ \\example.markdown.*\\ \\\"Example\\ Title\\\"   ]]\n}\n\n@test \"'add' with piped content includes content from --title and multiple --tags, --content, and arguments separated by newlines and names file to value in --filename.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add                  \\\n    \"Argument content one.\"         \\\n    --tags    tag1,tag2             \\\n    --title   \"Example Title\"       \\\n    --content \"Option content one.\" \\\n    --tags    tag3,tag4             \\\n    --content \"Option content two.\" \\\n    \"Argument content two.\"         \\\n    --filename \".markdown\" <<< \"Piped content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                ]]\n\n  # Creates new note file:\n\n  [[ -f \"${NB_DIR}/home/.markdown\"    ]]\n\n  diff                                \\\n    <(cat \"${NB_DIR}/home/.markdown\") \\\n    <(cat <<HEREDOC\n# Example Title\n\n#tag1 #tag2 #tag3 #tag4\n\nArgument content one. Argument content two.\n\nOption content one.\n\nOption content two.\n\nPiped content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log --stat\n  git log | grep -q '\\[nb\\] Add: .markdown'\n\n  # Does not add to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"           ]]\n  [[ -z \"$(cat \"${NB_DIR}/home/.index\")\"  ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*].*\\ .*              ]]\n  [[ \"${lines[0]}\" =~ \\.markdown.*\\ \\\"Example\\ Title\\\"  ]]\n}\n\n# no argument #################################################################\n\n@test \"'add' with no arguments creates new note file created with \\$EDITOR.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates a new note file with $EDITOR:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  grep -q '# mock_editor' \"${NB_DIR}/home\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# --tags option ###############################################################\n\n@test \"'add --tags' with no argument exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --tags --filename \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # Does not create new note file with content:\n\n  [[ ! -f \"${NB_DIR}/home/example.md\" ]]\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ !.*\\ .*--tags.*\\ requires\\ a\\ valid\\ argument. ]]\n}\n\n@test \"'add --tags <tag-list>' creates new note with tags.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add            \\\n    --tags    tag1,tag2       \\\n    --title   \"Example Title\" \\\n    --content \"Example content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new note file with content:\n\n  [[ -f \"${NB_DIR}/home/example_title.md\"     ]]\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\n#tag1 #tag2\n\nExample content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example_title.md ]]\n}\n\n@test \"'add --tags <tag-list>' with tags formatted as hashtags creates new note with tags.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add              \\\n    --tags    '#tag1','#tag2'   \\\n    --title   \"Example Title\"   \\\n    --content \"Example content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new note file with content:\n\n  [[ -f \"${NB_DIR}/home/example_title.md\" ]]\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\n#tag1 #tag2\n\nExample content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example_title.md ]]\n}\n\n@test \"'add --tags <tag-list> --tag <tag-list>' with a mix of tag formatting creates new note with tags.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add                \\\n    --tags    '#tag1',tag2        \\\n    --title   \"Example Title\"     \\\n    --content \"Example content.\"  \\\n    --tag     tag3,'#tag4',tag5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new note file with content:\n\n  [[ -f \"${NB_DIR}/home/example_title.md\" ]]\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\n#tag1 #tag2 #tag3 #tag4 #tag5\n\nExample content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example_title.md ]]\n}\n\n# piped #######################################################################\n\n@test \"'add' with piped content includes content from --title, --tags, --content, and arguments separated by newlines.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  echo \"Piped content.\" | {\n    run \"${_NB}\" add              \\\n      \"Argument content one.\"     \\\n      --tags    tag1,tag2         \\\n      --title   \"Example Title\"   \\\n      --content \"Option content.\" \\\n      \"Argument content two.\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    # Returns status 0:\n\n    [[ \"${status}\" -eq 0          ]]\n\n    # Creates new note file:\n\n    [[ -f \"${NB_DIR}/home/example_title.md\" ]]\n\n    diff                                        \\\n      <(cat \"${NB_DIR}/home/example_title.md\")  \\\n      <(cat <<HEREDOC\n# Example Title\n\n#tag1 #tag2\n\nArgument content one. Argument content two.\n\nOption content.\n\nPiped content.\nHEREDOC\n)\n\n    # Creates git commit:\n\n    cd \"${NB_DIR}/home\" || return 1\n    while [[ -n \"$(git status --porcelain)\" ]]\n    do\n      sleep 1\n    done\n    git log --stat\n    git log | grep -q '\\[nb\\] Add: example_title.md'\n\n    # Adds to index:\n\n    [[ -e \"${NB_DIR}/home/.index\" ]]\n\n    diff                      \\\n      <(ls \"${NB_DIR}/home\")  \\\n      <(cat \"${NB_DIR}/home/.index\")\n\n    # Prints output:\n\n    [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example_title.md.*\\ \\\"Example\\ Title\\\" ]]\n  }\n}\n\n@test \"'add' with piped content includes content from --title, and standard input separated by newlines.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo 'Piped content.' | \\\"${_NB}\\\" add --title Example\\ Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file:\n\n  [[ -f \"${NB_DIR}/home/example_title.md\" ]]\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nPiped content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log --stat\n  git log | grep -q '\\[nb\\] Add: example_title.md'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example_title.md.*\\ \\\"Example\\ Title\\\" ]]\n}\n\n@test \"'add' with piped content includes content from --content, and standard input separated by newlines.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo 'Piped content.' | \\\"${_NB}\\\" add --content \\\"Example content.\\\"\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  [[ -f \"${NB_DIR}/home/${_files[0]:-}\" ]]\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/home/${_files[0]:-}\")  \\\n    <(cat <<HEREDOC\nExample content.\n\nPiped content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log --stat\n  git log | grep -q \"\\[nb\\] Add: ${_files[0]:-}\"\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*${_files[0]:-} ]]\n}\n\n@test \"'add' with piped content creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo '# Piped content.' | \\\"${_NB}\\\" add --filename example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file:\n\n  [[ -f \"${NB_DIR}/home/example.md\" ]]\n\n  diff                                  \\\n    <(cat \"${NB_DIR}/home/example.md\")  \\\n    <(cat <<HEREDOC\n# Piped content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: example.md'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example.md.*\\ \\\"Piped\\ content.\\\" ]]\n}\n\n@test \"'add --type org' with piped content creates a new .org note file.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo '# Piped' | \\\"${_NB}\\\" add --type org\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  grep -q '# Piped' \"${NB_DIR}/home\"/*\n\n  [[ \"${_files[0]}\" =~ org$ ]]\n}\n\n@test \"'add --type ''' with piped content exits with 1.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo '# Piped' | \\\"${_NB}\\\" add --type\"\n\n  [[ ${status} -eq 1        ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0  ]]\n}\n\n# notebook: scoped ############################################################\n\n@test \"'add notebook:' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" add example:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with $EDITOR:\n\n  _files=($(ls \"${NB_DIR}/example\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  [[ \"$(cat \"${NB_DIR}/example/${_files[0]}\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/example\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/example/.index\"          ]]\n\n  diff                        \\\n    <(ls \"${NB_DIR}/example\") \\\n    <(cat \"${NB_DIR}/example/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                  ]]\n  [[ \"${output}\" =~ example:[A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ example:[A-Za-z0-9]+.md ]]\n}\n\n@test \"'notebook:add' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" example:add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Creates new note file with $EDITOR:\n\n  _files=($(ls \"${NB_DIR}/example\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  [[ \"$(cat \"${NB_DIR}/example/${_files[0]}\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/example\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/example/.index\"          ]]\n\n  diff                        \\\n    <(ls \"${NB_DIR}/example\") \\\n    <(cat \"${NB_DIR}/example/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                  ]]\n  [[ \"${output}\" =~ example:[A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ example:[A-Za-z0-9]+.md ]]\n}\n\n@test \"'add notebook: <filename>' (space) creates new note with <filename>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" add example: \"Example Filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with $EDITOR:\n\n  cat \"${NB_DIR}/example/Example Filename.md\"\n\n  [[ -f \"${NB_DIR}/example/Example Filename.md\"                         ]]\n  [[    \"$(cat \"${NB_DIR}/example/Example Filename.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/example\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example Filename.md'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/example/.index\"          ]]\n\n  diff                        \\\n    <(ls \"${NB_DIR}/example\") \\\n    <(cat \"${NB_DIR}/example/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                        ]]\n  [[ \"${output}\" =~ example:[A-Za-z0-9]+          ]]\n  [[ \"${output}\" =~ example:Example\\ Filename.md  ]]\n}\n\n@test \"'add notebook:<filename>' (no space) creates new note with <filename>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" add example:Example\\ Filename.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with $EDITOR:\n\n  [[ -f \"${NB_DIR}/example/Example Filename.md\"                         ]]\n  [[    \"$(cat \"${NB_DIR}/example/Example Filename.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/example\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example Filename.md'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/example/.index\"          ]]\n\n  diff                        \\\n    <(ls \"${NB_DIR}/example\") \\\n    <(cat \"${NB_DIR}/example/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                        ]]\n  [[ \"${output}\" =~ example:[A-Za-z0-9]+          ]]\n  [[ \"${output}\" =~ example:Example\\ Filename.md  ]]\n}\n\n@test \"'add notebook:<string>' (no space) creates new note with <string> as filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" add example:Example\\ String\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with $EDITOR:\n\n  [[ -f \"${NB_DIR}/example/Example String\"                          ]]\n  [[    \"$(cat \"${NB_DIR}/example/Example String\")\" =~ mock_editor  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/example\" || return 1\n  while [[ -n \"$(git status --porcelain)\"     ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/example/.index\"            ]]\n\n  diff                        \\\n    <(ls \"${NB_DIR}/example\") \\\n    <(cat \"${NB_DIR}/example/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                  ]]\n  [[ \"${output}\" =~ example:[A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ example:Example\\ String ]]\n}\n\n\n@test \"'add notebook: <string>' (space) creates new note with <string> as content.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" add example: Example\\ String\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with $EDITOR:\n\n  _files=($(ls \"${NB_DIR}/example\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  [[ \"$(cat \"${NB_DIR}/example/${_files[0]}\")\" =~ Example\\ String ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/example\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/example/.index\"          ]]\n\n  diff                        \\\n    <(ls \"${NB_DIR}/example\") \\\n    <(cat \"${NB_DIR}/example/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                  ]]\n  [[ \"${output}\" =~ example:[A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ example:[A-Za-z0-9]+.md ]]\n}\n\n# <filename> argument #########################################################\n\n@test \"'add' with filename argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \"example-filename.md\" --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new note file with content:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" == 1                     ]]\n  [[ \"${_files[0]}\" == \"example-filename.md\"  ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/home\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:              ]]\n  [[ \"${output}\" =~ example-filename.md ]]\n}\n\n@test \"'add' with .org filename argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \"example-filename.org\" --content \"Example content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new note file with content:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  == 1                      ]]\n  [[ \"${_files[0]}\"   == \"example-filename.org\" ]]\n\n  grep -q 'Example content.' \"${NB_DIR}/home\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                ]]\n  [[ \"${output}\" =~ example-filename.org  ]]\n}\n\n# <content> argument ##########################################################\n\n@test \"'add' with content argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \"# Content\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with content:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  grep -q '# Content' \"${NB_DIR}/home\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'add' with scope and content argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add Example\n  }\n\n  run \"${_NB}\" Example:add \"# Content\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with content:\n\n  _files=($(ls \"${NB_DIR}/Example/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  grep -q '# Content' \"${NB_DIR}/Example\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example/.index\" ]]\n\n  diff                        \\\n    <(ls \"${NB_DIR}/Example\") \\\n    <(cat \"${NB_DIR}/Example/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                  ]]\n  [[ \"${output}\" =~ Example:[A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ Example:[A-Za-z0-9]+.md ]]\n}\n\n@test \"'add' with URL content argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with content:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_files[0]}\")\" == \"${_BOOKMARK_URL}\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'add' with scope and URL content argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add Example\n  }\n\n  run \"${_NB}\" Example:add \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with content:\n\n  _files=($(ls \"${NB_DIR}/Example/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  [[ \"$(cat \"${NB_DIR}/Example/${_files[0]}\")\" == \"${_BOOKMARK_URL}\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example/.index\" ]]\n\n  diff                        \\\n    <(ls \"${NB_DIR}/Example\") \\\n    <(cat \"${NB_DIR}/Example/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                  ]]\n  [[ \"${output}\" =~ Example:[A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ Example:[A-Za-z0-9]+.md ]]\n}\n\n@test \"'add' with email address content argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \"example@example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with content:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_files[0]}\")\" == \"example@example.com\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'add' with 'http:' non-URL content argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \"http: this is not a URL\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with content:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_files[0]}\")\" == \"http: this is not a URL\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'add' with 'example.com' common TLD domain content argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \"example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # Creates new note file with content:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_files[0]}\")\" == \"example.com\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n# --content option ############################################################\n\n@test \"'add' with --content option exits with 0, creates new note, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --content \"# Content\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  grep -q '# Content' \"${NB_DIR}/home\"/*\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with URL --content option exits with 0, creates new note, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --content \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  grep -q 'file' \"${NB_DIR}/home\"/*\n  grep -q 'fixtures' \"${NB_DIR}/home\"/*\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with empty --content option exits with 1\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --content\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 1      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0  ]]\n}\n\n# --filename option ###########################################################\n\n@test \"'add' with --filename option starting with a '.' (period) uses the specified filename without adding to .index.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --filename .markdown\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                                             ]]\n  [[ \"${output}\" =~   Added:\\ .*[.*].*\\                             ]]\n  [[ \"${output}\" =~   .markdown.*\\ \\\"mock_editor\\ ${NB_DIR}/home/\\\" ]]\n\n  [[ -e \"${NB_DIR}/home/.markdown\"                                  ]]\n\n  [[ -z \"$(cat \"${NB_DIR}/home/.index\")\"                            ]]\n\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log\n  git -C \"${NB_DIR}/home\" log | grep -q \"\\[nb\\] Add: .markdown\"\n}\n\n@test \"'add' with --filename option exits with 0, creates new note, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --filename example.org\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  [[ -n \"$(ls example.org)\" ]]\n\n  grep -q '# mock_editor' \"${NB_DIR}/home\"/*\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with --filename option overrides content or filename argument.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \"sample.md\" --filename example.org\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  [[ -n \"$(ls example.org)\" ]]\n  run ! grep -q '# mock_editor' \"${NB_DIR}/home\"/*\n  grep -q 'sample.md' \"${NB_DIR}/home\"/*\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with extensionless --filename option creates file without extension.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --filename example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0     ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  [[   -n \"$(ls example)\"             ]]\n  [[   -e \"${NB_DIR}/home/example\"    ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\" ]]\n\n  grep -q '# mock_editor' \"${NB_DIR}/home\"/*\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with empty --filename option exits with 1\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 1      ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  ls \"${NB_DIR}/home/\"\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0  ]]\n}\n\n# --type option ###############################################################\n\n@test \"'add --type org' with content argument creates a new .org note file.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add  \"* Content\" --type org\n\n  [[ \"${status}\" -eq 0      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  grep -q '* Content' \"${NB_DIR}/home\"/*\n\n  [[ \"${_files[0]}\" =~ org$ ]]\n}\n\n@test \"'add --type ''' without argument exits with 1.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add  \"* Content\" --type\n\n  [[ \"${status}\" -eq 1      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0  ]]\n}\n\n# --encrypt option ############################################################\n\n@test \"'add --encrypt' with content argument creates a new .enc note file.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add  \"* Content\" --encrypt --password=example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${status}\"      -eq 0                                                     ]]\n  [[ \"${#_files[@]}\"  -eq 1                                                     ]]\n  [[ \"${_files[0]}\"   =~  enc$                                                  ]]\n  [[ \"$(file \"${NB_DIR}/home/${_files[0]}\" | cut -d: -f2)\" =~ encrypted|openssl ]]\n}\n\n@test \"'add --encrypt' with invalid encryption tool displays error message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  NB_ENCRYPTION_TOOL=\"not-valid\" run \"${_NB}\" add  \"* Content\" --encrypt --password=example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${status}\"      -eq 1                             ]]\n  [[ \"${#_files[@]}\"  -eq 0                             ]]\n  [[ \"${output}\"      =~  Encryption\\ tool\\ not\\ found: ]]\n  [[ \"${output}\"      =~  not-valid                     ]]\n}\n\n# --password option ###########################################################\n\n@test \"'add --password' without argument exits with 1.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add  \"* Content\" --encrypt --password\n\n  [[ \"${status}\"    -eq 1   ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0  ]]\n}\n\n# help ########################################################################\n\n@test \"'help add' exits with status 0 and prints help information.\" {\n  run \"${_NB}\" help add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:  ]]\n  [[ \"${lines[1]}\"  =~  nb\\ add   ]]\n}\n\n@test \"'help a' exits with status 0 and prints help information.\" {\n  run \"${_NB}\" help a\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:  ]]\n  [[ \"${lines[1]}\"  =~  nb\\ add   ]]\n}\n\n@test \"'help +' exits with status 0 and prints help information.\" {\n  run \"${_NB}\" help +\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:  ]]\n  [[ \"${lines[1]}\"  =~  nb\\ add   ]]\n}\n\n@test \"'help create' exits with status 0 and prints help information.\" {\n  run \"${_NB}\" help create\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:  ]]\n  [[ \"${lines[1]}\"  =~  nb\\ add   ]]\n}\n\n@test \"'help new' exits with status 0 and prints help information.\" {\n  run \"${_NB}\" help new\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:  ]]\n  [[ \"${lines[1]}\"  =~  nb\\ add   ]]\n}\n"
  },
  {
    "path": "test/archive-unarchive.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# <name> validation ###########################################################\n\n@test \"'archive <reserved>' exits with 1 and prints error message.\" {\n  {\n    \"${_NB}\" init\n\n    cd \"${_TMP_DIR}\"\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"home\\\\n\")\n\n    declare _names=(\n      \".cache\"\n      \".current\"\n      \".plugins\"\n      \".readme\"\n      \"readme\"\n      \"readme.md\"\n    )\n  }\n\n  declare __name=\n  for     __name in \"${_names[@]}\"\n  do\n    run \"${_NB}\" archive \"${__name}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"    -eq 1               ]]\n    [[ \"${lines[0]}\"  =~  Name\\ reserved  ]]\n    [[ \"${lines[0]}\"  =~  ${__name}       ]]\n  done\n}\n\n# `archive` ###################################################################\n\n@test \"'ar' exits with 0 and archives the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"Example Notebook\\\\n\")\n\n    [[ !  -f \"${NB_DIR}/Example Notebook/.archived\" ]]\n  }\n\n  run \"${_NB}\" ar\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                 ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"Example Notebook\") archived.\"  ]]\n\n  [[    -f \"${NB_DIR}/Example Notebook/.archived\"   ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Archived'\n\n  cd \"${_TMP_DIR}\"\n\n  run \"${_NB}\" ls --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                               ]]\n\n  [[ \"${lines[0]}\"  =~  [[:space:]][[:space:]]home\\ ·\\ \\[1\\ archived\\]  ]]\n  [[ \"${output}\"    =~  0\\ items\\.                                      ]]\n}\n\n@test \"'archive' exits with 0 and archives 'home' when it's the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"home\\\\n\")\n\n    [[ !  -f \"${NB_DIR}/Example Notebook/.archived\"         ]]\n  }\n\n  run \"${_NB}\" archive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                     ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"home\") archived.\"  ]]\n\n  [[    -f \"${NB_DIR}/home/.archived\"                       ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"                   ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Archived'\n\n  cd \"${_TMP_DIR}\"\n\n  run \"${_NB}\" ls --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n\n  [[ \"${lines[0]}\"  =~  [[:space:]][[:space:]]\\[1\\ archived\\] ]]\n  [[ \"${output}\"    =~  0\\ items\\.                            ]]\n}\n\n@test \"'archive' exits with 0 and archives the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"Example Notebook\\\\n\")\n\n    [[ !  -f \"${NB_DIR}/Example Notebook/.archived\" ]]\n  }\n\n  run \"${_NB}\" archive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                 ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"Example Notebook\") archived.\"  ]]\n\n  [[    -f \"${NB_DIR}/Example Notebook/.archived\"   ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Archived'\n\n  cd \"${_TMP_DIR}\"\n\n  run \"${_NB}\" ls --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                               ]]\n\n  [[ \"${lines[0]}\"  =~  [[:space:]][[:space:]]home\\ ·\\ \\[1\\ archived\\]  ]]\n  [[ \"${output}\"    =~  0\\ items\\.                                      ]]\n}\n\n@test \"'archive <name>' exits with 0 and archives notebook <name>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"home\\\\n\")\n\n    [[ !  -f \"${NB_DIR}/Example Notebook/.archived\" ]]\n  }\n\n  run \"${_NB}\" archive \"Example Notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                 ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"Example Notebook\") archived.\"  ]]\n\n  [[    -f \"${NB_DIR}/Example Notebook/.archived\"   ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Archived'\n\n  cd \"${_TMP_DIR}\"\n\n  run \"${_NB}\" ls --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                               ]]\n\n  [[ \"${lines[0]}\"  =~  [[:space:]][[:space:]]home\\ ·\\ \\[1\\ archived\\]  ]]\n  [[ \"${output}\"    =~  0\\ items\\.                                      ]]\n}\n\n@test \"'archive' does not create git commit if already archived.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"Example Notebook\\\\n\")\n\n    touch \"${NB_DIR}/Example Notebook/.archived\"\n\n    [[    -f \"${NB_DIR}/Example Notebook/.archived\" ]]\n  }\n\n  run \"${_NB}\" archive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                             ]]\n\n  # NOTE: Spinner changes output in unexpected ways.\n  [[ \"${output}\"  =~  Example\\ Notebook             ]]\n  [[ \"${output}\"  =~  archived\\.$                   ]]\n\n  [[    -f \"${NB_DIR}/Example Notebook/.archived\"   ]]\n\n  # Does not create git commit\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q -v '\\[nb\\] Archived'\n}\n\n# `unarchive` #################################################################\n\n@test \"'unar' exits with 0 and unarchives the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"Example Notebook\\\\n\")\n\n    \"${_NB}\" archive\n\n    [[    -f \"${NB_DIR}/Example Notebook/.archived\" ]]\n  }\n\n  run \"${_NB}\" unar\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                   ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"Example Notebook\") unarchived.\"  ]]\n\n  [[ !  -f \"${NB_DIR}/Example Notebook/.archived\"   ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n\n  git log | grep '\\[nb\\] Unarchived'\n}\n\n@test \"'unarchive' exits with 0 and unarchives the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"Example Notebook\\\\n\")\n\n    \"${_NB}\" archive\n\n    [[    -f \"${NB_DIR}/Example Notebook/.archived\" ]]\n  }\n\n  run \"${_NB}\" unarchive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                   ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"Example Notebook\") unarchived.\"  ]]\n\n  [[ !  -f \"${NB_DIR}/Example Notebook/.archived\"   ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n\n  git log | grep '\\[nb\\] Unarchived'\n}\n\n@test \"'unarchive <name>' exits with 0 and unarchives notebook <name>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"home\\\\n\")\n\n    \"${_NB}\" archive \"Example Notebook\"\n\n    [[    -f \"${NB_DIR}/Example Notebook/.archived\" ]]\n  }\n\n  run \"${_NB}\" unarchive \"Example Notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                   ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"Example Notebook\") unarchived.\"  ]]\n\n  [[ !  -f \"${NB_DIR}/Example Notebook/.archived\"   ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n\n  git log | grep '\\[nb\\] Unarchived'\n}\n\n@test \"'unarchive' does not create git commit if already archived.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                    \\\n      <(\"${_NB}\" notebooks current --name)  \\\n      <(printf \"Example Notebook\\\\n\")\n\n    [[ !  -f \"${NB_DIR}/Example Notebook/.archived\" ]]\n  }\n\n  run \"${_NB}\" unarchive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                             ]]\n\n  # NOTE: Spinner changes output in unexpected ways.\n  [[ \"${output}\"  =~  Example\\ Notebook             ]]\n  [[ \"${output}\"  =~  unarchived\\.$                 ]]\n\n  [[ !  -f \"${NB_DIR}/Example Notebook/.archived\"   ]]\n\n  # Does not create git commit\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"           ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q -v '\\[nb\\] Unarchived'\n}\n"
  },
  {
    "path": "test/bookmark-command.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# no argument #################################################################\n\n@test \"'bookmark' command with no argument exits with 0, prints message, and lists.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_BOOKMARK}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0\n  [[ ${status} -eq 0 ]]\n\n  # Does not create note file\n  _files=($(ls \"${NB_DIR}/home/\"))\n  [[ \"${#_files[@]}\" -eq 0 ]]\n\n  # Does not create git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Add'\n\n  # Prints help information\n  [[ \"${lines[0]}\" =~ ^Add ]]\n}\n\n# <url> or <list option...> argument ##########################################\n\n@test \"'bookmark <query>' command exits with 0 and displays a list of bookmarks with titles.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nline example\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n      --title \"Example Bookmark Title\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_BOOKMARK}\" example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0 ]]\n  [[ \"${lines[0]}\" =~ Example\\ Bookmark\\ Title ]] && [[ \"${lines[0]}\" =~ 4 ]]\n  [[ \"${#lines[@]}\" == \"1\" ]]\n}\n\n@test \"'bookmark --sort' command exits with 0 and displays a sorted list of bookmarks.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n      --title \"Example Bookmark Title\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_BOOKMARK}\" --sort\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0 ]]\n  [[ \"${lines[0]}\" =~ second.bookmark.md       ]] && [[ \"${lines[0]}\" =~ 2 ]]\n  [[ \"${lines[1]}\" =~ Example\\ Bookmark\\ Title ]] && [[ \"${lines[1]}\" =~ 4 ]]\n}\n\n@test \"'bookmark' command with valid <url> argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_BOOKMARK}\" \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note with bookmark filename\n  [[ \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md ]]\n\n  # Creates new note file with content\n  [[ \"${#_files[@]}\" -eq 1 ]]\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark' with invalid <url> argument creates new bookmark without downloading.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark 'http://invalid-url'\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note with bookmark filename\n  [[ \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md ]]\n\n  # Creates new note file with content\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  _bookmark_content=\"# (invalid-url)\n\n<http://invalid-url>\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  diff <(cat \"${NB_DIR}/home/${_filename}\") <(printf \"%s\\\\n\" \"${_bookmark_content}\")\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints error message\n  _message=\"${_ERROR_PREFIX} Unable to download page at $(_color_primary \"http://invalid-url\")\"\n  [[ \"${lines[0]}\" == \"${_message}\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n"
  },
  {
    "path": "test/bookmark-processing.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'bookmark' extracts title when tags are separated by newlines.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_TITLES_NEWLINES_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n\n  [[ \"${status}\"    -eq   0                         ]]\n\n  # Creates new note with bookmark filename\n\n  [[ \"${_filename}\" =~    [A-Za-z0-9]+.bookmark.md  ]]\n\n  # Creates new note file with content\n\n  [[ \"${#_files[@]}\" -eq  1                         ]]\n\n  diff                                              \\\n    <(cat \"${NB_DIR}/home/${_filename}\")            \\\n    <(cat <<HEREDOC\n# Title One\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com-titles-newlines.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n    )\n\n  # Creates git commit\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n\n  [[ -e \"${NB_DIR}/home/.index\"               ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home\")                    \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output\n\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark' extracts first title when there are multiple.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_TITLES_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n\n  [[ \"${status}\"    -eq   0                         ]]\n\n  # Creates new note with bookmark filename\n\n  [[ \"${_filename}\" =~    [A-Za-z0-9]+.bookmark.md  ]]\n\n  # Creates new note file with content\n\n  [[ \"${#_files[@]}\" -eq  1                         ]]\n\n  diff                                              \\\n    <(cat \"${NB_DIR}/home/${_filename}\")            \\\n    <(cat <<HEREDOC\n# Title One\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com-titles.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n    )\n\n  # Creates git commit\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n\n  [[ -e \"${NB_DIR}/home/.index\"               ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home\")                    \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output\n\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark' extracts title and meta description tag content.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n\n  [[ \"${status}\"    -eq   0                         ]]\n\n  # Creates new note with bookmark filename\n\n  [[ \"${_filename}\" =~    [A-Za-z0-9]+.bookmark.md  ]]\n\n  # Creates new note file with content\n\n  [[ \"${#_files[@]}\" -eq  1                         ]]\n\n  diff                                              \\\n    <(cat \"${NB_DIR}/home/${_filename}\")            \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n    )\n\n  # Creates git commit\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n\n  [[ -e \"${NB_DIR}/home/.index\"               ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home\")                    \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output\n\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark' extracts open graph title and description tag content.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_OG_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  #\n  [[ \"${status}\"    -eq   0                         ]]\n\n  # Creates new note with bookmark filename\n\n  [[ \"${_filename}\" =~    [A-Za-z0-9]+.bookmark.md  ]]\n\n  # Creates new note file with content\n\n  [[ \"${#_files[@]}\" -eq  1                         ]]\n\n  diff                                              \\\n    <(cat \"${NB_DIR}/home/${_filename}\")            \\\n    <(cat <<HEREDOC\n# Example OG Title\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com-og.html>\n\n## Description\n\nExample OG description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n    )\n\n  # Creates git commit\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n\n  [[ -e \"${NB_DIR}/home/.index\"               ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home\")                    \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output\n\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n"
  },
  {
    "path": "test/bookmark.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --quiet #####################################################################\n\n@test \"'add bookmark' with --quiet option creates new bookmark without printing output.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\" add bookmark       \\\n    \"${_BOOKMARK_URL}\"            \\\n    --tags tag1,tag2              \\\n    --filename \"example\"          \\\n    --related http://example.org  \\\n    --related sample:123          \\\n    --related \"[[demo:456]]\"      \\\n    --related \"Example Title\"     \\\n    --quiet\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  [[ -f \"${NB_DIR}/home/example.bookmark.md\" ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Does not print output:\n\n  [[ -z \"${output:-}\" ]]\n}\n\n# templates ###################################################################\n\n@test \"'bookmark <url>' with assigned \\$NB_DEFAULT_TEMPLATE skips the template.\" {\n  {\n    \"${_NB}\" init\n\n    export NB_DEFAULT_TEMPLATE=\"Example template with no template tags.\"\n  }\n\n  run \"${_NB}\"                    \\\n    \"${_BOOKMARK_URL}\"            \\\n    --tags tag1,tag2              \\\n    --filename \"example\"          \\\n    --related http://example.org  \\\n    --related sample:123          \\\n    --related \"[[demo:456]]\"      \\\n    --related \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  [[ -f \"${NB_DIR}/home/example.bookmark.md\" ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example.bookmark.md ]]\n}\n\n\n# dupe detection ##############################################################\n\n@test \"'bookmark folder/ <url>' with existing bookmark at notebook root does not display prompt.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --filename one\n\n    declare _before_files=()\n    _before_files=($(ls \"${NB_DIR}/home/\"))\n\n    printf \"\\${_BOOKMARK_URL}:      '%s'\\\\n\"  \"${_BOOKMARK_URL:-}\"\n    printf \"\\${_before_files[*]}: '%s'\\\\n\"  \"${_before_files[*]:-}\"\n\n    [[        \"${#_before_files[@]}\" -eq 1                    ]]\n    [[    -f  \"${NB_DIR}/home/one.bookmark.md\"                ]]\n    [[ !  -f  \"${NB_DIR}/home/Example Folder/two.bookmark.md\" ]]\n\n    diff                                        \\\n      <(cat \"${NB_DIR}/home/one.bookmark.md\")   \\\n      <(cat <<HEREDOC\n# Example Domain\n\n<${_BOOKMARK_URL:-}>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n      )\n  }\n\n  run \"${_NB}\" bookmark \"Example Folder/\" \"${_BOOKMARK_URL}\" --filename two <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq  0  ]]\n  [[ \"${#lines[@]}\" -eq  2  ]]\n\n  [[ \"${lines[0]}\"  =~   \\\nCreating\\ new\\ folder:\\ .*Example\\ Folder                                                         ]]\n  [[ \"${lines[1]}\"  =~   \\\nAdded:\\ .*[.*Example\\ Folder/1.*].*\\ 🔖\\ .*Example\\ Folder/two.bookmark.md.*\\ \\\"Example\\ Domain\\\" ]]\n\n  declare _after_files=()\n  _after_files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_after_files[*]}: '%s'\\\\n\"  \"${_after_files[*]:-}\"\n\n  [[        \"${#_after_files[@]}\" -eq 2                     ]]\n  [[    -f  \"${NB_DIR}/home/one.bookmark.md\"                ]]\n  [[    -f  \"${NB_DIR}/home/Example Folder/two.bookmark.md\" ]]\n}\n\n@test \"'bookmark <url>' with 2 existing bookmarks at notebook root displays prompt.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --filename one\n\n    \"${_NB}\" copy \"one.bookmark.md\" \"example.md\"\n\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --filename two <<< \"y${_NEWLINE}\"\n\n    cat <<HEREDOC | \"${_NB}\" add --filename \"three.bookmark.md\"\n# Example Domain\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Comment\n\n<${_BOOKMARK_URL:-}>\n\n## Related\n\n- <${_BOOKMARK_URL:-}>\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n\n    declare _before_files=()\n    _before_files=($(ls \"${NB_DIR}/home/\"))\n\n    printf \"\\${_BOOKMARK_URL}:    '%s'\\\\n\"  \"${_BOOKMARK_URL:-}\"\n    printf \"\\${_before_files[*]}: '%s'\\\\n\"  \"${_before_files[*]:-}\"\n\n    [[        \"${#_before_files[@]}\" -eq 4        ]]\n    [[    -f  \"${NB_DIR}/home/example.md\"         ]]\n    [[    -f  \"${NB_DIR}/home/one.bookmark.md\"    ]]\n    [[    -f  \"${NB_DIR}/home/two.bookmark.md\"    ]]\n    [[    -f  \"${NB_DIR}/home/three.bookmark.md\"  ]]\n    [[ !  -f  \"${NB_DIR}/home/four.bookmark.md\"   ]]\n\n    diff                                        \\\n      <(cat \"${NB_DIR}/home/one.bookmark.md\")   \\\n      <(cat <<HEREDOC\n# Example Domain\n\n<${_BOOKMARK_URL:-}>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n      )\n\n    diff                                        \\\n      <(cat \"${NB_DIR}/home/example.md\")        \\\n      <(cat <<HEREDOC\n# Example Domain\n\n<${_BOOKMARK_URL:-}>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n      )\n\n    diff                                        \\\n      <(cat \"${NB_DIR}/home/two.bookmark.md\")   \\\n      <(cat <<HEREDOC\n# Example Domain\n\n<${_BOOKMARK_URL:-}>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n      )\n\n    diff                                        \\\n      <(cat \"${NB_DIR}/home/three.bookmark.md\") \\\n      <(cat <<HEREDOC\n# Example Domain\n\n<https://example.com>\n\n## Description\n\nExample description.\n\n## Comment\n\n<${_BOOKMARK_URL:-}>\n\n## Related\n\n- <${_BOOKMARK_URL:-}>\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n      )\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --filename four <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq  0  ]]\n  [[ \"${#lines[@]}\" -eq  6  ]]\n\n  [[ \"${lines[0]}\"  =~   \\\n2\\ bookmarks\\ for\\ this\\ URL\\ exist\\ in\\ this\\ folder:              ]]\n  [[ \"${lines[1]}\"  =~   \\\n[^-]-----------------------------------------------[^-]             ]]\n  [[ \"${lines[2]}\"  =~   \\\n.*[.*1.*].*\\ 🔖\\ .*one.bookmark.md.*\\ \\\"Example\\ Domain\\\"           ]]\n  [[ \"${lines[3]}\"  =~   \\\n.*[.*3.*].*\\ 🔖\\ .*two.bookmark.md.*\\ \\\"Example\\ Domain\\\"           ]]\n  [[ \"${lines[4]}\"  =~   \\\n[^-]------------------------------[^-]                              ]]\n  [[ \"${lines[5]}\"  =~   \\\nAdded:\\ .*[.*5.*].*\\ 🔖\\ .*four.bookmark.md.*\\ \\\"Example\\ Domain\\\"  ]]\n\n  declare _after_files=()\n  _after_files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_after_files[*]}: '%s'\\\\n\"  \"${_after_files[*]:-}\"\n\n  [[        \"${#_after_files[@]}\" -eq 5         ]]\n  [[    -f  \"${NB_DIR}/home/example.md\"         ]]\n  [[    -f  \"${NB_DIR}/home/one.bookmark.md\"    ]]\n  [[    -f  \"${NB_DIR}/home/two.bookmark.md\"    ]]\n  [[    -f  \"${NB_DIR}/home/three.bookmark.md\"  ]]\n  [[    -f  \"${NB_DIR}/home/four.bookmark.md\"   ]]\n}\n\n@test \"'bookmark <url>' with 1 existing bookmark at notebook root displays prompt.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --filename one\n\n    declare _before_files=()\n    _before_files=($(ls \"${NB_DIR}/home/\"))\n\n    printf \"\\${_BOOKMARK_URL}:      '%s'\\\\n\"  \"${_BOOKMARK_URL:-}\"\n    printf \"\\${_before_files[*]}: '%s'\\\\n\"  \"${_before_files[*]:-}\"\n\n    [[        \"${#_before_files[@]}\" -eq 1      ]]\n    [[    -f  \"${NB_DIR}/home/one.bookmark.md\"  ]]\n    [[ !  -f  \"${NB_DIR}/home/two.bookmark.md\"  ]]\n\n    diff                                        \\\n      <(cat \"${NB_DIR}/home/one.bookmark.md\")   \\\n      <(cat <<HEREDOC\n# Example Domain\n\n<${_BOOKMARK_URL:-}>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n      )\n\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --filename two <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq  0  ]]\n  [[ \"${#lines[@]}\" -eq  5  ]]\n\n  [[ \"${lines[0]}\"  =~   \\\n1\\ bookmark\\ for\\ this\\ URL\\ exists\\ in\\ this\\ folder:            ]]\n  [[ \"${lines[1]}\"  =~   \\\n[^-]----------------------------------------------[^-]            ]]\n  [[ \"${lines[2]}\"  =~   \\\n.*[.*1.*].*\\ 🔖\\ .*one.bookmark.md.*\\ \\\"Example\\ Domain\\\"         ]]\n  [[ \"${lines[3]}\"  =~   \\\n[^-]------------------------------[^-]                            ]]\n  [[ \"${lines[4]}\"  =~   \\\nAdded:\\ .*[.*2.*].*\\ 🔖\\ .*two.bookmark.md.*\\ \\\"Example\\ Domain\\\" ]]\n\n  declare _after_files=()\n  _after_files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_after_files[*]}: '%s'\\\\n\"  \"${_after_files[*]:-}\"\n\n  [[        \"${#_after_files[@]}\" -eq 2       ]]\n  [[    -f  \"${NB_DIR}/home/one.bookmark.md\"  ]]\n  [[    -f  \"${NB_DIR}/home/two.bookmark.md\"  ]]\n}\n\n# `nb <url>` ##################################################################\n\n@test \"'nb <url1> <url2>' with --tags, --filename, and --related options creates 2 new bookmarks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\"                    \\\n    \"${_BOOKMARK_URL}\"            \\\n    \"${_BOOKMARK_OG_URL}\"         \\\n    --tags tag1,tag2              \\\n    --filename \"example\"          \\\n    --related http://example.org  \\\n    --related sample:123          \\\n    --related \"[[demo:456]]\"      \\\n    --related \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark files with content:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 2 ]]\n\n  [[ -f \"${NB_DIR}/home/example.bookmark.md\"    ]]\n  [[ -f \"${NB_DIR}/home/example-1.bookmark.md\"  ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example-1.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example OG Title\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com-og.html>\n\n## Description\n\nExample OG description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  printf \"ls \\\"\\${NB_DIR}/home\\\": '%s'\" \"$(ls \"${NB_DIR}/home\")\"\n  printf \"cat \\\"\\${NB_DIR}/home/.index\\\": '%s'\" \"$(cat \"${NB_DIR}/home/.index\")\"\n\n  diff                        \\\n    <(ls -r \"${NB_DIR}/home\") \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example.bookmark.md    ]]\n  [[ \"${lines[1]}\" =~ Added:\\ .*[.*2.*].*\\ .*example-1.bookmark.md  ]]\n}\n\n@test \"'nb <url1> <url2> <url3>' with --tags, --filename, and --related options creates 3 new bookmarks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\"                    \\\n    \"${_BOOKMARK_URL}\"            \\\n    \"${_BOOKMARK_OG_URL}\"         \\\n    \"${_BOOKMARK_TITLES_URL}\"     \\\n    --tags tag1,tag2              \\\n    --filename \"example\"          \\\n    --related http://example.org  \\\n    --related sample:123          \\\n    --related \"[[demo:456]]\"      \\\n    --related \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark files with content:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 3 ]]\n\n  [[ -f \"${NB_DIR}/home/example.bookmark.md\"    ]]\n  [[ -f \"${NB_DIR}/home/example-1.bookmark.md\"  ]]\n  [[ -f \"${NB_DIR}/home/example-2.bookmark.md\"  ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  diff                                            \\\n    <(cat \"${NB_DIR}/home/example-1.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example OG Title\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com-og.html>\n\n## Description\n\nExample OG description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  diff                                            \\\n    <(cat \"${NB_DIR}/home/example-2.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Title One\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com-titles.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  printf \"ls -t -r \\\"\\${NB_DIR}/home\\\": '%s'\" \"$(ls -t -r \"${NB_DIR}/home\")\"\n  printf \"cat \\\"\\${NB_DIR}/home/.index\\\": '%s'\" \"$(cat \"${NB_DIR}/home/.index\")\"\n\n  diff                            \\\n    <(ls -t -r \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example.bookmark.md    ]]\n  [[ \"${lines[1]}\" =~ Added:\\ .*[.*2.*].*\\ .*example-1.bookmark.md  ]]\n  [[ \"${lines[2]}\" =~ Added:\\ .*[.*3.*].*\\ .*example-2.bookmark.md  ]]\n}\n\n@test \"'nb <url>' with --tags, --filename, and --related options creates new bookmark.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\"                    \\\n    \"${_BOOKMARK_URL}\"            \\\n    --tags tag1,tag2              \\\n    --filename \"example\"          \\\n    --related http://example.org  \\\n    --related sample:123          \\\n    --related \"[[demo:456]]\"      \\\n    --related \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  [[ -f \"${NB_DIR}/home/example.bookmark.md\" ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example.bookmark.md ]]\n}\n\n@test \"'nb <notebook>: <url>' with --tags, --filename, and --related options creates new bookmark.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\"                    \\\n    \"Example Notebook:\"           \\\n    \"${_BOOKMARK_URL}\"            \\\n    --tags tag1,tag2              \\\n    --filename \"example\"          \\\n    --related http://example.org  \\\n    --related sample:123          \\\n    --related \"[[demo:456]]\"      \\\n    --related \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  [[ -f \"${NB_DIR}/Example Notebook/example.bookmark.md\"    ]]\n\n  diff                                                      \\\n    <(cat \"${NB_DIR}/Example Notebook/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                      \\\n    <(ls \"${NB_DIR}/Example Notebook\")      \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*Example\\ Notebook:1.*].*\\ .*example.bookmark.md ]]\n}\n\n\n@test \"'nb <notebook>: <url>' with no options creates new bookmark.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\"                    \\\n    \"Example Notebook:\"           \\\n    \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  _files=($(ls \"${NB_DIR}/Example Notebook/\"))\n\n  [[ \"${#_files[@]}\" -eq 1    ]]\n\n  [[ -f \"${NB_DIR}/Example Notebook/${_files[0]}\"     ]]\n\n  diff                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/${_files[0]}\")  \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                      \\\n    <(ls \"${NB_DIR}/Example Notebook\")      \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*Example\\ Notebook:1.*].*\\ .*.bookmark.md ]]\n}\n\n# `add bookmark` ##############################################################\n\n@test \"'add bookmark' with --tags, --filename, and --related options creates new bookmark.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\" add bookmark       \\\n    \"${_BOOKMARK_URL}\"            \\\n    --tags tag1,tag2              \\\n    --filename \"example\"          \\\n    --related http://example.org  \\\n    --related sample:123          \\\n    --related \"[[demo:456]]\"      \\\n    --related \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  [[ -f \"${NB_DIR}/home/example.bookmark.md\" ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example.bookmark.md ]]\n}\n\n# --no-request ################################################################\n\n@test \"'bookmark --no-request' creates bookmark without requesting content.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --no-request\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note with bookmark filename\n  [[ \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md ]]\n\n  # Creates new note file with content\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  diff                                                                            \\\n    <(printf \"<file://%s/fixtures/example.com.html>\\\\n\" \"${NB_TEST_BASE_PATH}\")   \\\n    <(cat \"${NB_DIR}/home/${_filename}\")\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# no argument #################################################################\n\n@test \"'bookmark' with no argument exits with 0, prints message, and lists.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Bookmark One.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    \"${_NB}\" add \"Bookmark Two.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n  }\n\n  run \"${_NB}\" bookmark\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # exits with status 0\n\n  [[ \"${status}\" -eq 0          ]]\n\n  # does not create new file\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 2    ]]\n\n  # does not create git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q -v '\\[nb\\] Add'\n\n  # prints output\n\n  [[ \"${lines[0]}\" =~ ^Add:\\ .*nb\\ \\<url\\>.*\\ Help:\\ .*nb\\ help\\ bookmark ]]\n  [[ \"${lines[1]}\" =~ [^-]------------------------------------[^-]        ]]\n}\n\n@test \"'<notebook>:bookmark' with no argument exits with 0, prints message, and lists with selector in header.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add                                  \\\n      \"Example Notebook:Bookmark One.bookmark.md\" \\\n      -c \"<${_BOOKMARK_URL}>\"\n\n    \"${_NB}\" add                                  \\\n      \"Example Notebook:Bookmark Two.bookmark.md\" \\\n      -c \"<${_BOOKMARK_URL}>\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:bookmark\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # exits with status 0\n\n  [[ \"${status}\" -eq 0      ]]\n\n  # does not create new file\n\n  [[ -z \"$(ls \"${NB_DIR}/home/\")\" ]]\n\n  # does not create git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q -v '\\[nb\\] Add'\n\n  # prints output\n\n  [[ \"${lines[0]}\" =~ \\\n        ^Add:\\ .*nb\\ Example\\\\\\ Notebook:\\ \\<url\\>.*\\ Help:\\ .*nb\\ help\\ bookmark ]]\n  [[ \"${lines[1]}\" =~ \\\n        [^-]-------------------------------------------------------[^-]           ]]\n}\n\n# --tags option ###############################################################\n\n@test \"'bookmark' with --tags and no argument exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --tags --filename \"example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # Does not create new bookmark file:\n\n  [[ ! -f \"${NB_DIR}/home/example.bookmark.md\" ]]\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ !.*\\ .*--tags.*\\ requires\\ a\\ valid\\ argument. ]]\n}\n\n@test \"'bookmark' with --tags option creates new bookmark with tags.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --tags tag1,tag2 --filename \"example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  [[ -f \"${NB_DIR}/home/example.bookmark.md\" ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example.bookmark.md ]]\n}\n\n@test \"'bookmark' with --tags option and hashtags creates new bookmark with tags.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark     \\\n    \"${_BOOKMARK_URL}\"      \\\n    --tags '#tag1','#tag2'  \\\n    -c \"Example comment.\"   \\\n    --filename \"example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  [[ -f \"${NB_DIR}/home/example.bookmark.md\" ]]\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Comment\n\nExample comment.\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*1.*].*\\ .*example.bookmark.md ]]\n}\n\n# <url> or <list option...> argument ##########################################\n\n@test \"'bookmark <query>' exits with 0 and displays a list of bookmarks with titles.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nline example\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n      --title \"Example Bookmark Title\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" bookmark example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${lines[0]}\" =~ Example\\ Bookmark\\ Title  ]] && [[ \"${lines[0]}\" =~ 4 ]]\n  [[ \"${#lines[@]}\" == \"1\"                      ]]\n}\n\n@test \"'bookmark --sort' exits with 0 and displays a sorted list of bookmarks.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n      --title \"Example Bookmark Title\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" bookmark --sort\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${lines[0]}\" =~ second.bookmark.md        ]] && [[ \"${lines[0]}\" =~ 2 ]]\n  [[ \"${lines[1]}\" =~ Example\\ Bookmark\\ Title  ]] && [[ \"${lines[1]}\" =~ 4 ]]\n}\n\n@test \"'bookmark -n <num>' exits with 0 and displays limited list.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n      --title \"Example Bookmark Title\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" bookmark -n 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${lines[0]}\" =~ second.bookmark.md      ]] && [[ \"${lines[0]}\" =~ 2 ]]\n  [[ \"${lines[1]}\" == '1 omitted. 2 total.'   ]]\n}\n\n@test \"'bookmark' with valid <url> argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0        ]]\n\n  # Creates new note with bookmark filename\n  [[ \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md ]]\n\n  # Creates new note file with content\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark' with pdf <url> argument creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"file://${NB_TEST_BASE_PATH}/fixtures/example.pdf\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note with bookmark filename\n  [[ \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md ]]\n\n  # Creates new note file with content\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  _bookmark_content=\"<file://${NB_TEST_BASE_PATH}/fixtures/example.pdf>\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark' with invalid <url> argument creates new bookmark without downloading.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark 'http://invalid-url'\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0        ]]\n\n  # Creates new note with bookmark filename\n  [[ \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md ]]\n\n  # Creates new note file with content\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  _bookmark_content=\"# (invalid-url)\n\n<http://invalid-url>\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  diff <(cat \"${NB_DIR}/home/${_filename}\") <(printf \"%s\\\\n\" \"${_bookmark_content}\")\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints error message\n  _message=\"${_ERROR_PREFIX} Unable to download page at $(_color_primary \"http://invalid-url\")\"\n  [[ \"${lines[0]}\" == \"${_message}\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# --comment option ############################################################\n\n@test \"'bookmark' with --comment option creates new note with comment.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --comment \"New comment.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0        ]]\n\n  # Creates new note file with content\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Comment\n\nNew comment.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# --quote option ##############################################################\n\n@test \"'bookmark' with --quote option creates new note with quote.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --quote \"Quote line 1.\n\nQuote line 2.\"\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note file with content\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Quote\n\n> Quote line 1.\n>\n> Quote line 2.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  _file_content=\"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  printf \"\\${_file_content}: '%s'\\\\n\" \"${_file_content}\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  diff -u <(echo \"${_file_content}\") <(echo \"${_bookmark_content}\")\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# --save-source option ########################################################\n\n@test \"'bookmark --save-source' creates new note with HTML content.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --save-source\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note with bookmark filename\n  [[ \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md ]]\n\n  # Creates new note file with content\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\n\n## Source\n\n\\`\\`\\`html\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.html\")\n\\`\\`\\`\"\n\n  # TODO: vim highlighting bug \\`\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# --skip-content option #######################################################\n\n@test \"'bookmark' with --skip-content option creates new note with no page content.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --skip-content\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note file with content\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# --title option ##############################################################\n\n@test \"'bookmark' with --title option creates new note with title.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --title \"New Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note file with content\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  _bookmark_content=\"\\\n# New Title\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# New Title' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# --related option ############################################################\n\n@test \"'bookmark' with invalid --related <url> argument exits with 1.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark --related\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 1\n  [[ ${status} -eq 1 ]]\n\n  # Does not create note file\n  _files=($(ls \"${NB_DIR}/home/\"))\n  [[ \"${#_files[@]}\" -eq 0 ]]\n\n  # Does not create git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Add'\n\n  # Prints help information\n  [[ \"${lines[0]}\" =~ requires\\ a\\ valid\\ argument ]]\n}\n\n@test \"'bookmark' with one --related URL creates new note.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --related https://example.net\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note file with content\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <https://example.net>\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark' with three --related URLs creates new note.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" \\\n    --related https://example.net \\\n    --related https://example.org \\\n    --related https://example.example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note file with content\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <https://example.net>\n- <https://example.org>\n- <https://example.example>\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark' with --related URLs and selectors creates new note.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"  \\\n    --related https://example.net           \\\n    --related example:123                   \\\n    --related https://example.example       \\\n    --related \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Creates new note file with content\n  _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <https://example.net>\n- [[example:123]]\n- <https://example.example>\n- [[Example Title]]\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" == \"${_bookmark_content}\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# --encrypt option ############################################################\n\n@test \"'bookmark --encrypt' with content argument creates a new .enc bookmark.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --encrypt --password=example\n\n  [[ ${status} -eq 0 ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1                                                      ]]\n  [[ \"${_files[0]}\" =~ enc$                                                     ]]\n  [[ \"$(file \"${NB_DIR}/home/${_files[0]}\" | cut -d: -f2)\" =~ encrypted|openssl ]]\n}\n\n@test \"'bookmark --encrypt --password' without argument exits with 1.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --encrypt --password\n\n  [[ ${status} -eq 1        ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0  ]]\n}\n\n# --filename option ###########################################################\n\n@test \"'add' with --filename option exits with 0, creates new note, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --filename example.bookmark.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0 ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  [[ -n \"$(ls example.bookmark.md)\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with --filename option uses specified extension.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --filename example.org\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0 ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  [[ -n \"$(ls example.org)\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'add' with extension-less --filename option uses default extension.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --filename example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0 ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  [[ -n \"$(ls example.bookmark.md)\" ]]\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# `bookmark <notebook>:` ###########################################################\n\n@test \"'nb bookmark <notebook>: <url>' with --tags, --filename, and --related options creates new bookmark.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\"                    \\\n    bookmark                      \\\n    \"Example Notebook:\"           \\\n    \"${_BOOKMARK_URL}\"            \\\n    --tags tag1,tag2              \\\n    --filename \"example\"          \\\n    --related http://example.org  \\\n    --related sample:123          \\\n    --related \"[[demo:456]]\"      \\\n    --related \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  [[ -f \"${NB_DIR}/Example Notebook/example.bookmark.md\"    ]]\n\n  diff                                                      \\\n    <(cat \"${NB_DIR}/Example Notebook/example.bookmark.md\") \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Related\n\n- <http://example.org>\n- [[sample:123]]\n- [[demo:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1 #tag2\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                      \\\n    <(ls \"${NB_DIR}/Example Notebook\")      \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*Example\\ Notebook:1.*].*\\ .*example.bookmark.md ]]\n}\n\n\n@test \"'nb bookmark <notebook>: <url>' with no options creates new bookmark.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\"                    \\\n    bookmark                      \\\n    \"Example Notebook:\"           \\\n    \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  _files=($(ls \"${NB_DIR}/Example Notebook/\"))\n\n  [[ \"${#_files[@]}\" -eq 1    ]]\n\n  [[ -f \"${NB_DIR}/Example Notebook/${_files[0]}\"     ]]\n\n  diff                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/${_files[0]}\")  \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                      \\\n    <(ls \"${NB_DIR}/Example Notebook\")      \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Added:\\ .*[.*Example\\ Notebook:1.*].*\\ .*.bookmark.md ]]\n}\n\n@test \"'nb bookmark <notebook>:<folder>/ <url>' with no options creates new bookmark.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"demo\"\n    \"${_NB}\" notebooks add \"sample\"\n  }\n\n  run \"${_NB}\"                          \\\n    bookmark                            \\\n    \"Example Notebook:Example Folder/\"  \\\n    \"${_BOOKMARK_URL}\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates new bookmark file with content:\n\n  _files=($(ls \"${NB_DIR}/Example Notebook/Example Folder/\"))\n\n  [[ \"${#_files[@]}\" -eq 1    ]]\n\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/${_files[0]}\"     ]]\n\n  diff                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/${_files[0]}\")  \\\n    <(cat <<HEREDOC\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"                 ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/.index\"  ]]\n\n  diff                                      \\\n    <(ls \"${NB_DIR}/Example Notebook\")      \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  diff                                                \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Folder\") \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Creating\\ new\\ folder:\\ .*Example\\ Notebook:Example\\ Folder/          ]]\n  [[ \"${lines[1]}\" =~ Added:\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*.bookmark.md ]]\n}\n\n# `bookmark delete` ###########################################################\n\n@test \"'bookmark delete' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n    [[ -e \"${NB_DIR}/home/${_filename}\" ]]\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n  }\n\n  run \"${_NB}\" delete 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Deletes note file\n  [[ ! -e \"${NB_DIR}/home/${_filename}\" ]]\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[ \"${_original_index}\" != \"$(cat \"${NB_DIR}/home/.index\")\"     ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Deleted:                  ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# `bookmark edit` #############################################################\n\n@test \"'bookmark edit' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n    _original=\"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  }\n\n  run \"${_NB}\" bookmark edit 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Updates file\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/${_filename}\")  \\\n    <(printf \"%s\\\\n\" \"${_original}\")      &&\n      return 1\n\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output\n  [[ \"${output}\" =~ Updated:                  ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# `bookmark url` ##############################################################\n\n@test \"'bookmark url' with invalid <id> prints error.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n  }\n\n  run \"${_NB}\" bookmark url 99\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  1           ]]\n  [[ \"${output}\" =~   Not\\ found  ]]\n}\n\n@test \"'bookmark url' prints bookmark url.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n  }\n\n  run \"${_NB}\" bookmark url 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"${_BOOKMARK_URL}\"  ]]\n}\n\n@test \"'bookmark url' with multiple URLs prints first url in <>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add example.bookmark.md \\\n      --content \"\\\nhttps://example.com\n<${_BOOKMARK_URL}>\n<https://example.com>\"\n  }\n\n  run \"${_NB}\" bookmark url 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"${_BOOKMARK_URL}\"  ]]\n}\n\n# encrypted ###################################################################\n\n@test \"'bookmark url' with encrypted bookmark prints bookmark URL.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --encrypt --password=example\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  run \"${_NB}\" bookmark url 1 --password=example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"${_BOOKMARK_URL}\"  ]]\n}\n\n# `bookmark list` #############################################################\n\n@test \"'bookmark list' exits with 0 and displays a list of bookmarks with titles.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n      --title \"Example Bookmark Title\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" bookmark list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${lines[0]}\" =~ Example\\ Bookmark\\ Title  ]] && [[ \"${lines[0]}\" =~ 4 ]]\n  [[ \"${lines[1]}\" =~ second.bookmark.md        ]] && [[ \"${lines[1]}\" =~ 2 ]]\n}\n\n@test \"'bookmark list' with no bookmarks prints message.\" {\n  {\n    \"${_NB}\" init\n    _expected=\"0 bookmarks.\n\nAdd a bookmark:\n  $(_color_primary 'nb <url>')\nHelp information:\n  $(_color_primary 'nb help bookmark')\"\n  }\n\n  run \"${_NB}\" bookmark list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${_expected}: '%s'\\\\n\" \"${_expected}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${_expected}\" == \"${output}\"  ]]\n}\n\n# `bookmark list --sort` ######################################################\n\n@test \"'bookmark list --sort' exits with 0 and displays a sorted list of bookmarks.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n      --title \"Example Bookmark Title\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" bookmark list --sort\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${lines[0]}\" =~ second.bookmark.md        ]] && [[ \"${lines[0]}\" =~ 2 ]]\n  [[ \"${lines[1]}\" =~ Example\\ Bookmark\\ Title  ]] && [[ \"${lines[1]}\" =~ 4 ]]\n}\n\n# help ########################################################################\n\n@test \"'help bookmark' exits with status 0 and prints.\" {\n  run \"${_NB}\" help bookmark\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ Usage.*:      ]]\n  [[ \"${lines[1]}\" =~  nb\\ bookmark ]]\n}\n\n@test \"'bookmark help' exits with status 0 and prints.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" bookmark help\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ Usage.*:      ]]\n  [[ \"${lines[1]}\" =~  nb\\ bookmark ]]\n}\n"
  },
  {
    "path": "test/bookmarks.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `bookmarks` #################################################################\n\n@test \"'bookmarks' exits with 0 and displays a list of bookmarks with titles.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n      --title \"Example Bookmark Title\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" bookmarks\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${lines[0]}\" =~ Add                       ]] && [[ \"${lines[0]}\" =~ Help  ]]\n  [[ \"${lines[1]}\" =~ ---                       ]]\n  [[ \"${lines[2]}\" =~ Example\\ Bookmark\\ Title  ]] && [[ \"${lines[2]}\" =~ 4     ]]\n  [[ \"${lines[3]}\" =~ second.bookmark.md        ]] && [[ \"${lines[3]}\" =~ 2     ]]\n}\n\n# `bookmarks --sort` ##########################################################\n\n@test \"'bookmarks --sort' exits with 0 and displays a sorted list of bookmarks.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n      --title \"Example Bookmark Title\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" bookmarks --sort\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${lines[0]}\" =~ second.bookmark.md        ]] && [[ \"${lines[0]}\" =~ 2 ]]\n  [[ \"${lines[1]}\" =~ Example\\ Bookmark\\ Title  ]] && [[ \"${lines[1]}\" =~ 4 ]]\n}\n"
  },
  {
    "path": "test/browse-add.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# HTML <title> ################################################################\n\n@test \"'browse add <folder>/' with local notebook sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse add \"Example Folder/\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ add\\ local:Example\\\\\\ Folder/\\</title\\>          ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n@test \"'browse add <notebook>:<folder>/<filename>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add \"Example Notebook:Example Folder\" --type \"folder\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse add \"Example Notebook:Example Folder/Example File.md\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ add\\ Example\\\\\\ Notebook:Example\\\\\\ Folder/Example\\\\\\ File.md\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n@test \"'browse add <folder>/' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse add \"Example Folder/\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ add\\ home:Example\\\\\\ Folder/\\</title\\>           ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n@test \"'browse add <notebook>:' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse add \"Example Notebook:\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ add\\ Example\\\\\\ Notebook:\\</title\\>              ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n@test \"'browse add' sets HTML <title> to CLI command with no selector.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse add --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ add\\ home:\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n# local #######################################################################\n\n@test \"POST to --add <folder-name>/<filename> URL with local notebook creates folder and note and redirects.\"  {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data                                                                \\\n\"content=Example%20line%20one.%0D%0A%0D%0AExample%20line%20two.&--title=Example%20Title\"  \\\n\"http://localhost:6789/local:Example%20Folder/Example%20File.md?--add&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Creates file:\n\n  ls -la \"${_TMP_DIR}/Local Notebook/\"\n\n  [[ -f \"${_TMP_DIR}/Local Notebook/Example Folder/Example File.md\"     ]]\n\n  diff                                                                  \\\n    <(cat \"${_TMP_DIR}/Local Notebook/Example Folder/Example File.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample line one.\n\nExample line two.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${_TMP_DIR}/Local Notebook\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${#lines[@]}\" -eq 5                                                     ]]\n\n  declare _expected_param_pattern=\"--limit=30\\&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found                                  ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                             ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                                          ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                                           ]]\n  [[ \"${lines[4]}\"  =~  \\\nLocation:\\ \\/\\/localhost:6789\\/Example\\ Folder/1\\?${_expected_param_pattern}  ]]\n}\n\n@test \"GET to --add URL with local notebook renders form.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D -           \\\n\"http://localhost:6789/local:?--add&--example&-x&abcdefg&--sample=demo-value&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0    ]]\n\n  # Prints output:\n\n  [[    \"${lines[0]}\"  =~ HTTP/1.0\\ 200\\ OK                               ]]\n  [[    \"${lines[1]}\"  =~ Date:\\ .*                                       ]]\n  [[    \"${lines[2]}\"  =~ Expires:\\ .*                                    ]]\n  [[    \"${lines[3]}\"  =~ Server:\\ nb                                     ]]\n  [[    \"${lines[4]}\"  =~ Content-Type:\\ text/html                        ]]\n\n  [[    \"${output}\"    =~ \\\naction=\\\"/local:\\?--add\\&--columns=.*\\&--limit=.*\\&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook ]]\n\n  [[    \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"--example\\\"\\>  ]]\n  [[    \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"-x\\\"\\>         ]]\n  [[    \"${output}\"    =~ \\\n\\<input\\ type=\\\"hidden\\\"\\ name=\\\"--sample\\\"\\ value=\\\"demo-value\\\"\\>       ]]\n\n  [[ !  \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"abcdefg\\\"\\>    ]]\n}\n\n# POST ########################################################################\n\n@test \"POST to --add <folder-name>/<folder-name>/<filename> URL with existing file creates another with incremented filename.\"  {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                      \\\n      \"Example Folder/Sample Folder/Example File.md\"  \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\" ]]\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data                                                                \\\n\"content=Example%20line%20one.%0D%0A%0D%0AExample%20line%20two.&--title=Example%20Title\"  \\\n\"http://localhost:6789/home:Example%20Folder/Sample%20Folder/Example%20File.md?--add\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Creates file:\n\n  ls -la \"${NB_DIR}/home/\"\n\n  [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File-1.md\"     ]]\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File-1.md\"\n\n  diff                                                                      \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File-1.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample line one.\n\nExample line two.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${#lines[@]}\" -eq 5                                                   ]]\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found                                ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                           ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                                        ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                                         ]]\n  [[ \"${lines[4]}\"  =~  \\\nLocation:\\ \\/\\/localhost:6789\\/Example\\ Folder/Sample\\ Folder/2\\?--limit=30 ]]\n}\n\n@test \"POST to --add <folder-name>/<folder-name> (no slash) URL creates folder and file named 'Sample Folder' and redirects.\"  {\n  {\n    \"${_NB}\" init\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data                                                                \\\n\"content=Example%20line%20one.%0D%0A%0D%0AExample%20line%20two.&--title=Example%20Title\"  \\\n\"http://localhost:6789/home:Example%20Folder/Sample%20Folder?--add\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0  ]]\n\n  # Creates file:\n\n  [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder\"     ]]\n\n  diff                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample line one.\n\nExample line two.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${#lines[@]}\" -eq 5                                     ]]\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found                  ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                             ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                          ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                           ]]\n  [[ \"${lines[4]}\"  =~  \\\nLocation:\\ \\/\\/localhost:6789\\/Example\\ Folder/1\\?--limit=30  ]]\n}\n\n@test \"POST to --add <folder-name>/<folder-name>/ (slash) URL creates folders and note and redirects.\"  {\n  {\n    \"${_NB}\" init\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data                                                                \\\n\"content=Example%20line%20one.%0D%0A%0D%0AExample%20line%20two.&--title=Example%20Title\"  \\\n\"http://localhost:6789/home:Example%20Folder/Sample%20Folder/?--add\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0  ]]\n\n  # Creates file:\n\n  _files=($(ls \"${NB_DIR}/home/Example Folder/Sample Folder/\"))\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/${_files[0]}\"        ]]\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/${_files[0]}\")     \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample line one.\n\nExample line two.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${#lines[@]}\" -eq 5                                                   ]]\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found                                ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                           ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                                        ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                                         ]]\n  [[ \"${lines[4]}\"  =~  \\\nLocation:\\ \\/\\/localhost:6789\\/Example\\ Folder/Sample\\ Folder/1\\?--limit=30 ]]\n}\n\n@test \"POST to --add <folder-name>/<folder-name>/<filename> URL creates folders and note and redirects.\"  {\n  {\n    \"${_NB}\" init\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data                                                                \\\n\"content=Example%20line%20one.%0D%0A%0D%0AExample%20line%20two.&--title=Example%20Title\"  \\\n\"http://localhost:6789/home:Example%20Folder/Sample%20Folder/Example%20File.md?--add\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Creates file:\n\n  ls -la \"${NB_DIR}/home/\"\n\n  [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\"     ]]\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample line one.\n\nExample line two.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${#lines[@]}\" -eq 5                                                   ]]\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found                                ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                           ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                                        ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                                         ]]\n  [[ \"${lines[4]}\"  =~  \\\nLocation:\\ \\/\\/localhost:6789\\/Example\\ Folder/Sample\\ Folder/1\\?--limit=30 ]]\n}\n\n@test \"POST to --add <folder-name>/<filename> URL creates folder and note and redirects.\"  {\n  {\n    \"${_NB}\" init\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data                                                                \\\n\"content=Example%20line%20one.%0D%0A%0D%0AExample%20line%20two.&--title=Example%20Title\"  \\\n\"http://localhost:6789/home:Example%20Folder/Example%20File.md?--add\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Creates file:\n\n  ls -la \"${NB_DIR}/home/\"\n\n  [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\"     ]]\n\n  diff                                                      \\\n    <(cat \"${NB_DIR}/home/Example Folder/Example File.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample line one.\n\nExample line two.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${#lines[@]}\" -eq 5                                                             ]]\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found                                          ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                                     ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                                                  ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                                                   ]]\n  [[ \"${lines[4]}\"  =~  Location:\\ \\/\\/localhost:6789\\/Example\\ Folder/1\\?--limit=30  ]]\n}\n\n@test \"POST to --add <filename> URL creates note and redirects.\"  {\n  {\n    \"${_NB}\" init\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data                                                                \\\n\"content=Example%20line%20one.%0D%0A%0D%0AExample%20line%20two.&--title=Example%20Title\"  \\\n\"http://localhost:6789/home:Example%20File.md?--add\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Creates file:\n\n  ls -la \"${NB_DIR}/home/\"\n\n  [[ -f \"${NB_DIR}/home/Example File.md\"    ]]\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/home/Example File.md\") \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample line one.\n\nExample line two.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${#lines[@]}\" -eq 5                                             ]]\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found                          ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                     ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                                  ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                                   ]]\n  [[ \"${lines[4]}\"  =~  Location:\\ \\/\\/localhost:6789\\/1\\?--limit=30  ]]\n}\n\n# CLI #########################################################################\n\n@test \"'browse --add <notebook>:<item-selector>' renders the 'add' form with populated content and selector filename field.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse                                 \\\n    \"Example Notebook:Example Folder/Example File.md\" \\\n    --add --print                                     \\\n    --title     \"Example Title\"                       \\\n    --content   \"Example content.\"                    \\\n    --tags      tag1,tag2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                  ]]\n\n  [[    \"${output}\"  =~  ❯.*nb.*\\ .*·.*\\ .*Example\\ Notebook.*\\ .*:.*\\ .*1  ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/Example%20Notebook:?--columns=.*&--limit=.*\\\">Example Notebook</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\".*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"action=\\\"/Example%20Notebook:Example%20Folder/Example%20File.md?--add&--columns=.*&--limit=.*\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"add\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"rows=\\\".*\\\"># Example Title${_NEWLINE}${_NEWLINE}#tag1 #tag2${_NEWLINE}${_NEWLINE}Example content.${_NEWLINE}</textarea>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<input type=\\\"hidden\\\" name=\\\"--title\\\"\"\n}\n\n@test \"'browse --add <item-selector>' renders the 'add' form with populated content.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/Example\\ File.md --add --print  \\\n    --title     \"Example Title\"                                       \\\n    --content   \"Example content.\"                                    \\\n    --tags      tag1,tag2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                    ]]\n\n  [[    \"${output}\"  =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/home:?--columns=.*&--limit=.*\\\">home</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\".*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"action=\\\"/home:Example%20Folder/Example%20File.md?--add&--columns=.*&--limit=.*\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"add\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"rows=\\\".*\\\"># Example Title${_NEWLINE}${_NEWLINE}#tag1 #tag2${_NEWLINE}${_NEWLINE}Example content.${_NEWLINE}</textarea>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<input type=\\\"hidden\\\" name=\\\"--title\\\"\"\n}\n\n@test \"'browse --add <folder-selector>/<filename>' includes <folder-selector>/<filename> in form action.\" {\n  # TODO: review behavior\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/Example\\ File.md --add --print  \\\n    --title     \"Example Title\"                                       \\\n    --content   \"Example content.\"                                    \\\n    --tags      tag1,tag2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                    ]]\n\n  [[    \"${output}\"  =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/home:?--columns=.*&--limit=.*\\\">home</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\".*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"action=\\\"/home:Example%20Folder/Example%20File.md?--add&--columns=.*&--limit=.*\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"add\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"rows=\\\".*\\\"># Example Title${_NEWLINE}${_NEWLINE}#tag1 #tag2${_NEWLINE}${_NEWLINE}Example content.${_NEWLINE}</textarea>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<input type=\\\"hidden\\\" name=\\\"--title\\\"\"\n}\n\n@test \"'browse --add <folder-selector>/' includes add options as pre-filled content hidden form fields.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/Example\\ File.md --add --print  \\\n    --title     \"Example Title\"                                       \\\n    --content   \"Example content.\"                                    \\\n    --tags      tag1,tag2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                  ]]\n\n  [[    \"${output}\"  =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*Example\\ Folder ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/home:?--columns=.*&--limit=.*\\\">home</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\".*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"action=\\\"/home:Example%20Folder/Example%20File.md?--add&--columns=.*&--limit=.*\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"add\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"rows=\\\".*\\\"># Example Title${_NEWLINE}${_NEWLINE}#tag1 #tag2${_NEWLINE}${_NEWLINE}Example content.${_NEWLINE}</textarea>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<input type=\\\"hidden\\\" name=\\\"--title\\\"\"\n}\n\n@test \"'browse --add <selector>' opens the add page in the browser.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/ --add --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                    ]]\n\n  [[    \"${output}\"  =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/home:?--columns=.*&--limit=.*\\\">home</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\".*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"action=\\\"/home:Example%20Folder/?--add&--columns=.*&--limit=.*\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"add\\\">\"\n}\n\n# option parameters ###########################################################\n\n@test \"GET to --add URL with option parameters adds hidden form fields.\" {\n  {\n    \"${_NB}\" init\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:?--add&--example&-x&abcdefg&--sample=demo-value\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0    ]]\n\n  # Prints output:\n\n  [[    \"${lines[0]}\"  =~ HTTP/1.0\\ 200\\ OK                               ]]\n  [[    \"${lines[1]}\"  =~ Date:\\ .*                                       ]]\n  [[    \"${lines[2]}\"  =~ Expires:\\ .*                                    ]]\n  [[    \"${lines[3]}\"  =~ Server:\\ nb                                     ]]\n  [[    \"${lines[4]}\"  =~ Content-Type:\\ text/html                        ]]\n\n  [[    \"${output}\"    =~ action=\\\"/home:\\?--add                          ]]\n\n  [[    \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"--example\\\"\\>  ]]\n  [[    \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"-x\\\"\\>         ]]\n  [[    \"${output}\"    =~ \\\n\\<input\\ type=\\\"hidden\\\"\\ name=\\\"--sample\\\"\\ value=\\\"demo-value\\\"\\>       ]]\n\n  [[ !  \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"abcdefg\\\"\\>    ]]\n}\n\n# GET #########################################################################\n\n@test \"GET to --add URL with --columns parameter uses value for textarea, form URL parameters, and header links.\" {\n  {\n    \"${_NB}\" init\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:?--add&--columns=20\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                ]]\n\n  # Does not create file:\n\n  [[ -z \"$(ls \"${NB_DIR}/home/\")\"         ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1      ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"href=\\\"//localhost:6789/?--columns=20&--limit=30\\\"><span class=\\\"muted\\\">❯</span>nb</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\"32\\\">\"\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n    \"<form${_NEWLINE}.*${_NEWLINE}.*action=\\\"/home:\\?--add&--columns=.*&--limit=.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"add\\\">\"\n}\n\n@test \"GET to --add URL without --columns parameter uses default value for textarea.\" {\n  {\n    \"${_NB}\" init\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:?--add\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                ]]\n\n  # Does not create file:\n\n  [[ -z \"$(ls \"${NB_DIR}/home/\")\"         ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/home:?--columns=.*&--limit=.*\\\">home</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\"32\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"add\\\">\"\n}\n\n@test \"GET to --add URL prints form without creating note.\" {\n  {\n    \"${_NB}\" init\n\n    (ncat                                 \\\n      --exec \"${_NB} browse --respond\"    \\\n      --listen                            \\\n      --source-port \"6789\"                \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:?--add\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                ]]\n\n  # Does not create file:\n\n  [[ -z \"$(ls \"${NB_DIR}/home/\")\"         ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*\\+     ]]\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"<form${_NEWLINE}.*${_NEWLINE}.*action=\\\"/home:\\?--add\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"add\\\">\"\n}\n"
  },
  {
    "path": "test/browse-containers.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# escaping / HTML entities ####################################################\n\n@test \"'browse --container' renders filenames and titles with parentheses.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Filename (1).md\" --content \"Example content one.\"\n    \"${_NB}\" add  \"Example Filename (2).md\" --title   \"Example Title (2).\"\n  }\n\n  run \"${_NB}\" browse --container\n\n  declare _amp='\\&'\n\n  printf \"\\${_amp}:   '%s'\\\\n\" \"${_amp}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                                                   ]]\n\n  [[ !  \"${output}\"   =~  Example\\ Filename\\ \\(\\#40\\;1\\)\\#41\\;\\.md            ]]\n  [[    \"${output}\"   =~  Example\\ Filename\\ ${_amp}\\#40\\;1${_amp}\\#41\\;\\.md  ]]\n\n  [[ !  \"${output}\"   =~  Example\\ Title\\ \\(\\#40\\;2\\)\\#41\\;\\.                 ]]\n  [[    \"${output}\"   =~  Example\\ Title\\ ${_amp}\\#40\\;2${_amp}\\#41\\;\\.       ]]\n}\n\n# folderst first ##############################################################\n\n@test \"'NB_FOLDERS_FIRST=1 browse' prints folders first.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" folder add \"Folder One\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" folder add \"Folder Two\"\n\n    export NB_FOOTER=0\n    export NB_HEADER=0\n  }\n\n  run printf \"%s\\\\n\" \"$(\"${_NB}\" browse --container | awk '/<p class=\"item-list\">/,/<\\/p>/')\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 7 ]]\n\n  [[ \"${lines[0]}\" =~ \\<p\\ class=\\\"item-list\\\"\\>                                                ]]\n  [[ \"${lines[1]}\" =~ \\<a.*home:5.*📂\\ Folder\\ Two\\</a\\>\\<br\\>                                  ]]\n  [[ \"${lines[2]}\" =~ \\<a.*home:4.*File\\ Three.md\\ ·\\ \\\"Example\\ content\\ three.\\\"\\</a\\>\\<br\\>  ]]\n  [[ \"${lines[3]}\" =~ \\<a.*home:3.*File\\ Two.md\\ ·\\ \\\"Example\\ content\\ two.\\\"\\</a\\>\\<br\\>      ]]\n  [[ \"${lines[4]}\" =~ \\<a.*home:2.*📂\\ Folder\\ One\\</a\\>\\<br\\>                                  ]]\n  [[ \"${lines[5]}\" =~ \\<a.*home:1.*File\\ One.md\\ ·\\ \\\"Example\\ content\\ one.\\\"\\</a\\>\\<br\\>      ]]\n  [[ \"${lines[6]}\" =~ \\</p\\>                                                                    ]]\n\n  run printf \"%s\\\\n\" \"$(NB_FOLDERS_FIRST=1 \"${_NB}\" browse --container | awk '/<p class=\"item-list\">/,/<\\/p>/')\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 7 ]]\n\n  [[ \"${lines[0]}\" =~ \\<p\\ class=\\\"item-list\\\"\\>                                                ]]\n  [[ \"${lines[1]}\" =~ \\<a.*home:5.*📂\\ Folder\\ Two\\</a\\>\\<br\\>                                  ]]\n  [[ \"${lines[2]}\" =~ \\<a.*home:2.*📂\\ Folder\\ One\\</a\\>\\<br\\>                                  ]]\n  [[ \"${lines[3]}\" =~ \\<a.*home:4.*File\\ Three.md\\ ·\\ \\\"Example\\ content\\ three.\\\"\\</a\\>\\<br\\>  ]]\n  [[ \"${lines[4]}\" =~ \\<a.*home:3.*File\\ Two.md\\ ·\\ \\\"Example\\ content\\ two.\\\"\\</a\\>\\<br\\>      ]]\n  [[ \"${lines[5]}\" =~ \\<a.*home:1.*File\\ One.md\\ ·\\ \\\"Example\\ content\\ one.\\\"\\</a\\>\\<br\\>      ]]\n  [[ \"${lines[6]}\" =~ \\</p\\>                                                                    ]]\n}\n\n# todos #######################################################################\n\n@test \"'browse --container' displays marked-up checkboxes in todo titles.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example One.todo.md\" --content   \"# [x] Example todo one.\"\n    \"${_NB}\" add  \"Example Two.todo.md\" --content   \"# [ ] Example todo two.\"\n  }\n\n  run \"${_NB}\" browse --container\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a\\ rel=\\\"noopener\\ noreferrer\\\"\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"         ]]\n  [[    \"${output}\"   =~  \\\n--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\          ]]\n  [[    \"${output}\"   =~  \\\nmuted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>]\\</span\\>  ]]\n  [[    \"${output}\"   =~  \\\n\\</span\\>\\ \\✔️\\ \\ \\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>\\ \\</span\\>\\<span  ]]\n  [[    \"${output}\"   =~  \\\n\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Example\\ todo\\ two\\.\\</a\\>\\<br\\>                       ]]\n\n\n  [[    \"${output}\"   =~  \\\n\\<a\\ rel=\\\"noopener\\ noreferrer\\\"\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"         ]]\n  [[    \"${output}\"   =~  \\\n--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\          ]]\n  [[    \"${output}\"   =~  \\\nmuted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:1\\</span\\>\\<span\\ class=\\\"muted\\\"\\>]\\</span\\>  ]]\n  [[    \"${output}\"   =~  \\\n\\</span\\>\\ \\✅\\ \\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>x\\</span\\>\\<span\\   ]]\n  [[    \"${output}\"   =~  \\\n\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Example\\ todo\\ one\\.\\</a\\>\\<br\\>                       ]]\n}\n\n# notebook: selectors #########################################################\n\n@test \"'browse' includes notebook selectors for items in the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"Example Two.md\" --content \"Example content two.\"\n\n    \"${_NB}\" add \"Sample Folder/Sample One.md\" --content \"Sample content one.\"\n    \"${_NB}\" add \"Sample Folder/Sample Two.md\" --content \"Sample content two.\"\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:3\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:1\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n\n  run \"${_NB}\" browse Sample\\ Folder/ --print\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:Sample${_S}Folder/2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:Sample${_S}Folder/1\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n}\n\n@test \"'browse' includes notebook selectors for items in a selected notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example One.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"Example Notebook:Example Two.md\" --content \"Example content two.\"\n\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample One.md\" --content \"Sample content one.\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample Two.md\" --content \"Sample content two.\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:browse --print\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>Example${_S}Notebook:3\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>Example${_S}Notebook:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>Example${_S}Notebook:1\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n\n  run \"${_NB}\" browse Example\\ Notebook:Sample\\ Folder/ --print\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>Example${_S}Notebook:Sample${_S}Folder/2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>Example${_S}Notebook:Sample${_S}Folder/1\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n}\n\n@test \"'browse --query <query>' includes notebook selectors for results in a selected notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example One.md\" --content \"Example 123 content.\"\n    \"${_NB}\" add \"Example Notebook:Example Two.md\" --content \"Example content.\"\n\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample One.md\" --content \"Sample content.\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample Two.md\" --content \"Sample 123 content.\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:browse --query \"123\" --print\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>Example${_S}Notebook:1\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]                   ]]\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>Example${_S}Notebook:Sample${_S}Folder/2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n}\n\n# .index ######################################################################\n\n@test \"'browse' reconciles ancestor .index files with incomplete nested .index file.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${NB_DIR}/home/Example/Sample/Demo\"\n\n    printf \"# Title\" > \"${NB_DIR}/home/Example/Sample/Demo/File.md\"\n\n    touch \"${NB_DIR}/home/Example/Sample/Demo/.index\"\n\n    git -C \"${NB_DIR}/home\" add --all\n    git -C \"${NB_DIR}/home\" commit -am \"Example commit message.\"\n\n    [[ !  -e \"${NB_DIR}/home/Example/.index\"              ]]\n    [[ !  -e \"${NB_DIR}/home/Example/Sample/.index\"       ]]\n    [[    -e \"${NB_DIR}/home/Example/Sample/Demo/.index\"  ]]\n    [[    -e \"${NB_DIR}/home/Example/Sample/Demo/File.md\" ]]\n\n    git -C \"${NB_DIR}/home\" status\n\n    [[ -z \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse \"Example/Sample/Demo/\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${output}\"  =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:Example/Sample/Demo/1\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example/.index\")              \\\n    <(printf \"Sample\\\\n\")\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example/Sample/.index\")       \\\n    <(printf \"Demo\\\\n\")\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example/Sample/Demo/.index\")  \\\n    <(printf \"File.md\\\\n\")\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  git -C \"${NB_DIR}/home\" status\n  git -C \"${NB_DIR}/home\" log\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Reconcile Index'\n}\n\n@test \"'browse' reconciles root-level .index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    printf \"# Title Four\" > \"${NB_DIR}/home/File Four.md\"\n\n    \"${_NB}\" git -C \"${NB_DIR}/home\" add --all\n    \"${_NB}\" git -C \"${NB_DIR}/home\" commit -am \"Example commit message.\"\n\n    git -C \"${NB_DIR}/home\" status\n\n    [[ -z \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n\n    diff                              \\\n      <(cat \"${NB_DIR}/home/.index\")  \\\n      <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nHEREDOC\n)\n\n    [[  -e \"${NB_DIR}/home/File One.md\"    ]]\n    [[  -e \"${NB_DIR}/home/File Two.md\"    ]]\n    [[  -e \"${NB_DIR}/home/File Three.md\"  ]]\n    [[  -e \"${NB_DIR}/home/File Four.md\"   ]]\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                  ]]\n\n  [[ \"${output}\"    =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:4\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n\n  diff                              \\\n    <(cat \"${NB_DIR}/home/.index\")  \\\n    <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nFile Four.md\nHEREDOC\n)\n\n  git -C \"${NB_DIR}/home\" log\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Reconcile Index'\n}\n\n@test \"'browse' reconciles nested .index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    printf \"# Title Four\" > \"${NB_DIR}/home/Example Folder/File Four.md\"\n\n    diff                                            \\\n      <(cat \"${NB_DIR}/home/Example Folder/.index\") \\\n      <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nHEREDOC\n)\n\n    [[  -e \"${NB_DIR}/home/Example Folder/File One.md\"    ]]\n    [[  -e \"${NB_DIR}/home/Example Folder/File Two.md\"    ]]\n    [[  -e \"${NB_DIR}/home/Example Folder/File Three.md\"  ]]\n    [[  -e \"${NB_DIR}/home/Example Folder/File Four.md\"   ]]\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/ --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${output}\"    =~  href=\\\"//localhost:6789/home:1/4  ]]\n  [[ \"${output}\"    =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:Example${_S}Folder/4\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n\n  diff                                            \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\") \\\n    <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nFile Four.md\nHEREDOC\n)\n\n  git -C \"${NB_DIR}/home\" log\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Reconcile Index'\n}\n\n# HTML <title> ################################################################\n\n@test \"'browse <folder>/<folder>/<file>' with local notebook sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/Sample\\ Folder/Example\\ File.md --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ local:1/1/1\\</title\\> ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n@test \"'browse <folder>/ --query <query>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/ --query \"content\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ home:1\\ --query\\ \\\"content\\\"\\</title\\>           ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n@test \"'browse <folder>/<folder>/<file>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/Sample\\ Folder/Example\\ File.md --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ home:1/1/1\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n@test \"'browse' sets HTML <title> to CLI command with no selector.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                          ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                        ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ home:\\</title\\>   ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                      ]]\n}\n\n@test \"'browse <notebook>:' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Notebook: --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                      ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ Example\\\\\\ Notebook:\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                                    ]]\n}\n\n@test \"'browse <folder>/' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/ --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                          ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                        ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ home:1\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                      ]]\n}\n\n# local notebook ##############################################################\n\n@test \"'browse' with no arguments serves the local notebook contents as a rendered HTML page with links to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Title One\"         \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"File Two.md\"       \\\n      --title     \"Title Two\"         \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder\"    \\\n      --type      \"folder\"\n\n    declare _expected_param_pattern=\"--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\\&--columns=.*\\&--limit=.*\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0                   ]]\n  [[ \"${output}\"  =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  # header crumbs\n\n  [[ \"${output}\"  =~  \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>\\<strong\\>.*\\<a.*\\ href=\\\"//localhost:6789/\\?${_expected_param_pattern}\\\"\\>   ]]\n  [[ \"${output}\"  =~  \\\nhref=\\\"//localhost:6789/\\?${_expected_param_pattern}\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\> ]]\n  [[ \"${output}\"  =~  \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/local:\\?${_expected_param_pattern}\\\"\\>local\\</a\\>.*\\</nav\\>   ]]\n\n  # form\n\n  [[ \"${output}\"  =~  \\\naction=\\\"/local:\\?--columns=.*\\&--limit=.*\\&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\\\"  ]]\n\n  [[ \"${output}\"  =~  \\\n\\<input\\ type=\\\"hidden\\\"\\ name=\\\"--local\\\"\\ \\ \\ \\ \\ value=\\\"${_TMP_DIR}/Local\\ Notebook\\\"\\>     ]]\n\n  # list\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/local:3\\?--columns.*\\&--limit=.*\\&--local=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ \"${output}\"  =~  .*\\[.*local:3.*\\].*${_S}📂${_S}Example${_S}Folder\\</a\\>\\<br\\>                   ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/local:2\\?--columns.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ \"${output}\"  =~  .*\\[.*local:2.*\\].*${_S}Title${_S}Two\\</a\\>\\<br\\>                   ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/local:1\\?--columns.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ \"${output}\"  =~  .*\\[.*local:1.*\\].*${_S}Title${_S}One\\</a\\>\\<br\\>                   ]]\n}\n\n# columns #####################################################################\n\n@test \"GET to container URL with no --columns param and GUI request truncates using the default column value and omits --column param from links.\" {\n\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                    \\\n      \"Example File.md\"             \\\n       --content \"Example content.\" \\\n--title \"\\\nabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:?--gui\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                                        ]]\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*home                    ]]\n\n  [[ \"${output}\"    =~  abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmno…  ]]\n\n  printf \"%s\\\\n\" \"${output}\" \\\n    | grep -q \"href=\\\"//localhost:6789/home:1\\\" class=\\\"list-item\\\"\"\n\n}\n\n@test \"GET to container URL with --columns param truncates using the provided value.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                    \\\n      \"Example File.md\"             \\\n       --content \"Example content.\" \\\n--title \"\\\nabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:?--columns=20\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                                        ]]\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*home                    ]]\n\n  [[ \"${output}\"    =~  abcdefghi…                                ]]\n\n  printf \"%s\\\\n\" \"${output}\" \\\n    | grep -q \"href=\\\"//localhost:6789/home:1?--columns=20&--limit=.*\\\" class=\\\"list-item\\\"\"\n}\n\n# empty #######################################################################\n\n@test \"'browse <folder-selector>/' (slash) with empty folder prints message and header.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder\" --type \"folder\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/ --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0               ]]\n\n  [[ \"${output}\"  =~  \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>\\<strong\\>\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*\\&--limit=.*\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>  ]]\n  [[ \"${output}\"  =~  \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns.*\\&--limit=.*\\\"\\>home\\</a\\>\\ .*:.*\\              ]]\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1/\\?--columns.*\\&--limit=.*\\\"\\>Example\\ Folder\\</a\\>\\ .*/.*\\</nav\\> ]]\n\n  [[ \"${output}\"  =~  0${_NBSP}items. ]]\n}\n\n@test \"'browse <notebook>:' with empty notebook prints message and header.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Notebook: --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0               ]]\n\n  [[ \"${output}\"  =~  \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>\\<strong\\>\\<a.*\\ href=\\\"//localhost:6789/\\?--columns.*\\&--limit=.*\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\> ]]\n  [[ \"${output}\"  =~  \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/Example%20Notebook:\\?--columns=.*\\&--limit=.*\\\"\\>Example\\ Notebook\\</a\\>.*\\</nav\\>  ]]\n\n  [[ \"${output}\"  =~  0${_NBSP}items. ]]\n}\n\n# notebooks and folder (containers) ###########################################\n\n@test \"'browse' with no arguments serves the current notebook contents as a rendered HTML page with links to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Title One\"         \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"File Two.md\"       \\\n      --title     \"Title Two\"         \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder\"    \\\n      --type      \"folder\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0                   ]]\n  [[ \"${output}\"  =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  [[ \"${output}\"  =~  \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>\\<strong\\>.*\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*\\&--limit=.*\\\"\\> ]]\n  [[ \"${output}\"  =~  \\\nhref=\\\"//localhost:6789/\\?--columns=.*\\&--limit=.*\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\> ]]\n  [[ \"${output}\"  =~  \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*\\&--limit=.*\\\"\\>home\\</a\\>.*\\</nav\\>     ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ \"${output}\"  =~  .*\\[.*home:3.*\\].*${_S}📂${_S}Example${_S}Folder\\</a\\>\\<br\\>        ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ \"${output}\"  =~  .*\\[.*home:2.*\\].*${_S}Title${_S}Two\\</a\\>\\<br\\>                    ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ \"${output}\"  =~  .*\\[.*home:1.*\\].*${_S}Title${_S}One\\</a\\>\\<br\\>                    ]]\n}\n\n@test \"'browse <folder-selector>/' (slash) serves the list as rendered HTML with links to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File Two.md\"  \\\n      --title     \"Title Two\"                   \\\n      --content   \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/ --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<nav class=\\\"header-crumbs\\\">.*<a.* href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\".*·.* <a.* href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> .*:.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<a.* href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*\\\">Example Folder</a> .*/.*</nav>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<a.* href=\\\"//localhost:6789/home:1/2?--columns=.*&--limit=.*\\\" class=\\\"list-item\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\".*\\[.*Example${_S}Folder/2.*\\].*${_S}Title${_S}Two</a><br>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<a.* href=\\\"//localhost:6789/home:1/1?--columns=.*&--limit=.*\\\" class=\\\"list-item\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\".*\\[.*Example${_S}Folder/1.*\\].*${_S}Title${_S}One</a><br>\"\n}\n\n@test \"'browse <folder-selector>' (no slash) serves the list as rendered HTML with links to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File Two.md\"  \\\n      --title     \"Title Two\"                   \\\n      --content   \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0 ]]\n\n  [[ \"${output}\"  =~  \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>\\<strong\\>\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*\\&--limit=.*\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>  ]]\n  [[ \"${output}\"  =~  \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*\\&--limit=.*\\\"\\>home\\</a\\>\\ .*:.*\\               ]]\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1/\\?--columns=.*\\&--limit=.*\\\"\\>Example\\ Folder\\</a\\>\\ .*/.*\\</nav\\>  ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1/2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>                ]]\n  [[ \"${output}\"  =~  .*\\[.*Example${_S}Folder/2.*\\].*${_S}Title${_S}Two\\</a\\>\\<br\\>                      ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1/1\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>                ]]\n  [[ \"${output}\"  =~  .*\\[.*Example${_S}Folder/1.*\\].*${_S}Title${_S}One\\</a\\>\\<br\\>                      ]]\n}\n\n@test \"'browse <notebook>:' serves the notebook contents as rendered HTML with links to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:File One.md\"  \\\n      --title     \"Title One\"                     \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Notebook:File Two.md\"  \\\n      --title     \"Title Two\"                     \\\n      --content   \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Notebook: --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a.* href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\".*·.* <a.* href=\\\"//localhost:6789/Example%20Notebook:?--columns=.*\\&--limit=.*\\\">Example Notebook</a> <span \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"class=\\\"muted\\\">:</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//localhost:6789/Example Notebook:?--columns=.*&--limit=.*&--add\\\">+</a></strong></nav>\"\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/Example%20Notebook:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ \"${output}\"  =~  .*\\[.*Example${_S}Notebook:2.*\\].*${_S}Title${_S}Two\\</a\\>\\<br\\>                  ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/Example%20Notebook:1\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ \"${output}\"  =~  .*\\[.*Example${_S}Notebook:1.*\\].*${_S}Title${_S}One\\</a\\>\\<br\\>                  ]]\n}\n"
  },
  {
    "path": "test/browse-delete.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# HTML <title> ################################################################\n\n@test \"'browse delete <folder>/<folder>/<file>' with local notebook sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse delete Example\\ Folder/Sample\\ Folder/Example\\ File.md --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>          ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ delete\\ local:1/1/1\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>        ]]\n}\n\n@test \"'browse delete <folder>/<folder>/<file>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse delete Example\\ Folder/Sample\\ Folder/Example\\ File.md --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>          ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ delete\\ home:1/1/1\\</title\\>   ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>        ]]\n}\n\n@test \"'browse delete <id>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse delete 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>          ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ delete\\ home:1\\</title\\>       ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>        ]]\n}\n\n@test \"'browse delete <notebook>:<id>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse delete Example\\ Notebook:1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                      ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                    ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ delete\\ Example\\\\\\ Notebook:1\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                  ]]\n}\n\n@test \"'browse <folder>/<id>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ home:1/1\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                        ]]\n}\n\n# POST ########################################################################\n\n@test \"POST to --delete URL with local notebook deletes the note and redirects.\"  {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"Example content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data  \\\n    \"\"                      \\\n    \"http://localhost:6789/local:1?--delete&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ -z \"$(ls \"${_TMP_DIR}/Local Notebook\")\"  ]]\n\n  # Creates git commit:\n\n  cd \"${_TMP_DIR}/Local Notebook\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"     ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  declare _expected_param_pattern=\"--limit=30\\&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found                      ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  \\\nLocation:\\ \\/\\/localhost:6789\\/local:\\?${_expected_param_pattern} ]]\n}\n\n@test \"POST to --delete URL deletes the note and redirects.\"  {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"Example content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data \"\" \"http://localhost:6789/home:1?--delete\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Deletes file:\n\n  [[ -z \"$(ls \"${NB_DIR}/home\")\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found                             ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                        ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                                     ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                                      ]]\n  [[ \"${lines[4]}\"  =~  Location:\\ \\/\\/localhost:6789\\/home:\\?--limit=.* ]]\n}\n\n# GET #########################################################################\n\n@test \"GET to --delete URL with --local parameter renders form to delete local item.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"Example content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n\n    declare _local_notebook_param=\"--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n    declare _expected_param_pattern=\"${_local_notebook_param}&--columns=.*&--limit=30\"\n  }\n\n  run curl -sS -D - \"http://localhost:6789/local:1?--delete&${_local_notebook_param}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Does not delete file:\n\n  diff                                      \\\n    <(cat \"${_TMP_DIR}/Local Notebook/Example File.md\") \\\n    <(printf \"# Example Title\\\\n\\\\nExample content.\\\\n\")\n\n  # Does not create git commit:\n\n  cd \"${_TMP_DIR}/Local Notebook\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*local.*\\ .*:.*\\ .*1     ]]\n  [[ \"${output}\"    =~  header-crumbs.*↓                          ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/?${_expected_param_pattern}\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"❯</span>nb</a>.*<span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">-</span> <span class=\\\"muted\\\">|</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h2 align=\\\"center\\\">deleting</h2>\"\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"<p align=\\\"center\\\">${_NEWLINE}.*<a rel=\\\"noopener noreferrer\\\" href=\\\"//localhost:6789/local:1\\?${_expected_param_pattern}\\\">${_NEWLINE}.*\\[1\\] Example File.md \\\"Example Title\\\"${_NEWLINE}.*</a>${_NEWLINE}.*</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"action=\\\"/local:1?--delete&${_expected_param_pattern}\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"delete\\\">\"\n}\n\n@test \"GET to --delete URL with --columns parameter uses value for form URL parameters, and header links.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"Example content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1?--delete&--columns=20\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Does not delete file:\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/home/Example File.md\") \\\n    <(printf \"# Example Title\\\\n\\\\nExample content.\\\\n\")\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1      ]]\n  [[ \"${output}\"    =~  header-crumbs.*↓                          ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/?--columns=20&--limit=30\\\"><span class=\\\"muted\\\">❯</span>nb</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"❯</span>nb</a>.*<span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">-</span> <span class=\\\"muted\\\">|</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h2 align=\\\"center\\\">deleting</h2>\"\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"<p align=\\\"center\\\">${_NEWLINE}.*<a rel=\\\"noopener noreferrer\\\" href=\\\"//localhost:6789/home:1\\?--columns=.*&--limit=.*\\\">${_NEWLINE}.*\\[1\\] Example File.md \\\"Example Title\\\"${_NEWLINE}.*</a>${_NEWLINE}.*</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"action=\\\"/home:1?--delete&--columns=.*&--limit=.*\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"delete\\\">\"\n}\n\n@test \"GET to --delete URL prints form without deleting note.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"Example content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1?--delete\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Does not delete file:\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/home/Example File.md\") \\\n    <(printf \"# Example Title\\\\n\\\\nExample content.\\\\n\")\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1      ]]\n  [[ \"${output}\"    =~  header-crumbs.*↓                          ]]\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"<form${_NEWLINE}.*${_NEWLINE}.*action=\\\"/home:1\\?--delete\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"delete\\\">\"\n}\n\n# CLI #########################################################################\n\n@test \"'browse --delete <selector>' opens the delete page in the browser.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --delete --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                        ]]\n\n  [[    \"${output}\"  =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1     ]]\n  [[ \"${output}\"    =~  header-crumbs.*↓                          ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h2 align=\\\"center\\\">deleting</h2>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p align=\\\"center\\\">${_NEWLINE}.*<a rel=\\\"noopener noreferrer\\\" href=\\\"//localhost:6789/home:1?--columns=.*&--limit=.*\\\">${_NEWLINE}.*\\[1\\] Example File.md \\\"Example Title\\\"${_NEWLINE}.*</a>${_NEWLINE}</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"action=\\\"/home:1?--delete&--columns=.*&--limit=.*\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"delete\\\">\"\n}\n\n"
  },
  {
    "path": "test/browse-edit.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'browse edit <id>' with todo item does not mark up done / closed checkbox in textareas.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [x] Example todo one.\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/home/Example One.todo.md\"\n  }\n\n  run \"${_NB}\" browse edit 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                                                       ]]\n  [[    \"${output}\"   =~  \\<\\!DOCTYPE\\ html\\>                                     ]]\n\n  [[    \"${output}\"   =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                        ]]\n  [[    \"${output}\"   =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\> ]]\n\n  [[    \"${output}\"   =~  \\#\\ \\[x\\]\\ Example\\ todo\\ one\\.                         ]]\n  [[ !  \"${output}\"   =~  \\\n\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>x\\</span\\>      ]]\n  [[ !  \"${output}\"   =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>x\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>    ]]\n}\n\n# HTML <title> ################################################################\n\n@test \"'browse edit <folder>/<folder>/<file>' with local notebook sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse edit Example\\ Folder/Sample\\ Folder/Example\\ File.md --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>          ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ edit\\ local:1/1/1\\</title\\>    ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>        ]]\n}\n\n@test \"'browse edit <folder>/<folder>/<file>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse edit Example\\ Folder/Sample\\ Folder/Example\\ File.md --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>          ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ edit\\ home:1/1/1\\</title\\>     ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>        ]]\n}\n\n@test \"'browse edit <file>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse edit 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>          ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ edit\\ home:1\\</title\\>         ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>        ]]\n}\n\n@test \"'browse edit <notebook>:<file>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse edit Example\\ Notebook:1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                    ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                  ]]\n  [[    \"${output}\"    =~  \\\n\\<title\\>${_ME}\\ browse\\ edit\\ Example\\\\\\ Notebook:1\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                ]]\n}\n\n@test \"'browse edit <folder>/<file>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse edit Example\\ Folder/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                  ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ edit\\ home:1/1\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                              ]]\n}\n\n# POST ########################################################################\n\n@test \"POST to --edit URL updates the note and prints form.\"  {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"Example content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D -                                                 \\\n    --data \"content=Line%20one.%0D%0A%0D%0ALine%20%2F%26%3F%20two.\" \\\n    \"http://localhost:6789/home:1?--edit\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Updates file:\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/home/Example File.md\") \\\n    <(printf \"Line one.\\\\n\\\\nLine /&? two.\\\\n\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1      ]]\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"<form${_NEWLINE}.*${_NEWLINE}.*action=\\\"/home:1\\?--edit\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"save\\\"> <span class=\\\"muted\\\">·</span> <span class=\\\"muted last-saved\\\">last: .*</span>\"\n}\n\n# local notebook ##############################################################\n\n@test \"POST to --edit URL with local notebook updates the note and prints form.\"  {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"Example content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - --data  \\\n    \"content=Updated\"       \\\n    \"http://localhost:6789/local:1?--edit&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Updates file:\n\n  diff                                                  \\\n    <(cat \"${_TMP_DIR}/Local Notebook/Example File.md\") \\\n    <(printf \"Updated\\\\n\")\n\n  # Creates git commit:\n\n  cd \"${_TMP_DIR}/Local Notebook\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*local.*\\ .*:.*\\ .*1     ]]\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"<form${_NEWLINE}.*${_NEWLINE}.*action=\\\"/local:1\\?--edit&.*--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"save\\\"> <span class=\\\"muted\\\">·</span> <span class=\\\"muted last-saved\\\">last: .*</span>\"\n}\n\n@test \"GET to --edit URL with local notebook renders form.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add  \"Example Folder/File One.js\"  \\\n      --content   \"console.log('example');\"\n\n    # shellcheck disable=2129\n    printf \"export NB_TESTING=1\\\\n\"               >> \"${NBRC_PATH}\"\n\n    (ncat                                       \\\n      --exec \"${_NB} browse --respond\"          \\\n      --listen                                  \\\n      --source-port \"6789\"                      \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/local:1/1?--edit&--example&-x&abcdefg&--sample=demo-value&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0    ]]\n\n  # Prints output:\n\n  [[    \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                              ]]\n  [[    \"${lines[1]}\"  =~  Date:\\ .*                                      ]]\n  [[    \"${lines[2]}\"  =~  Expires:\\ .*                                   ]]\n  [[    \"${lines[3]}\"  =~  Server:\\ nb                                    ]]\n  [[    \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8      ]]\n\n  [[    \"${output}\"    =~ \\\naction=\\\"/local:1/1\\?--edit\\&--columns=.*\\&--limit=.*\\&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook ]]\n\n  [[    \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"--example\\\"\\>  ]]\n  [[    \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"-x\\\"\\>         ]]\n  [[    \"${output}\"    =~ \\\n\\<input\\ type=\\\"hidden\\\"\\ name=\\\"--sample\\\"\\ value=\\\"demo-value\\\"\\>       ]]\n\n  [[ !  \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"abcdefg\\\"\\>    ]]\n}\n\n# option parameters ###########################################################\n\n@test \"GET to --edit URL with option parameters adds hidden form fields.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.js\"  \\\n      --content   \"console.log('example');\"\n\n    # shellcheck disable=2129\n    printf \"export NB_TESTING=1\\\\n\"               >> \"${NBRC_PATH}\"\n\n    (ncat                                       \\\n      --exec \"${_NB} browse --respond\"          \\\n      --listen                                  \\\n      --source-port \"6789\"                      \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1/1?--edit&--example&-x&abcdefg&--sample=demo-value\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0    ]]\n\n  # Prints output:\n\n  [[    \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                              ]]\n  [[    \"${lines[1]}\"  =~  Date:\\ .*                                      ]]\n  [[    \"${lines[2]}\"  =~  Expires:\\ .*                                   ]]\n  [[    \"${lines[3]}\"  =~  Server:\\ nb                                    ]]\n  [[    \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8      ]]\n\n  [[    \"${output}\"    =~ action=\\\"/home:1/1\\?--edit                      ]]\n\n  [[    \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"--example\\\"\\>  ]]\n  [[    \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"-x\\\"\\>         ]]\n  [[    \"${output}\"    =~ \\\n\\<input\\ type=\\\"hidden\\\"\\ name=\\\"--sample\\\"\\ value=\\\"demo-value\\\"\\>       ]]\n\n  [[ !  \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"abcdefg\\\"\\>    ]]\n}\n\n# ace editor ##################################################################\n\n@test \"GET to --edit URL with Ace enabled sets the theme with \\$NB_ACE_THEME.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.js\"  \\\n      --content   \"console.log('example');\"\n\n    # shellcheck disable=2129\n    printf \"export NB_ACE_ENABLED=1\\\\n\"           >> \"${NBRC_PATH}\"\n    printf \"export NB_ACE_THEME=\\\"ambiance\\\"\\\\n\"  >> \"${NBRC_PATH}\"\n    printf \"export NB_TESTING=1\\\\n\"               >> \"${NBRC_PATH}\"\n\n    (ncat                                       \\\n      --exec \"${_NB} browse --respond\"          \\\n      --listen                                  \\\n      --source-port \"6789\"                      \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1/1?--edit&--columns=20\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0    ]]\n\n  # Prints output:\n\n  [[    \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                              ]]\n  [[    \"${lines[1]}\"  =~  Date:\\ .*                                      ]]\n  [[    \"${lines[2]}\"  =~  Expires:\\ .*                                   ]]\n  [[    \"${lines[3]}\"  =~  Server:\\ nb                                    ]]\n  [[    \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8      ]]\n\n  [[    \"${output}\"    =~ action=\\\"/home:1/1\\?--edit                      ]]\n\n  [[    \"${output}\"    =~ initializeAceEditor                             ]]\n  [[    \"${output}\"    =~ editor\\.setTheme\\(\\'ace\\/theme\\/ambiance\\'\\)\\;  ]]\n}\n\n@test \"GET to --edit URL with Ace enabled and non-default extension includes initialization with updated mode.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.js\"  \\\n      --content   \"console.log('example');\"\n\n    printf \"export NB_ACE_ENABLED=1\\\\n\" >> \"${NBRC_PATH}\"\n    printf \"export NB_TESTING=1\\\\n\"     >> \"${NBRC_PATH}\"\n\n    (ncat                                       \\\n      --exec \"${_NB} browse --respond\"          \\\n      --listen                                  \\\n      --source-port \"6789\"                      \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1/1?--edit&--columns=20\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0    ]]\n\n  # Prints output:\n\n  [[    \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                                  ]]\n  [[    \"${lines[1]}\"  =~  Date:\\ .*                                          ]]\n  [[    \"${lines[2]}\"  =~  Expires:\\ .*                                       ]]\n  [[    \"${lines[3]}\"  =~  Server:\\ nb                                        ]]\n  [[    \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8          ]]\n\n  [[    \"${output}\"    =~ action=\\\"/home:1/1\\?--edit                          ]]\n\n  [[    \"${output}\"    =~ initializeAceEditor                                 ]]\n  [[    \"${output}\"    =~ aceModeList\\.getModeForPath\\(\\'example.js\\'\\)\\.mode ]]\n}\n\n@test \"GET to --edit URL with Ace un-enabled does not include initialization.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content.\"\n\n    printf \"export NB_ACE_ENABLED=0\\\\n\" >> \"${NBRC_PATH}\"\n    printf \"export NB_TESTING=1\\\\n\"     >> \"${NBRC_PATH}\"\n\n    (ncat                                       \\\n      --exec \"${_NB} browse --respond\"          \\\n      --listen                                  \\\n      --source-port \"6789\"                      \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1/1?--edit&--columns=20\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0    ]]\n\n  # Prints output:\n\n  [[    \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                                  ]]\n  [[    \"${lines[1]}\"  =~  Date:\\ .*                                          ]]\n  [[    \"${lines[2]}\"  =~  Expires:\\ .*                                       ]]\n  [[    \"${lines[3]}\"  =~  Server:\\ nb                                        ]]\n  [[    \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8          ]]\n\n  [[    \"${output}\"    =~ action=\\\"/home:1/1\\?--edit                          ]]\n\n\n  [[ !  \"${output}\"    =~ initializeAceEditor                                 ]]\n  [[ !  \"${output}\"    =~ aceModeList\\.getModeForPath\\(\\'example.md\\'\\)\\.mode ]]\n}\n\n@test \"GET to --edit URL with Ace enabled includes initialization with default mode and theme.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content. [[Example Title]]\"\n\n    printf \"export NB_ACE_ENABLED=1\\\\n\" >> \"${NBRC_PATH}\"\n    printf \"export NB_TESTING=1\\\\n\"     >> \"${NBRC_PATH}\"\n\n    (ncat                                       \\\n      --exec \"${_NB} browse --respond\"          \\\n      --listen                                  \\\n      --source-port \"6789\"                      \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1/1?--edit&--columns=20\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0    ]]\n\n  # Prints output:\n\n  [[    \"${lines[0]}\"  =~ HTTP/1.0\\ 200\\ OK                                   ]]\n  [[    \"${lines[1]}\"  =~ Date:\\ .*                                           ]]\n  [[    \"${lines[2]}\"  =~ Expires:\\ .*                                        ]]\n  [[    \"${lines[3]}\"  =~ Server:\\ nb                                         ]]\n  [[    \"${lines[4]}\"  =~ Content-Type:\\ text/html\\;\\ charset=UTF-8           ]]\n\n  [[    \"${output}\"    =~ action=\\\"/home:1/1\\?--edit                          ]]\n\n  [[    \"${output}\"    =~ initializeAceEditor                                 ]]\n  [[    \"${output}\"    =~ aceModeList\\.getModeForPath\\(\\'example.md\\'\\)\\.mode ]]\n  [[    \"${output}\"    =~ editor\\.setTheme\\(\\'ace\\/theme\\/twilight\\'\\)\\;      ]]\n}\n\n# GET #########################################################################\n\n@test \"GET to --edit URL with .odt file renders item without form.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"      \\\n      --title     \"Title One\"                       \\\n      --content   \"Example content. [[Example Title]]\"\n\n    cat \"${NB_DIR}/home/Example Folder/File One.md\" \\\n      | pandoc --from markdown --to odt             \\\n      | \"${_NB}\" add \"Example Folder/File One.odt\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/File One.odt\" ]]\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1/2?--edit&--columns=20\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0    ]]\n\n  printf \"%s\\\\n\" \"${output}\"  | grep -v -q \\\n    \"<p>Example content. <a\"\n\n  printf \"%s\\\\n\" \"${output}\"  | grep -v -q \\\n    \"<form\"\n}\n\n@test \"GET to --edit URL with --columns parameter uses value for textarea, form URL parameters, and header links and retains leading tab.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"\tExample content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1?--edit&--columns=20\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Does not update file:\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/home/Example File.md\") \\\n    <(printf \"# Example Title\\\\n\\\\n\tExample content.\\\\n\")\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1      ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"href=\\\"//localhost:6789/?--columns=20&--limit=30\\\"><span class=\\\"muted\\\">❯</span>nb</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\"32\\\"># Example Title\"\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n    \"<form${_NEWLINE}.*${_NEWLINE}.*action=\\\"/home:1\\?--edit&--columns=.*&--limit=.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"save\\\"> <span class=\\\"muted\\\">·</span> <span class=\\\"muted last-saved\\\">last: .*</span>\"\n}\n\n@test \"GET to --edit URL without --columns parameter uses default value for textarea and retains leading tab.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"\tExample content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1?--edit\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Does not update file:\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/home/Example File.md\") \\\n    <(printf \"# Example Title\\\\n\\\\n\tExample content.\\\\n\")\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//lo\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"calhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\"\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\">:</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//localhost:6789/home:\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"1?--columns=.*&--limit=.*\\\">1</a> <span class=\\\"muted\\\">·</span> <a.* \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"rel=\\\"noopener noreferrer\\\" href=\\\"//localhost:6789/--original/home/Example File.md\\\">↓</a> <span class=\\\"muted\\\">·</span> <span cl\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"ss=\\\"muted\\\">editing</span> <span class=\\\"muted\\\">·</span> <a rel=\\\"noopener noreferrer\\\" \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/home:1?--columns=.*&--limit=30&--delete\\\">-</a> <span class=\\\"muted\\\">|</span> <a \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"rel=\\\"noopener noreferrer\\\" href=\\\"//localhost:6789/home:?--columns=.*&--limit=30&--add\\\">+</a></strong></nav>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"rows=\\\"32\\\"># Example Title\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"save\\\"> <span class=\\\"muted\\\">·</span> <span class=\\\"muted last-saved\\\">last: .*</span>\"\n\n  [[ !  \"${output}\"    =~ \\<input\\ type=\\\"hidden\\\"\\ name=\\\"home%3A1\\\"\\> ]]\n\n}\n\n@test \"GET to --edit URL prints form without updating note.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --title \"Example Title\" --content \"Example content.\"\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1?--edit\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[    \"${status}\"  -eq 0                  ]]\n\n  # Does not update file:\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/home/Example File.md\") \\\n    <(printf \"# Example Title\\\\n\\\\nExample content.\\\\n\")\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n\n  [[ \"${output}\"    =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1      ]]\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"<form${_NEWLINE}.*${_NEWLINE}.*action=\\\"/home:1\\?--edit\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"save\\\"> <span class=\\\"muted\\\">·</span> <span class=\\\"muted last-saved\\\">last: .*</span>\"\n}\n\n# CLI #########################################################################\n\n@test \"'browse --edit <selector>' opens the edit page in the browser.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add --title \"Example Title\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --edit --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                    ]]\n\n  [[    \"${output}\"  =~  ❯.*nb.*\\ .*·.*\\ .*home.*\\ .*:.*\\ .*1 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | rg --multiline -q \\\n\"<form${_NEWLINE}.*${_NEWLINE}.*action=\\\"/home:1\\?--edit\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"value=\\\"save\\\"> <span class=\\\"muted\\\">·</span> <span class=\\\"muted last-saved\\\">last: .*</span>\"\n}\n"
  },
  {
    "path": "test/browse-header-crumbs.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --add #######################################################################\n\n@test \"'browse <notebook>:<folder-id>/<folder-id>/ --add' displays header crumbs with '+' unlinked.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type \"folder\"\n  }\n\n  run \"${_NB}\" browse home:1/1/ --header --add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\">:</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">:</span> <a href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*\\\">Example Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <a href=\\\"//localhost:6789/home:1/1/?--columns=.*&--limit=.*\\\">Sample Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <span class=\\\"muted\\\">+</span></strong></nav>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \"↓\"\n}\n\n# --edit ######################################################################\n\n@test \"'browse --edit' with .odt file does not display edit link in header crumbs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"                 \\\n      --title     \"Example Title\"                   \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"      \\\n      --title     \"Title One\"                       \\\n      --content   \"Example content. [[Example Title]]\"\n\n    cat \"${NB_DIR}/home/Example Folder/File One.md\" \\\n      | pandoc --from markdown --to odt             \\\n      | \"${_NB}\" add \"Example Folder/File One.odt\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/File One.odt\" ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 2/2 --print --edit\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0               ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"<a.* href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\" <span class=\\\"muted\\\">·</span> <a.* href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\">:</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\" <span class=\\\"muted\\\">:</span> <a.* href=\\\"//localhost:6789/home:2/?--columns=.*&--limit=.*\\\">Example Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"</span> <a.* href=\\\"//localhost:6789/--original/home/Example Folder/File One.odt\\\">↓</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\" <span class=\\\"muted\\\">/</span> <span class=\\\"muted\\\">2</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -v  -q \"edit\"\n}\n\n@test \"'browse <notebook>:<folder-id>/<folder-id>/<file-id> --edit' displays header crumbs with linked id and editing message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/File One.md\"  \\\n      --title     \"Example Title\"                             \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" browse home:1/1/1 --header --edit\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\">:</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">:</span> <a href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*\\\">Example Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <a href=\\\"//localhost:6789/home:1/1/?--columns=.*&--limit=.*\\\">Sample Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"</span> <a href=\\\"//localhost:6789/home:1/1/1?--columns=.*&--limit=.*\\\">1</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"</span> <a.* href=\\\"//localhost:6789/--original/home/Example Folder/Sample Folder/File One.md\\\">↓</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">editing</span> <span class=\\\"muted\\\">·</span> <a href=\\\"//local\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"host:6789/home:1/1/1?--columns=.*&--limit=.*&--delete\\\">-</a> <span class=\\\"muted\\\">\\|</span> <a \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/home:1/1/?--columns=.*&--limit=.*&--add\\\">+</a></strong></nav>\"\n}\n\n# header crumbs ###############################################################\n\n@test \"'browse <notebook>:<folder-id>/<folder-id>/<file-id>' with local notebook displays header crumbs with id with file.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/File One.md\"  \\\n      --title     \"Example Title\"                             \\\n      --content   \"Example content.\"\n\n    declare _local_notebook_param=\"--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n    declare _expected_params=\"?${_local_notebook_param}&--columns=.*&--limit=.*\"\n  }\n\n  run \"${_NB}\" browse local:1/1/1 --header\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a href=\\\"//localhost:6789/${_expected_params}\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a href=\\\"//localhost:6789/local:${_expected_params}\\\">local</a> <span class=\\\"muted\\\">:</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">:</span> <a href=\\\"//localhost:6789/local:1/${_expected_params}\\\">Example Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <a href=\\\"//localhost:6789/local:1/1/${_expected_params}\\\">Sample Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <span class=\\\"muted\\\">1</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"1</span> <span class=\\\"muted\\\">·</span> <a\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"</span> <a.* href=\\\"//localhost:6789/--original/local/Example Folder/Sample Folder/File One.md?${_local_notebook_param}\\\">↓</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<a href=\\\"//localhost:6789/local:1/1/1${_expected_params}&--edit\\\">edit</a> <span class=\\\"muted\\\">\\|</span> <a \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/local:1/1/${_expected_params}&--add\\\">+</a></strong></nav>\"\n}\n\n@test \"'browse <notebook>:<file-id>' displays header crumbs with id with file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Example Title\"     \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" browse home:1 --header\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\">:</span\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">:</span> <span class=\\\"muted\\\">1</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"1</span> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"</span> <a.* href=\\\"//localhost:6789/--original/home/File One.md\\\">↓</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <a href=\\\"//localhost:6789/home:1?--columns=.*&--limit=.*&--edit\\\">edit</a> <span class=\\\"muted\\\">\\|</span> <a \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*&--add\\\">+</a></strong></nav>\"\n}\n\n@test \"'browse <notebook>:<folder-id>/<folder-id>/<file-id>' displays header crumbs with id with file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/File One.md\"  \\\n      --title     \"Example Title\"                             \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" browse home:1/1/1 --header\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\">:</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">:</span> <a href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*\\\">Example Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <a href=\\\"//localhost:6789/home:1/1/?--columns=.*&--limit=.*\\\">Sample Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <span class=\\\"muted\\\">1</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"1</span> <span class=\\\"muted\\\">·</span> <a\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"</span> <a.* href=\\\"//localhost:6789/--original/home/Example Folder/Sample Folder/File One.md\\\">↓</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<a href=\\\"//localhost:6789/home:1/1/1?--columns=.*&--limit=.*&--edit\\\">edit</a> <span class=\\\"muted\\\">\\|</span> <a \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/home:1/1/?--columns=.*&--limit=.*&--add\\\">+</a></strong></nav>\"\n}\n\n@test \"'browse <notebook>:<folder-id>/<file-id>' displays header crumbs with folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" browse home:1/1 --header\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0 ]]\n\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\">:</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">:</span> <a href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*\\\">Example Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <span class=\\\"muted\\\">1</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"1</span> <span class=\\\"muted\\\">·</span> <a\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"</span> <a.* href=\\\"//localhost:6789/--original/home/Example Folder/File One.md\\\">↓</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<a href=\\\"//localhost:6789/home:1/1?--columns=.*&--limit=.*&--edit\\\">edit</a> <span class=\\\"muted\\\">|</span> <a \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*&--add\\\">+</a></strong></nav>\"\n}\n\n@test \"'browse <notebook>:<folder-id>/<folder-id>' displays header crumbs with folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/File One.md\"  \\\n      --title     \"Example Title\"                             \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" use \"Example Notebook\"\n  }\n\n  run \"${_NB}\" browse home:1/1/ --header\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\">:</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">:</span> <a href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*\\\">Example Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <a href=\\\"//localhost:6789/home:1/1/?--columns=.*&--limit=.*\\\">Sample Folder</a> <span class=\\\"muted\\\">/</span> <a \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/home:1/1/?--columns=.*&--limit=.*&--add\\\">+</a></strong></nav>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \"↓\"\n\n\n  run \"${_NB}\" browse home:1/1/ --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0  ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong>\"\n}\n\n@test \"'browse <notebook-path>/<folder>/<filename>' displays header crumbs with folder and id for file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" browse \"${NB_DIR}/home/Example Folder/File One.md\" --header\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0  ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a href=\\\"//localhost:6789/?--columns=.*&--limit.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\">:</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">:</span> <a href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*\\\">Example Folder</a> <span class=\\\"muted\\\">/</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">/</span> <span class=\\\"muted\\\">1</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"1</span> <span class=\\\"muted\\\">·</span> <a\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"</span> <a.* href=\\\"//localhost:6789/--original/home/Example Folder/File One.md\\\">↓</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<a href=\\\"//localhost:6789/home:1/1?--columns=.*&--limit=.*&--edit\\\">edit</a> <span class=\\\"muted\\\">\\|</span> <a \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*&--add\\\">+</a></strong></nav>\"\n}\n\n@test \"'browse <notebook-path>/<folder>' displays header crumbs with folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" browse \"${NB_DIR}/home/Example Folder\" --header\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">·</span> <a href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*\\\">home</a> <span class=\\\"muted\\\">:</span> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\" <span class=\\\"muted\\\">:</span> <a href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*\\\">Example Folder</a> <span class=\\\"muted\\\">/</span> <a \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"href=\\\"//localhost:6789/home:1/?--columns=.*&--limit=.*&--add\\\">+</a></strong></nav>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \"↓\"\n}\n"
  },
  {
    "path": "test/browse-items.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'browse <selector>' processes markdown with \\$NB_BROWSE_MARKDOWN_READER value.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Root Title One\"    \\\n      --content   \"$(<<HEREDOC cat\nExample line one\nExample line two\n\nExample line four\n:smile:\nHEREDOC\n)\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  diff                                                                  \\\n    <(printf \"%s\\\\n\" \"${output}\" | sed -ne '/<div class=\"main\">/,$ p')  \\\n    <(cat <<HEREDOC\n<div class=\"main\">\n\n<h1 id=\"root-title-one\">Root Title One</h1>\n<p>Example line one\nExample line two</p>\n<p>Example line four\n<span class=\"emoji\" data-emoji=\"smile\">😄</span></p>\n</div>\n</body>\n</html>\nHEREDOC\n)\n\n  NB_BROWSE_MARKDOWN_READER=\"markdown+hard_line_breaks-emoji\" run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  diff                                                                  \\\n    <(printf \"%s\\\\n\" \"${output}\" | sed -ne '/<div class=\"main\">/,$ p')  \\\n    <(cat <<HEREDOC\n<div class=\"main\">\n\n<h1 id=\"root-title-one\">Root Title One</h1>\n<p>Example line one<br />\nExample line two</p>\n<p>Example line four<br />\n:smile:</p>\n</div>\n</body>\n</html>\nHEREDOC\n)\n\n}\n\n# response handling ###########################################################\n\n@test \"'browse' responds to request with no parameters and successfully serves item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"     \\\n      --title     \"Example Title\"       \\\n      --content   \"Example content.\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  [[ \"${output}\"    =~  header\\-crumbs.*↓   ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"example-title\\\">Example Title</h1>\"\n}\n\n@test \"'browse' responds to request with selector containing non-ascii characters.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"     \\\n      --title     \"Example Noté Title\"  \\\n      --content   \"Example noté content.\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/home:Example%20Noté%20Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  [[ \"${output}\"    =~  header\\-crumbs.*↓   ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"example-noté-title\\\">Example Noté Title</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example noté content.</p>\"\n}\n\n# todos #######################################################################\n\n@test \"'browse <id>' with todo item displays marked-up done / closed checkbox.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [x] Example todo one.\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/home/Example One.todo.md\"\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                      ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                         ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>x\\</span\\>           ]]\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>x\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>        ]]\n}\n\n@test \"'browse <id>' with todo item displays marked-up undone / open checkbox (space).\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [ ] Example todo one.\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/home/Example One.todo.md\"\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                      ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                         ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>${_S}\\</span\\>    ]]\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>${_S}\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>  ]]\n}\n\n@test \"'browse <id>' with todo item displays marked-up undone / open checkbox (no space).\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [ ] Example todo one.\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/home/Example One.todo.md\"\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                      ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                         ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>${_S}\\</span\\>    ]]\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>${_S}\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>  ]]\n}\n\n# pdf items ###################################################################\n\n@test \"'browse' with local notebook renders pdf item in an '<iframe>'.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    declare _filename=\"example.pdf\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/${_filename}\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/local/${_filename}\"\n    _raw_url_pattern+=\"\\?--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                          ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                        ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                           ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>    ]]\n\n  [[    \"${output}\"    =~  \\\n\\<iframe\\ src=\\\"${_raw_url_pattern}\\\"\\ width=\\\"100%\\\"\\ height=\\\"700px\\\"\\>\\</iframe\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\ align=\\\"center\\\"\\ class=\\\"media\\-caption\\\"\\>${_NEWLINE}.*\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>   ]]\n  [[    \"${output}\"    =~  \\\n\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>${_NEWLINE}.*${_filename}${_NEWLINE}.*\\</a\\>${_NEWLINE}.*\\</p\\>  ]]\n}\n\n@test \"'browse' renders pdf item in an '<iframe>'.\" {\n  {\n    \"${_NB}\" init\n\n    declare _filename=\"example.pdf\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/${_filename}\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/home/${_filename}\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                          ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                        ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                           ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>    ]]\n\n  [[    \"${output}\"    =~  \\\n\\<iframe\\ src=\\\"${_raw_url_pattern}\\\"\\ width=\\\"100%\\\"\\ height=\\\"700px\\\"\\>\\</iframe\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\ align=\\\"center\\\"\\ class=\\\"media\\-caption\\\"\\>${_NEWLINE}.*\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>   ]]\n  [[    \"${output}\"    =~  \\\n\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>${_NEWLINE}.*${_filename}${_NEWLINE}.*\\</a\\>${_NEWLINE}.*\\</p\\>  ]]\n}\n\n# audio items #################################################################\n\n@test \"'browse' with local notebook renders audio item as '<audio>' element.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    declare _filename=\"nb.mp3\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/${_filename}\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/local/${_filename}\"\n    _raw_url_pattern+=\"\\?--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n    declare _reported_file_type=\n    _reported_file_type=\"$(file -b --mime-type \"${_TMP_DIR}/Local Notebook/nb.mp3\")\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}:               '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:               '%s'\\\\n\" \"${output}\"\n  printf \"\\$(ls):                   '%s'\\\\n\" \"$(ls \"${_TMP_DIR}/Local Notebook/\")\"\n  printf \"\\${_reported_file_type}:  '%s'\\\\n\" \"${_reported_file_type}\"\n\n  [[    \"${status}\"    ==  0                                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                      ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                         ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<div\\ align=\\\"center\\\"\\ class=\\\"media-item\\\"\\>${_NEWLINE}.*\\<audio\\ controls\\>     ]]\n  [[    \"${output}\"    =~  \\\nmedia-item\\\"\\>${_NEWLINE}.*\\<audio\\ controls\\>${_NEWLINE}.*\\<source\\ src=           ]]\n  [[    \"${output}\"    =~  \\\n\\<source\\ src=\\\"${_raw_url_pattern}\\\"\\ type=\\\"audio/mpeg\\\"\\>                        ]]\n  [[    \"${output}\"    =~  \\\ntype=\\\"audio/mpeg\\\"\\>${_NEWLINE}.*\\</audio\\>${_NEWLINE}.*\\</div\\>                   ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\ align=\\\"center\\\"\\ class=\\\"media\\-caption\\\"\\>${_NEWLINE}.*\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>   ]]\n  [[    \"${output}\"    =~  \\\n\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>${_NEWLINE}.*${_filename}${_NEWLINE}.*\\</a\\>${_NEWLINE}.*\\</p\\>  ]]\n}\n\n@test \"'browse' renders audio item as '<audio>' element.\" {\n  {\n    \"${_NB}\" init\n\n    declare _filename=\"nb.mp3\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/${_filename}\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/home/${_filename}\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                      ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                         ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<div\\ align=\\\"center\\\"\\ class=\\\"media-item\\\"\\>${_NEWLINE}.*\\<audio\\ controls\\>     ]]\n  [[    \"${output}\"    =~  \\\nmedia-item\\\"\\>${_NEWLINE}.*\\<audio\\ controls\\>${_NEWLINE}.*\\<source\\ src=           ]]\n  [[    \"${output}\"    =~  \\\n\\<source\\ src=\\\"${_raw_url_pattern}\\\"\\ type=\\\"audio/mpeg\\\"\\>                        ]]\n  [[    \"${output}\"    =~  \\\ntype=\\\"audio/mpeg\\\"\\>${_NEWLINE}.*\\</audio\\>${_NEWLINE}.*\\</div\\>                   ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\ align=\\\"center\\\"\\ class=\\\"media\\-caption\\\"\\>${_NEWLINE}.*\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>   ]]\n  [[    \"${output}\"    =~  \\\n\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>${_NEWLINE}.*${_filename}${_NEWLINE}.*\\</a\\>${_NEWLINE}.*\\</p\\>  ]]\n}\n\n# video items #################################################################\n\n@test \"'browse' with local notebook renders video item as '<video>' element.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    declare _filename=\"nb.mp4\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/${_filename}\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/local/${_filename}\"\n    _raw_url_pattern+=\"\\?--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                      ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                         ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<div\\ align=\\\"center\\\"\\ class=\\\"media-item\\\"\\>${_NEWLINE}.*\\<video\\ width=\\\"320\\\"  ]]\n  [[    \"${output}\"    =~  \\\n${_NEWLINE}.*\\<video\\ width=\\\"320\\\"\\ height=\\\"240\\\"\\ controls\\>${_NEWLINE}          ]]\n  [[    \"${output}\"    =~  \\\ncontrols\\>${_NEWLINE}.*\\<source\\ src=\\\"${_raw_url_pattern}\\\"\\ type=\\\"video/mp4\\\"\\>  ]]\n  [[    \"${output}\"    =~  \\\ntype=\\\"video/mp4\\\"\\>${_NEWLINE}.*\\</video\\>${_NEWLINE}.*\\</div\\>                    ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\ align=\\\"center\\\"\\ class=\\\"media\\-caption\\\"\\>${_NEWLINE}.*\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>   ]]\n  [[    \"${output}\"    =~  \\\n\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>${_NEWLINE}.*${_filename}${_NEWLINE}.*\\</a\\>${_NEWLINE}.*\\</p\\>  ]]\n}\n\n@test \"'browse' renders video item as '<video>' element.\" {\n  {\n    \"${_NB}\" init\n\n    declare _filename=\"nb.mp4\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/${_filename}\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/home/${_filename}\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                      ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                         ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<div\\ align=\\\"center\\\"\\ class=\\\"media-item\\\"\\>${_NEWLINE}.*\\<video\\ width=\\\"320\\\"  ]]\n  [[    \"${output}\"    =~  \\\n${_NEWLINE}.*\\<video\\ width=\\\"320\\\"\\ height=\\\"240\\\"\\ controls\\>${_NEWLINE}          ]]\n  [[    \"${output}\"    =~  \\\ncontrols\\>${_NEWLINE}.*\\<source\\ src=\\\"${_raw_url_pattern}\\\"\\ type=\\\"video/mp4\\\"\\>  ]]\n  [[    \"${output}\"    =~  \\\ntype=\\\"video/mp4\\\"\\>${_NEWLINE}.*\\</video\\>${_NEWLINE}.*\\</div\\>                    ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\ align=\\\"center\\\"\\ class=\\\"media\\-caption\\\"\\>${_NEWLINE}.*\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>   ]]\n  [[    \"${output}\"    =~  \\\n\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>${_NEWLINE}.*${_filename}${_NEWLINE}.*\\</a\\>${_NEWLINE}.*\\</p\\>  ]]\n}\n\n# HTML <title> ################################################################\n\n@test \"'browse <folder>/<folder>/<id>' with local notebook sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"          \\\n      --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse \"Example Folder/Sample Folder/1\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ local:1/1/1\\</title\\> ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n@test \"'browse <id>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                          ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                        ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ home:1\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                      ]]\n}\n\n@test \"'browse <folder>/<folder>/<id>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse \"Example Folder/Sample Folder/1\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                              ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                            ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ home:1/1/1\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                          ]]\n}\n\n@test \"'browse <notebook>:<folder>/<folder>/<filename>' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/Sample Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse \"Example Notebook:Example Folder/Sample Folder/1\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                          ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ Example\\\\\\ Notebook:1/1/1\\</title\\> ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                                        ]]\n}\n\n# image URLs ##################################################################\n\n@test \"'browse' with local notebook rewrites image paths to --original URLs.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add                    \\\n      --filename  \"Example File.md\" \\\n      --content   \"$(<<HEREDOC cat\n# Example Title\n\nExample ![](nb.png) content ![](Example Folder/nb.png).\n\nMore ![](https://example.test/example.png) demo content ![](http://example.test/sample.png).\nHEREDOC\n)\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/nb.png\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/nb.png\" Example\\ Folder/\n\n    [[ -f \"${_TMP_DIR}/Local Notebook/nb.png\"                 ]]\n    [[ -f \"${_TMP_DIR}/Local Notebook/Example Folder/nb.png\"  ]]\n\n    declare _raw_url_pattern_one=\"//localhost:6789/--original/local/nb.png\"\n    _raw_url_pattern_one+=\"\\?--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n    declare _raw_url_pattern_two=\"//localhost:6789/--original/local/Example%20Folder/nb.png\"\n    _raw_url_pattern_two+=\"\\?--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                      ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                    ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                       ]]\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ \\<img\\ src=\\\"${_raw_url_pattern_one}\\\"\\ \\/\\>\\ content\\              ]]\n  [[    \"${output}\"    =~  \\\n\\/\\>\\ content\\ \\<img\\ src=\\\"${_raw_url_pattern_two}\\\"\\ /\\>.\\</p\\>                 ]]\n  [[    \"${output}\"    =~  \\\n\\<p\\>\\More\\ \\<img\\ src=\\\"https://example.test/example.png\\\"\\ \\/\\>\\ demo\\ content  ]]\n  [[    \"${output}\"    =~  \\\n\\/\\>\\ demo\\ content\\ \\<img\\ src=\\\"http://example.test/sample.png\\\"\\ /\\>.\\</p\\>    ]]\n}\n\n@test \"'browse' rewrites image paths to --original URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                    \\\n      --filename  \"Example File.md\" \\\n      --content   \"$(<<HEREDOC cat\n# Example Title\n\nExample ![](nb.png) content ![](Example Folder/nb.png).\n\nMore ![](https://example.test/example.png) demo content ![](http://example.test/sample.png).\nHEREDOC\n)\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/nb.png\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/nb.png\" Example\\ Folder/\n\n    [[ -f \"${NB_DIR}/home/nb.png\"                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/nb.png\"  ]]\n\n    declare _raw_url_pattern_one=\"//localhost:6789/--original/home/nb.png\"\n    declare _raw_url_pattern_two=\"//localhost:6789/--original/home/Example%20Folder/nb.png\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                      ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                    ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                       ]]\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ \\<img\\ src=\\\"${_raw_url_pattern_one}\\\"\\ \\/\\>\\ content\\              ]]\n  [[    \"${output}\"    =~  \\\n\\/\\>\\ content\\ \\<img\\ src=\\\"${_raw_url_pattern_two}\\\"\\ /\\>.\\</p\\>                 ]]\n  [[    \"${output}\"    =~  \\\n\\<p\\>\\More\\ \\<img\\ src=\\\"https://example.test/example.png\\\"\\ \\/\\>\\ demo\\ content  ]]\n  [[    \"${output}\"    =~  \\\n\\/\\>\\ demo\\ content\\ \\<img\\ src=\\\"http://example.test/sample.png\\\"\\ /\\>.\\</p\\>    ]]\n}\n\n# image items #################################################################\n\n@test \"'browse' with local notebook renders image item as '<img>' element.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/nb.png\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/local/nb.png\"\n    _raw_url_pattern+=\"\\?--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                          ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                        ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                           ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>    ]]\n\n  [[    \"${output}\"    =~  \\\n\\<div\\ align=\\\"center\\\"\\ class=\\\"media-item\\\"\\>${_NEWLINE}.*\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\> ]]\n  [[    \"${output}\"    =~  \\\n${_raw_url_pattern}\\\"\\>${_NEWLINE}.*\\<img\\ src=\\\"${_raw_url_pattern}\\\"\\                           ]]\n  [[    \"${output}\"    =~  \\\n\\\"${_raw_url_pattern}\\\"\\ alt=\\\"${_IMOGI}\\ nb.png\\\"\\ /\\>${_NEWLINE}.*\\</a\\>${_NEWLINE}.*\\</div\\>    ]]\n}\n\n@test \"'browse' renders image item as '<img>' element.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/nb.png\"\n\n    declare _raw_url_pattern=\"//localhost:6789/--original/home/nb.png\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                          ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                                        ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>                           ]]\n  [[    \"${output}\"    =~  \\</span\\>\\ \\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\>↓\\</a\\>    ]]\n\n  [[    \"${output}\"    =~  \\\n\\<div\\ align=\\\"center\\\"\\ class=\\\"media-item\\\"\\>${_NEWLINE}.*\\<a.*\\ href=\\\"${_raw_url_pattern}\\\"\\> ]]\n  [[    \"${output}\"    =~  \\\n${_raw_url_pattern}\\\"\\>${_NEWLINE}.*\\<img\\ src=\\\"${_raw_url_pattern}\\\"\\                           ]]\n  [[    \"${output}\"    =~  \\\n\\\"${_raw_url_pattern}\\\"\\ alt=\\\"${_IMOGI}\\ nb.png\\\"\\ /\\>${_NEWLINE}.*\\</a\\>${_NEWLINE}.*\\</div\\>   ]]\n}\n\n# <img> stripping #############################################################\n\n@test \"'browse' strips <img> tags after '## Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename  \"Example File.bookmark.md\"  \\\n      --title     \"Example Title\"             \\\n      --content   \"$(<<HEREDOC cat\n<https://example.test>\n\n## Description\n\nExample image one: ![Example Image One](not-valid-1.png)\n\n## Content\n\nMore example ![Example Image Two](not-valid-2.png) content ![Example Image Three](not-valid-3.png) here.\nHEREDOC\n)\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>             ]]\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ image\\ one:\\ \\<img\\ src=\\\".*not-valid-1.png\\\"\\ alt=\\\"Example\\ Image\\ One\\\"\\ /\\>\\</p\\> ]]\n  [[    \"${output}\"    =~  \\<p\\>More\\ example\\ \\ content\\ \\ here.\\</p\\> ]]\n}\n\n@test \"'browse' strips <img> tags after '## Page Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename  \"Example File.bookmark.md\"  \\\n      --title     \"Example Title\"             \\\n      --content   \"$(<<HEREDOC cat\n<https://example.test>\n\n## Description\n\nExample image one: ![Example Image One](not-valid-1.png)\n\n## Page Content\n\nMore example ![Example Image Two](not-valid-2.png) content ![Example Image Three](not-valid-3.png) here.\nHEREDOC\n)\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>             ]]\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ image\\ one:\\ \\<img\\ src=\\\".*not-valid-1.png\\\"\\ alt=\\\"Example\\ Image\\ One\\\"\\ /\\>\\</p\\> ]]\n  [[    \"${output}\"    =~  \\<p\\>More\\ example\\ \\ content\\ \\ here.\\</p\\> ]]\n}\n\n@test \"'browse' renders <img> tags anywhere in non-bookmark items.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                    \\\n      --filename  \"Example File.md\" \\\n      --title     \"Example Title\"   \\\n      --content   \"$(<<HEREDOC cat\n<https://example.test>\n\n## Description\n\nExample image one: ![Example Image One](not-valid-1.png)\n\n## Content\n\nMore example ![Example Image Two](not-valid-2.png) content ![Example Image Three](not-valid-3.png) here.\nHEREDOC\n)\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                      ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                    ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>       ]]\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ image\\ one:\\ \\<img\\ src=\\\".*not-valid-1.png\\\"\\ alt=\\\"Example\\ Image\\ One\\\"\\ /\\>\\</p\\> ]]\n  [[    \"${output}\"    =~  \\\n\\<p\\>More\\ example\\ \\<img\\ src=\\\".*not-valid-2.png\\\"\\ alt=\\\"Example\\ Image\\ Two\\\"\\ /\\>\\ content\\    ]]\n  [[    \"${output}\"    =~  \\\n\\ content\\ \\<img\\ src=\\\".*not-valid-3.png\\\"\\ alt=\\\"Example\\ Image\\ Three\\\"\\ /\\>\\ here.\\</p\\>        ]]\n\n}\n\n# local notebook ##############################################################\n\n@test \"'browse <folder-id>/<id>' with local notebook serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content. [[Example Title]]\"\n\n    sleep 1\n\n    declare _expected_params=\"?--columns=.*&--limit=.*&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n  }\n\n  run \"${_NB}\" browse 2/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"title-one\\\">Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/local:Example Title${_expected_params}\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n# .pdf ########################################################################\n\n@test \"'browse' with .pdf file and 'pdftotext' enabled serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  hash \"pdftotext\" 2>/dev/null || skip\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"                         \\\n      --title     \"Example Title\"                           \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" import                                         \\\n      \"${NB_TEST_BASE_PATH}/fixtures/Example File.pdf\"      \\\n      \"Example Folder/\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.pdf\"  ]]\n\n    sleep 1\n  }\n\n  # TODO: improve\n  NB_BROWSE_PDF_TO_TEXT_ENABLED=1 run \"${_NB}\" browse 2/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example PDF File\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<a.* href=\\\"//localhost:6789/home:1?--columns=.*&--limit=.*\\\">\\[\\[home:1\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<a.* href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*&--query=%23tag1\\\">\\#tag1</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<a.* href=\\\"//localhost:6789/home:?--columns=.*&--limit=.*&--query=%23tag2\\\">\\#tag2</a>\"\n}\n\n# nb --browse / nb -b #########################################################\n\n@test \"'nb --browse <folder-id>/<id>' serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content. [[Example Title]]\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" --browse 2/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"title-one\\\">Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/home:Example Title?--columns=.*&--limit=.*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n@test \"'nb -b <folder-id>/<id>' serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content. [[Example Title]]\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" -b 2/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"title-one\\\">Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/home:Example Title?--columns=.*&--limit=.*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n# edge cases ##################################################################\n\n@test \"'browse <folder-id>/<id>' serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs without altering home link.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content. [[Example Title]]\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 2/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"title-one\\\">Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<a.* href=\\\"//localhost:6789/?--columns.*&--limit.*\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/home:Example Title?--columns=.*&--limit=.*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n# syntax highlighting #########################################################\n\n@test \"'browse <item>' includes syntax highlighting.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"example.rb\" --content  \"puts \\\"Hello World\\\"\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[    \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>             ]]\n\n  [[    \"${output}\"    =~  pre\\ \\>\\ code.sourceCode                     ]]\n\n  [[    \"${output}\"    =~  \\\n\\<div\\ class=\\\"sourceCode\\\"\\ id=\\\"cb1\\\"\\>\\<pre\\ class=\\\"sourceCode\\ rb\\\"\\>\\<code\\  ]]\n\n  [[    \"${output}\"    =~  \\<code\\ class=\\\"sourceCode\\ ruby\\\"\\>         ]]\n\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"fu\\\"\\>puts\\</span\\>\\ \\<span\\ class=\\\"st\\\"\\>\\&quot\\;Hello\\ World\\&quot\\;\\</span\\> ]]\n}\n\n# code ########################################################################\n\n@test \"'browse' with .bash file serves file in a code block.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.bash\" --content \"echo \\\"hello\\\"\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                       ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                     ]]\n\n  [[ \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>        ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'<a.* href=\"//localhost:6789/?--columns=.*&--limit=.*\"><span class=\"muted\">❯</span>nb</a>'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'<span class=\"muted\">·</span> <a.* href=\"//localhost:6789/home:?--columns=.*&--limit=.*\">home</a\\>'\n\n  [[ \"${output}\"    =~  \\<div\\ class=\\\"sourceCode\\\"             ]]\n  [[ \"${output}\"    =~  \\<pre\\ class=\\\"sourceCode\\ bash\\\"\\>     ]]\n  [[ \"${output}\"    =~  \\&quot\\;hello\\&quot\\;                   ]]\n}\n\n@test \"'browse' with .js file serves file in a code block.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.js\" --content \"console.log(\\\"hello\\\");\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                       ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                     ]]\n\n  [[ \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>        ]]\n  [[ \"${output}\"    =~  header-crumbs.*↓                        ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'<a.* href=\"//localhost:6789/?--columns=.*&--limit=.*\"><span class=\"muted\">❯</span>nb</a>'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'<span class=\"muted\">·</span> <a.* href=\"//localhost:6789/home:?--columns=.*&--limit=.*\">home</a\\>'\n\n  [[ \"${output}\"    =~  \\<div\\ class=\\\"sourceCode\\\"             ]]\n  [[ \"${output}\"    =~  \\<pre\\ class=\\\"sourceCode\\ js\\\"\\>       ]]\n  [[ \"${output}\"    =~  \\&quot\\;hello\\&quot\\;                   ]]\n}\n\n# .odt ########################################################################\n\n@test \"'browse' with .odt file serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"                 \\\n      --title     \"Example Title\"                   \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"      \\\n      --title     \"Title One\"                       \\\n      --content   \"Example content. [[Example Title]]\"\n\n    cat \"${NB_DIR}/home/Example Folder/File One.md\" \\\n      | pandoc --from markdown --to odt             \\\n      | \"${_NB}\" add \"Example Folder/File One.odt\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/File One.odt\" ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 2/2 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  pandoc --from odt --to html \"${NB_DIR}/home/Example Folder/File One.odt\"\n\n  [[ \"${output}\"    =~  header-crumbs.*↓    ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"title-one\\\"><span id=\\\"anchor\\\"></span>Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/home:Example Title?--columns=.*&--limit=.*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n# .docx #######################################################################\n\n@test \"'browse' with .docx file serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"                 \\\n      --title     \"Example Title\"                   \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"      \\\n      --title     \"Title One\"                       \\\n      --content   \"Example content. [[Example Title]]\"\n\n    cat \"${NB_DIR}/home/Example Folder/File One.md\" \\\n      | pandoc --from markdown --to docx            \\\n      | \"${_NB}\" add \"Example Folder/File One.docx\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/File One.docx\" ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 2/2 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  [[ \"${output}\"    =~  header-crumbs.*↓    ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"title-one\\\">Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/home:Example Title?--columns=.*&--limit=.*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n# .asciidoc ###################################################################\n\n@test \"'browse' with .asciidoc file serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.asciidoc\"  \\\n      --title     \"Title One\"                         \\\n      --content   \"$(cat <<HEREDOC\n= Example AsciiDoc Title\n\nExample content. [[Example Title]]\nHEREDOC\n      )\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 2/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  [[ \"${output}\"    =~  header-crumbs.*↓    ]]\n\n  # TODO: .org / org mode titles in pandoc HTML output?\n  # [[ \"${output}\"    =~  \\<h1\\ id=\\\"title-one\\\"\\>Title\\ One\\</h1\\>                     ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/home:Example Title?--columns=.*&--limit=.*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 .*>Example AsciiDoc Title</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<p>= Example AsciiDoc Title</p>\"\n}\n\n# .org ########################################################################\n\n@test \"'browse' with .org file serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.org\" \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content. [[Example Title]]\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 2/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  [[ \"${output}\"    =~  header-crumbs.*↓    ]]\n\n  # TODO: .org / org mode titles in pandoc HTML output?\n  # [[ \"${output}\"    =~  \\<h1\\ id=\\\"title-one\\\"\\>Title\\ One\\</h1\\>                     ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<nav class=\\\"header-crumbs\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/home:1?--columns=.*&amp;--limit=.*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n# markdown ####################################################################\n\n@test \"'browse <folder-id>/<id>' serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content. [[Example Title]]\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 2/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  [[ \"${output}\"    =~  header\\-crumbs.*↓   ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"title-one\\\">Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/home:Example Title?--columns=.*&--limit=.*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n@test \"'browse <folder-name>/<id>' serves the rendered HTML page with [[wiki-style links]] resolved to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.md\"  \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content. [[Example Title]]\"\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  [[ \"${output}\"    =~  header-crumbs.*↓    ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 id=\\\"title-one\\\">Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"//localhost:6789/home:Example Title?--columns=.*&--limit=.*\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n@test \"'browse <item-selector>' properly resolves titled [[wiki-style links]].\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Root Title One\"    \\\n      --content   \"$(<<HEREDOC cat\nExample link one: [[Root Title Two]]\n\nMore example [[Example Notebook:Example Folder/1]] content [[3/1]] here.\nHEREDOC\n)\"\n\n    \"${_NB}\" add  \"File Two.md\"       \\\n      --title     \"Root Title Two\"    \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Sample Folder/File One.md\"                   \\\n      --title     \"Sample Nested Title Two\"                     \\\n      --content   \"Sample nested content one.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File One.md\" \\\n      --title     \"Example Nested Title One\"                    \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" use \"Sample Notebook\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse home:1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'one: <a.* href=\"//localhost:6789/home:Root Title Two?--columns=.*&--limit.*\">\\[\\[Root Title Two\\]\\]</a>'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'example <a.* href=\"//localhost:6789/Example Notebook:Example Folder/1?--columns=.*&--limit.*\">\\[\\[Example Notebook:Example Folder/1\\]\\]</a> content'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'content <a.* href=\"//localhost:6789/home:3/1?--columns=.*&--limit.*\">\\[\\[3/1\\]\\]</a> here'\n}\n\n@test \"'browse <item-selector>' properly resolves titled [[wiki-style links]] and skips links with non-resolving selectors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Root Title One\"    \\\n      --content   \"$(<<HEREDOC cat\nExample link one: [[Root Title Two]]\n\nMore example [[Example Notebook:Example Folder/1]] content [[2/1]] here.\nHEREDOC\n)\"\n\n    \"${_NB}\" add  \"File Two.md\"       \\\n      --title     \"Root Title Two\"    \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Sample Folder/File One.md\"                   \\\n      --title     \"Sample Nested Title Two\"                     \\\n      --content   \"Sample nested content one.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File One.md\" \\\n      --title     \"Example Nested Title One\"                    \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" use \"Sample Notebook\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse home:1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'one: <a.* href=\"//localhost:6789/home:Root Title Two?--columns=.*&--limit.*\">\\[\\[Root Title Two\\]\\]</a>'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'example <a.* href=\"//localhost:6789/Example Notebook:Example Folder/1?--columns=.*&--limit.*\">\\[\\[Example Notebook:Example Folder/1\\]\\]</a> content'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'content <a.* href=\"//localhost:6789/home:2/1?--columns=.*&--limit.*\">\\[\\[2/1\\]\\]</a> here'\n}\n\n@test \"'browse <selector>' properly resolves duplicated [[wiki-style links]] in HTML.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Root Title One\"    \\\n      --content   \"$(<<HEREDOC cat\nExample link one: [[Example Notebook:Example Folder/1]]\n\nMore example [[Example Notebook:Example Folder/1]] content.\nHEREDOC\n)\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File One.md\" \\\n      --title     \"Nested Title One\"                            \\\n      --content   \"Nested content one.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'link one: <a.* href=\"//localhost:6789/Example Notebook:Example Folder/1?--columns=.*&--limit.*\">\\[\\[Example Notebook:Example Folder/1\\]\\]</a>'\n\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v\\\n'example <a.* href=\"//localhost:6789/Example Notebook:Example Folder/1?--columns=.*&--limit.*\">\\[\\[Example Notebook:Example Folder/1\\]\\]</a>'\n}\n\n@test \"'browse <selector>' resolves [[wiki-style links]] in a different arrangement in HTML.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Root Title One\"    \\\n      --content   \"$(<<HEREDOC cat\nExample content one [[Sample Folder/Nested Title One]] with more [[Example Notebook:File Two.md]].\n\nMore example [[Example Notebook:Example Folder/1]] content.\nHEREDOC\n)\"\n\n    \"${_NB}\" add  \"File Two.md\"                   \\\n      --title     \"Root Title Two\"                \\\n      --content   \"Root content two.\"\n\n    \"${_NB}\" add  \"Sample Folder/File One.md\"     \\\n      --title     \"Nested Title One\"              \\\n      --content   \"Nested content one.\"\n\n    \"${_NB}\" add  \"Sample Folder/File Two.md\"     \\\n      --title     \"Nested Title Two\"              \\\n      --content   \"Nested content two.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:File One.md\"  \\\n      --title     \"Root Title One\"                \\\n      --content   \"Root content one.\"\n\n    \"${_NB}\" add  \"Example Notebook:File Two.md\"  \\\n      --title     \"Root Title Two\"                \\\n      --content   \"Root content two.\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File One.md\" \\\n      --title     \"Nested Title One\"                            \\\n      --content   \"Nested content one.\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File Two.md\" \\\n      --title     \"Nested Title Two\"                            \\\n      --content   \"Nested content two.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'<a.* href=\"//localhost:6789/home:Sample Folder/Nested Title One?--columns=.*&--limit.*\">\\[\\[Sample Folder/Nested Title One\\]\\]</a>'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'<a.* href=\"//localhost:6789/Example Notebook:File Two.md?--columns=.*&--limit.*\">\\[\\[Example Notebook:File Two.md\\]\\]</a>'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'<a.* href=\"//localhost:6789/Example Notebook:Example Folder/1?--columns=.*&--limit.*\">\\[\\[Example Notebook:Example Folder/1\\]\\]</a>'\n}\n"
  },
  {
    "path": "test/browse-notebooks.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# terminal formatting #########################################################\n\n@test \"'browse --notebooks' breaks lines and omits separator at column limit.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n  }\n\n  run \"${_NB}\" browse --notebooks --columns 35 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0                   ]]\n  [[ \"${output}\"  =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<nav class=\\\"header-crumbs\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">notebooks</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<p><a.* href=\\\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=.*\\\">Demo${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Example%20Notebook:?--columns=.*&--limit=.*\\\">Example${_S}Notebook</a><br>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Sample%20Notebook:?--columns=.*&--limit=.*\\\">Sample${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Test%20Notebook:?--columns=.*&--limit=.*\\\">Test${_S}Notebook</a></p>\"\n\n  run \"${_NB}\" browse --notebooks --columns 10 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0                   ]]\n  [[ \"${output}\"  =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<nav class=\\\"header-crumbs\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">notebooks</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<p><a.* href=\\\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=.*\\\">Demo${_S}Notebook</a><br>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Example%20Notebook:?--columns=.*&--limit=.*\\\">Example${_S}Notebook</a><br>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Sample%20Notebook:?--columns=.*&--limit=.*\\\">Sample${_S}Notebook</a><br>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Test%20Notebook:?--columns=.*&--limit=.*\\\">Test${_S}Notebook</a></p>\"\n}\n\n# HTML <title> ################################################################\n\n@test \"'browse --notebooks' sets HTML <title> to CLI command.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --notebooks --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                                ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                              ]]\n  [[    \"${output}\"    =~  \\<title\\>${_ME}\\ browse\\ \\-\\-notebooks\\</title\\> ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                            ]]\n}\n\n# local #######################################################################\n\n@test \"'browse --notebooks'  with local notebook serves the list of unarchived notebooks with local notebook as a rendered HTML page with links to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n\n    declare _local_notebook_param=\"--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n    declare _expected_param_pattern=\"${_local_notebook_param}&--columns=.*&--limit=.*\"\n  }\n\n  run \"${_NB}\" browse --notebooks --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0                   ]]\n  [[ \"${output}\"  =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"<nav class=\\\"header-crumbs\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"<a.* href=\\\"//localhost:6789/?${_expected_param_pattern}\\\"><span \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"<span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">notebooks</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -v  -q \\\n\"<p><a.* href=\\\"//localhost:6789/local:?.*<a.* href=\\\"//localhost:6789/local:?\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"<p><a.* href=\\\"//localhost:6789/local:?${_expected_param_pattern}\\\">local</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"<p><a.* href=\\\"//localhost:6789/Demo%20Notebook:?${_expected_param_pattern}\\\">Demo${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"<a.* href=\\\"//localhost:6789/Example%20Notebook:?${_expected_param_pattern}\\\">Example${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"<a.* href=\\\"//localhost:6789/Sample%20Notebook:?${_expected_param_pattern}\\\">Sample${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n\"<a.* href=\\\"//localhost:6789/Test%20Notebook:?${_expected_param_pattern}\\\">Test${_S}Notebook</a></p>\"\n}\n\n# browse -n ###################################################################\n\n@test \"'browse -n'  serves the list of unarchived notebooks as a rendered HTML page with links to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n  }\n\n  run \"${_NB}\" browse -n --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0                   ]]\n  [[ \"${output}\"  =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<nav class=\\\"header-crumbs\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">notebooks</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<p><a.* href=\\\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=.*\\\">Demo${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Example%20Notebook:?--columns=.*&--limit=.*\\\">Example${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Sample%20Notebook:?--columns=.*&--limit=.*\\\">Sample${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Test%20Notebook:?--columns=.*&--limit=.*\\\">Test${_S}Notebook</a></p>\"\n}\n\n# browse --notebooks ##########################################################\n\n@test \"'browse --notebooks'  serves the list of unarchived notebooks as a rendered HTML page with links to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n  }\n\n  run \"${_NB}\" browse --notebooks --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0                   ]]\n  [[ \"${output}\"  =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<nav class=\\\"header-crumbs\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/?--columns=.*&--limit=.*\\\"><span \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">notebooks</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<p><a.* href=\\\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=.*\\\">Demo${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Example%20Notebook:?--columns=.*&--limit=.*\\\">Example${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Sample%20Notebook:?--columns=.*&--limit=.*\\\">Sample${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Test%20Notebook:?--columns=.*&--limit=.*\\\">Test${_S}Notebook</a></p>\"\n}\n\n@test \"GET to 'browse --notebooks' URL serves the list of unarchived notebooks as a rendered HTML page with links to internal web server URLs without mutedensional parameters.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n\n    (ncat                                   \\\n      --exec \"${_NB} browse --respond\"      \\\n      --listen                              \\\n      --source-port \"6789\"                  \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/?--gui\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0                   ]]\n  [[ \"${output}\"  =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<nav class=\\\"header-crumbs\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/\\\"><span \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<span class=\\\"muted\\\">❯</span>nb</a> <span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">notebooks</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<p><a.* href=\\\"//localhost:6789/Demo%20Notebook:\\\">Demo${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Example%20Notebook:\\\">Example${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Sample%20Notebook:\\\">Sample${_S}Notebook</a>${_S}.*·.*\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n\"<a.* href=\\\"//localhost:6789/Test%20Notebook:\\\">Test${_S}Notebook</a></p>\"\n}\n"
  },
  {
    "path": "test/browse-pagination.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'browse' only includes next page link when there are remaining items.\" {\n  {\n    \"${_NB}\" init\n\n    declare i=\n    for   ((i=1; i < 11; i++))\n    do\n      declare _content=\"Example content ${i}.\"\n\n      \"${_NB}\" add  \"File ${i}.md\"  \\\n        --title     \"Title ${i}\"    \\\n        --content   \"${_content}\"\n    done\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print --limit 10 --terminal\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                  ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ Demo\\\\\\ Notebook:\\</title\\>   ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep    -v -q  \\\n\"//localhost:6789/Demo%20Notebook:?--limit=.*&--columns=.*&--page=2\\\">next ❯\"\n\n  run \"${_NB}\" browse --print --limit 5 --page 2 --terminal\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                            ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                          ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ Demo\\\\\\ Notebook:\\ --page\\ 2\\</title\\>  ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep    -v -q  \\\n\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=.*&--page=2\\\">next ❯\"\n\n  run \"${_NB}\" browse --print --limit 9 --terminal\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                  ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ Demo\\\\\\ Notebook:\\</title\\>   ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep    -v -q  \\\n\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=.*&--page=2\\\">next ❯\"\n\n  {\n    \"${_NB}\" add  \"File 11.md\"  \\\n      --title     \"Title 11\"    \\\n      --content   \"Example content 11.\"\n  }\n\n  run \"${_NB}\" browse --print --limit 5 --page 2  --terminal\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                            ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                          ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ Demo\\\\\\ Notebook:\\ --page\\ 2\\</title\\>  ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep    -v -q  \\\n\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=.*&--page=3\\\">next ❯\"\n}\n\n@test \"'browse' includes pagination on links on listing page.\" {\n  {\n    \"${_NB}\" init\n\n    declare __number=\n    for     __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      declare _content=\"Example content.\"\n\n      case \"${__number}\" in\n        One)\n          _content+=\" [[Title Two]] • #example\"\n          ;;\n        Two|Three|Six|Seven|Nine)\n          _content+=\" #example\"\n          ;;\n      esac\n\n      \"${_NB}\" add  \"File ${__number}.md\" \\\n        --title     \"Title ${__number}\"   \\\n        --content   \"${_content}\"\n    done\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print --limit 2 --terminal\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                  ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ Demo\\\\\\ Notebook:\\</title\\>   ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a.* href=\\\"//localhost:6789/?--columns=.*&--limit=2\\\">\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"><a.* href=\\\"//localhost:6789/?--columns=.*&--limit=2\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<span class=\\\"muted\\\">·</span> <a.* href=\\\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=2\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"Demo Notebook</a> <span class=\\\"muted\\\">:</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//local\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"host:6789/Demo Notebook:?--columns=.*&--limit=2&--add\\\">+</a></strong></nav>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"//localhost:6789/Demo%20Notebook:10?--columns=.*&--limit=2\\\" class=\\\"list-item\\\">\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"//localhost:6789/Demo%20Notebook:9?--columns=.*&--limit=2\\\" class=\\\"list-item\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -v  -q  \\\n\"//localhost:6789/Demo%20Notebook:8?--columns=.*&--limit=2\\\" class=\\\"list-item\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=2&--page=2\\\">next ❯\"\n}\n\n\n@test \"'browse' encodes #hashtag queries in pagination links.\" {\n  {\n    \"${_NB}\" init\n\n    declare __number=\n    for     __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      declare _content=\"Example content. #example\"\n\n      case \"${__number}\" in\n        One)\n          _content+=\" [[Title Two]] • #example\"\n          ;;\n        Two|Three|Six|Seven|Nine)\n          _content+=\" #example\"\n          ;;\n      esac\n\n      \"${_NB}\" add  \"File ${__number}.md\" \\\n        --title     \"Title ${__number}\"   \\\n        --content   \"${_content}\"\n    done\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print --page 2 --limit 2 --terminal --query \"#example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                    ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>  ]]\n\n  [[ \"${output}\"  =~ \\\n\\<title\\>nb\\ browse\\ Demo\\\\\\ Notebook:\\ --query\\ \\\"\\&#35\\;example\\\"\\ --page\\ 2\\</title\\>  ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=2&--query=%23example\\\">❮ prev\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=2&--query=%23example&--page=3\\\">next ❯\"\n}\n\n@test \"'browse' includes pagination on links on item page.\" {\n  {\n    \"${_NB}\" init\n\n    declare __number=\n    for     __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      declare _content=\"Example content.\"\n\n      case \"${__number}\" in\n        One)\n          _content+=\" [[Title Two]] • #example\"\n          ;;\n        Two|Three|Six|Seven|Nine)\n          _content+=\" #example\"\n          ;;\n      esac\n\n      \"${_NB}\" add  \"File ${__number}.md\" \\\n        --title     \"Title ${__number}\"   \\\n        --content   \"${_content}\"\n    done\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print --limit 2 --terminal\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                  ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ Demo\\\\\\ Notebook:1\\</title\\>  ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<nav class=\\\"header-crumbs\\\">\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<a.* href=\\\"//localhost:6789/?--columns=.*&--limit=2\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<span class=\\\"muted\\\">·</span> <a.* href=\\\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=2\\\">Demo Notebook</a>\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"Demo Notebook</a> <span class=\\\"muted\\\">:</span> <span class=\\\"muted\\\">1</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<a.* href=\\\"//localhost:6789/Demo Notebook:Title Two?--columns=.*&--limit=2\\\">\\[\\[Title Two\\]\\]</a>\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<a.* href=\\\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=2&--query=%23example\\\">#example</a></p>\"\n}\n\n@test \"'browse' includes pagination on links on notebooks page.\" {\n  {\n    \"${_NB}\" init\n\n    declare __number=\n    for     __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      declare _content=\"Example content.\"\n\n      case \"${__number}\" in\n        One)\n          _content+=\" [[Title Two]] • #example\"\n          ;;\n        Two|Three|Six|Seven|Nine)\n          _content+=\" #example\"\n          ;;\n      esac\n\n      \"${_NB}\" add  \"File ${__number}.md\" \\\n        --title     \"Title ${__number}\"   \\\n        --content   \"${_content}\"\n    done\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --notebooks --print --limit 2 --terminal\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                            ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ \\-\\-notebooks\\</title\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<nav class=\\\"header-crumbs\\\">\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<a.* href=\\\"//localhost:6789/?--columns=.*&--limit=2\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<span class=\\\"muted\\\">·</span> <span class=\\\"muted\\\">notebooks</span>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<a.*href=\\\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=2\\\">Demo${_S}Notebook</a>${_S}<span\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"span> <a.*href=\\\"//localhost:6789/Example%20Notebook:?--columns=.*&--limit=2\\\">Example${_S}Notebook</a>${_S}<span\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"span> <a.*href=\\\"//localhost:6789/Sample%20Notebook:?--columns=.*&--limit=2\\\">Sample${_S}Notebook</a>${_S}<span\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"span> <a.*href=\\\"//localhost:6789/Test%20Notebook:?--columns=.*&--limit=2\\\">Test${_S}Notebook</a>\"\n}\n\n@test \"'browse' paginates lists with --limit <limit>.\" {\n  {\n    \"${_NB}\" init\n\n    declare __number=\n    for     __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print --limit 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                      ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                    ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ home:\\</title\\>   ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'<nav class=\"header-crumbs\"><strong><a.* href=\"//localhost:6789/?--columns=.*&--limit=4\"><span class=\"muted\">❯</span>nb</a>'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<span class=\\\"muted\\\">·</span> <a.* href=\\\"//localhost:6789/home:?--columns=.*&--limit=4\\\">home</a> <span \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"class=\\\"muted\\\">:</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//localhost:6789/home:?--columns=.*&--limit=4&--add\\\">+</a></strong></nav>\"\n\n  # 10-7\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:10\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>     ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:10.*\\].*${_S}Title${_S}Ten\\</a\\>\\<br\\>        ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:9\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:9.*\\].*${_S}${_S}Title${_S}Nine\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:8\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:8.*\\].*${_S}${_S}Title${_S}Eight\\</a\\>\\<br\\>  ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:7\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:7.*\\].*${_S}${_S}Title${_S}Seven\\</a\\>\\<br\\>  ]]\n\n  # 6-3\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:6\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:6.*\\].*${_S}${_S}Title${_S}Six\\</a\\>\\<br\\>    ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:5.*\\].*${_S}${_S}Title${_S}Five\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:4.*\\].*${_S}${_S}Title${_S}Four\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:3.*\\].*${_S}${_S}Title${_S}Three\\</a\\>\\<br\\>  ]]\n\n  # 2-1\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:2.*\\].*${_S}${_S}Title${_S}Two\\</a\\>\\<br\\>    ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:1.*\\].*${_S}${_S}Title${_S}One\\</a\\>\\<br\\>    ]]\n\n  # pagination links\n\n  [[    \"${output}\"  =~ \\<p\\ class=\\\"pagination\\\"\\>      ]]\n  [[    \"${output}\"  =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4${_AMP}--page=2\\\"\\>next\\ ❯\\</a\\>\\</p\\>  ]]\n  [[ !  \"${output}\"  =~ ❮\\ prev ]]\n\n  # page 2\n\n  sleep 1\n\n  run \"${_NB}\" browse --print --limit 4 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                  ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ home:\\ \\-\\-page\\ 2\\</title\\>  ]]\n\n  [[ \"${output}\"  =~ \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>.*\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*${_AMP}--limit=4               ]]\n  [[ \"${output}\"  =~ \\\nlocalhost:6789/\\?--columns=.*${_AMP}--limit=4\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>                  ]]\n  [[ \"${output}\"  =~ \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4\\\"\\>home\\</a\\>.*\\</strong\\>\\</nav\\>  ]]\n\n  # 10-7\n\n  [[ !  \"${output}\"  =~  \\\n\\<p\\>\\<a.*\\ href=\\\"//localhost:6789/home:10\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\> ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:10.*\\].*${_S}Title${_S}Ten\\</a\\>\\<br\\>        ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:9\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:9.*\\].*${_S}${_S}Title${_S}Nine\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:8\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:8.*\\].*${_S}${_S}Title${_S}Eight\\</a\\>\\<br\\>  ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:7\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:7.*\\].*${_S}${_S}Title${_S}Seven\\</a\\>\\<br\\>  ]]\n\n  # 6-3\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:6\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:6.*\\].*${_S}${_S}Title${_S}Six\\</a\\>\\<br\\>    ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:5.*\\].*${_S}${_S}Title${_S}Five\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:4.*\\].*${_S}${_S}Title${_S}Four\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:3.*\\].*${_S}${_S}Title${_S}Three\\</a\\>\\<br\\>  ]]\n\n  # 2-1\n\n  [[ !  \"${output}\"  =~  \\\n\\<p\\>\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:2.*\\].*${_S}${_S}Title${_S}Two\\</a\\>\\<br\\>    ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:1.*\\].*${_S}${_S}Title${_S}One\\</a\\>\\<br\\>    ]]\n\n  # pagination links\n\n  [[    \"${output}\"  =~ \\<p\\ class=\\\"pagination\\\"\\>      ]]\n  [[    \"${output}\"  =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4\\\"\\>❮\\ prev\\</a\\>\\ .*\\·.*\\              ]]\n  [[ !  \"${output}\"  =~ --page=1.*\\\"\\>❮\\ prev\\</a\\>\\ .*\\·.*\\   ]]\n  [[    \"${output}\"  =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4${_AMP}--page=3\\\"\\>next\\ ❯\\</a\\>\\</p\\>  ]]\n\n  # page 3\n\n  sleep 1\n\n  run \"${_NB}\" browse --print --limit 4 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                  ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ home:\\ \\-\\-page\\ 3\\</title\\>  ]]\n\n  [[ \"${output}\"  =~ \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>.*\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*${_AMP}--limit=4               ]]\n  [[ \"${output}\"  =~ \\\nlocalhost:6789/\\?--columns=.*${_AMP}--limit=4\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>                  ]]\n  [[ \"${output}\"  =~ \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4\\\"\\>home\\</a\\>.*\\</strong\\>\\</nav\\>  ]]\n\n  # 10-7\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:10\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:10.*\\].*${_S}Title${_S}Ten\\</a\\>\\<br\\>        ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:9\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:9.*\\].*${_S}${_S}Title${_S}Nine\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:8\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:8.*\\].*${_S}${_S}Title${_S}Eight\\</a\\>\\<br\\>  ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:7\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:7.*\\].*${_S}${_S}Title${_S}Seven\\</a\\>\\<br\\>  ]]\n\n  # 6-3\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:6\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:6.*\\].*${_S}${_S}Title${_S}Six\\</a\\>\\<br\\>    ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:5.*\\].*${_S}${_S}Title${_S}Five\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:4.*\\].*${_S}${_S}Title${_S}Four\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:3.*\\].*${_S}${_S}Title${_S}Three\\</a\\>\\<br\\>  ]]\n\n  # 2-1\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:2.*\\].*${_S}${_S}Title${_S}Two\\</a\\>\\<br\\>    ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:1.*\\].*${_S}${_S}Title${_S}One\\</a\\>\\<br\\>    ]]\n\n  # pagination links\n\n  [[    \"${output}\"  =~ \\<p\\ class=\\\"pagination\\\"\\>      ]]\n  [[    \"${output}\"  =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4${_AMP}--page=2\\\"\\>❮\\ prev\\</a\\>\\</p\\>  ]]\n  [[ !  \"${output}\"  =~ next\\ ❯ ]]\n\n  # page with list of items under pagination limit\n\n  sleep 1\n\n  run \"${_NB}\" browse --print --limit 11\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                      ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                    ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ home:\\</title\\>   ]]\n\n  [[ \"${output}\"  =~ \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>\\<strong\\>\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*${_AMP}--limit=11      ]]\n  [[ \"${output}\"  =~ \\\nlocalhost:6789/\\?--columns=.*${_AMP}--limit=11\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>                 ]]\n  [[ \"${output}\"  =~ \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=11\\\"\\>home\\</a\\>.*\\</strong\\>\\</nav\\> ]]\n\n  # 10-7\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:10\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\> ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:10.*\\].*${_S}Title${_S}Ten\\</a\\>\\<br\\>        ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:9\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:9.*\\].*${_S}${_S}Title${_S}Nine\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:8\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:8.*\\].*${_S}${_S}Title${_S}Eight\\</a\\>\\<br\\>  ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:7\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:7.*\\].*${_S}${_S}Title${_S}Seven\\</a\\>\\<br\\>  ]]\n\n  # 6-3\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:6\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:6.*\\].*${_S}${_S}Title${_S}Six\\</a\\>\\<br\\>    ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:5.*\\].*${_S}${_S}Title${_S}Five\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:4.*\\].*${_S}${_S}Title${_S}Four\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:3.*\\].*${_S}${_S}Title${_S}Three\\</a\\>\\<br\\>  ]]\n\n  # 2-1\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  .*\\[.*home:2.*\\].*${_S}${_S}Title${_S}Two\\</a\\>\\<br\\>         ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  .*\\[.*home:1.*\\].*${_S}${_S}Title${_S}One\\</a\\>\\<br\\>         ]]\n\n  # pagination links\n\n  [[ !  \"${output}\"  =~ \\<p\\ class=\\\"pagination\\\"\\> ]]\n  [[ !  \"${output}\"  =~ ❮\\ prev                     ]]\n  [[ !  \"${output}\"  =~ next\\ ❯                     ]]\n}\n\n@test \"'browse -<limit>' paginates list.\" {\n  {\n    \"${_NB}\" init\n\n    declare __number=\n    for     __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      declare _content=\"Example content.\"\n\n      case \"${__number}\" in\n        One)\n          _content+=\" [[Title Two]] • #example\"\n          ;;\n        Two|Three|Six|Seven|Nine)\n          _content+=\" #example\"\n          ;;\n      esac\n\n      \"${_NB}\" add  \"File ${__number}.md\" \\\n        --title     \"Title ${__number}\"   \\\n        --content   \"${_content}\"\n    done\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Demo Notebook\"\n\n    [[    -d \"${NB_DIR}/Demo Notebook\"  ]]\n    [[ !  -e \"${NB_DIR}/home\"           ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print -2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                  ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ Demo\\\\\\ Notebook:\\</title\\>   ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<nav class=\\\"header-crumbs\\\"><strong><a.* href=\\\"//localhost:6789/?--columns=.*&--limit=2\\\">\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"><a.* href=\\\"//localhost:6789/?--columns=.*&--limit=2\\\"><span class=\\\"muted\\\">❯</span>nb</a>\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"<span class=\\\"muted\\\">·</span> <a.* href=\\\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=2\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"Demo Notebook</a> <span class=\\\"muted\\\">:</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//local\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"host:6789/Demo Notebook:?--columns=.*&--limit=2&--add\\\">+</a></strong></nav>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"//localhost:6789/Demo%20Notebook:10?--columns=.*&--limit=2\\\" class=\\\"list-item\\\">\"\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"//localhost:6789/Demo%20Notebook:9?--columns=.*&--limit=2\\\" class=\\\"list-item\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -v  -q  \\\n\"//localhost:6789/Demo%20Notebook:8?--columns=.*&--limit=2\\\" class=\\\"list-item\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep       -q  \\\n\"//localhost:6789/Demo%20Notebook:?--columns=.*&--limit=2&--page=2\\\">next ❯\"\n}\n\n@test \"'browse' paginates lists with -n <limit>.\" {\n  {\n    \"${_NB}\" init\n\n    declare __number=\n    for     __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print -n 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                      ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                    ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ home:\\</title\\>   ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n'<nav class=\"header-crumbs\"><strong><a.* href=\"//localhost:6789/?--columns=.*&--limit=4\"><span class=\"muted\">❯</span>nb</a>'\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<span class=\\\"muted\\\">·</span> <a.* href=\\\"//localhost:6789/home:?--columns=.*&--limit=4\\\">home</a> <span \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"class=\\\"muted\\\">:</span> <a rel=\\\"noopener noreferrer\\\" href=\\\"//localhost:6789/home:?--columns=.*&--limit=4&--add\\\">+</a></strong></nav>\"\n\n  # 10-7\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:10\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>     ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:10.*\\].*${_S}Title${_S}Ten\\</a\\>\\<br\\>        ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:9\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:9.*\\].*${_S}${_S}Title${_S}Nine\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:8\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:8.*\\].*${_S}${_S}Title${_S}Eight\\</a\\>\\<br\\>  ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:7\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:7.*\\].*${_S}${_S}Title${_S}Seven\\</a\\>\\<br\\>  ]]\n\n  # 6-3\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:6\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:6.*\\].*${_S}${_S}Title${_S}Six\\</a\\>\\<br\\>    ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:5.*\\].*${_S}${_S}Title${_S}Five\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:4.*\\].*${_S}${_S}Title${_S}Four\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:3.*\\].*${_S}${_S}Title${_S}Three\\</a\\>\\<br\\>  ]]\n\n  # 2-1\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:2.*\\].*${_S}${_S}Title${_S}Two\\</a\\>\\<br\\>    ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>      ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:1.*\\].*${_S}${_S}Title${_S}One\\</a\\>\\<br\\>    ]]\n\n  # pagination links\n\n  [[    \"${output}\"  =~ \\<p\\ class=\\\"pagination\\\"\\>      ]]\n  [[    \"${output}\"  =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4${_AMP}--page=2\\\"\\>next\\ ❯\\</a\\>\\</p\\>  ]]\n  [[ !  \"${output}\"  =~ ❮\\ prev ]]\n\n  # page 2\n\n  sleep 1\n\n  run \"${_NB}\" browse --print -n 4 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                  ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ home:\\ \\-\\-page\\ 2\\</title\\>  ]]\n\n  [[ \"${output}\"  =~ \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>.*\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*${_AMP}--limit=4               ]]\n  [[ \"${output}\"  =~ \\\nlocalhost:6789/\\?--columns=.*${_AMP}--limit=4\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>                  ]]\n  [[ \"${output}\"  =~ \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4\\\"\\>home\\</a\\>.*\\</strong\\>\\</nav\\>  ]]\n\n  # 10-7\n\n  [[ !  \"${output}\"  =~  \\\n\\<p\\>\\<a.*\\ href=\\\"//localhost:6789/home:10\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\> ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:10.*\\].*${_S}Title${_S}Ten\\</a\\>\\<br\\>        ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:9\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:9.*\\].*${_S}${_S}Title${_S}Nine\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:8\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:8.*\\].*${_S}${_S}Title${_S}Eight\\</a\\>\\<br\\>  ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:7\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:7.*\\].*${_S}${_S}Title${_S}Seven\\</a\\>\\<br\\>  ]]\n\n  # 6-3\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:6\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:6.*\\].*${_S}${_S}Title${_S}Six\\</a\\>\\<br\\>    ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:5.*\\].*${_S}${_S}Title${_S}Five\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:4.*\\].*${_S}${_S}Title${_S}Four\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:3.*\\].*${_S}${_S}Title${_S}Three\\</a\\>\\<br\\>  ]]\n\n  # 2-1\n\n  [[ !  \"${output}\"  =~  \\\n\\<p\\>\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:2.*\\].*${_S}${_S}Title${_S}Two\\</a\\>\\<br\\>    ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>       ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:1.*\\].*${_S}${_S}Title${_S}One\\</a\\>\\<br\\>    ]]\n\n  # pagination links\n\n  [[    \"${output}\"  =~ \\<p\\ class=\\\"pagination\\\"\\>      ]]\n  [[    \"${output}\"  =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4\\\"\\>❮\\ prev\\</a\\>\\ .*\\·.*\\       ]]\n  [[ !  \"${output}\"  =~ --page=1.*\\\"\\>❮\\ prev\\</a\\>\\ .*\\·.*\\   ]]\n  [[    \"${output}\"  =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4${_AMP}--page=3\\\"\\>next\\ ❯\\</a\\>\\</p\\> ]]\n\n  # page 3\n\n  sleep 1\n\n  run \"${_NB}\" browse --print -n 4 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                                  ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                                ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ home:\\ \\-\\-page\\ 3\\</title\\>  ]]\n\n  [[ \"${output}\"  =~ \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>.*\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*${_AMP}--limit=4               ]]\n  [[ \"${output}\"  =~ \\\nlocalhost:6789/\\?--columns=.*${_AMP}--limit=4\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>                  ]]\n  [[ \"${output}\"  =~ \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4\\\"\\>home\\</a\\>.*\\</strong\\>\\</nav\\>  ]]\n\n  # 10-7\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:10\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:10.*\\].*${_S}Title${_S}Ten\\</a\\>\\<br\\>        ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:9\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:9.*\\].*${_S}${_S}Title${_S}Nine\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:8\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:8.*\\].*${_S}${_S}Title${_S}Eight\\</a\\>\\<br\\>  ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:7\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:7.*\\].*${_S}${_S}Title${_S}Seven\\</a\\>\\<br\\>  ]]\n\n  # 6-3\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:6\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:6.*\\].*${_S}${_S}Title${_S}Six\\</a\\>\\<br\\>    ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:5.*\\].*${_S}${_S}Title${_S}Five\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:4.*\\].*${_S}${_S}Title${_S}Four\\</a\\>\\<br\\>   ]]\n\n  [[ !  \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\"  =~  \\\n.*\\[.*home:3.*\\].*${_S}${_S}Title${_S}Three\\</a\\>\\<br\\>  ]]\n\n  # 2-1\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:2.*\\].*${_S}${_S}Title${_S}Two\\</a\\>\\<br\\>    ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*${_AMP}--limit=4\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:1.*\\].*${_S}${_S}Title${_S}One\\</a\\>\\<br\\>    ]]\n\n  # pagination links\n\n  [[    \"${output}\"  =~ \\<p\\ class=\\\"pagination\\\"\\>      ]]\n  [[    \"${output}\"  =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=4${_AMP}--page=2\\\"\\>❮\\ prev\\</a\\>\\</p\\>  ]]\n  [[ !  \"${output}\"  =~ next\\ ❯ ]]\n\n  # page with list of items under pagination limit\n\n  sleep 1\n\n  run \"${_NB}\" browse --print -n 11\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  == 0                                      ]]\n  [[ \"${output}\"  =~ \\<\\!DOCTYPE\\ html\\>                    ]]\n\n  [[ \"${output}\"  =~ \\<title\\>nb\\ browse\\ home:\\</title\\>   ]]\n\n  [[ \"${output}\"  =~ \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>\\<strong\\>\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*${_AMP}--limit=11      ]]\n  [[ \"${output}\"  =~ \\\nlocalhost:6789/\\?--columns=.*${_AMP}--limit=11\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>                 ]]\n  [[ \"${output}\"  =~ \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*${_AMP}--limit=11\\\"\\>home\\</a\\>.*\\</strong\\>\\</nav\\> ]]\n\n  # 10-7\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:10\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:10.*\\].*${_S}Title${_S}Ten\\</a\\>\\<br\\>        ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:9\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:9.*\\].*${_S}${_S}Title${_S}Nine\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:8\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:8.*\\].*${_S}${_S}Title${_S}Eight\\</a\\>\\<br\\>  ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:7\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:7.*\\].*${_S}${_S}Title${_S}Seven\\</a\\>\\<br\\>  ]]\n\n  # 6-3\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:6\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:6.*\\].*${_S}${_S}Title${_S}Six\\</a\\>\\<br\\>    ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:5.*\\].*${_S}${_S}Title${_S}Five\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:4.*\\].*${_S}${_S}Title${_S}Four\\</a\\>\\<br\\>   ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  \\\n.*\\[.*home:3.*\\].*${_S}${_S}Title${_S}Three\\</a\\>\\<br\\>  ]]\n\n  # 2-1\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  .*\\[.*home:2.*\\].*${_S}${_S}Title${_S}Two\\</a\\>\\<br\\>                  ]]\n\n  [[    \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*${_AMP}--limit=11\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\"  =~  .*\\[.*home:1.*\\].*${_S}${_S}Title${_S}One\\</a\\>\\<br\\>                  ]]\n\n  # pagination links\n\n  [[ !  \"${output}\"  =~ \\<p\\ class=\\\"pagination\\\"\\> ]]\n  [[ !  \"${output}\"  =~ ❮\\ prev                     ]]\n  [[ !  \"${output}\"  =~ next\\ ❯                     ]]\n}\n"
  },
  {
    "path": "test/browse-responses.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --local #####################################################################\n\n@test \"'browse local:' with missing --local param responds with 400 Bad Request.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add  \"Example File.md\"     \\\n      --title     \"Example Title\"       \\\n      --content   \"Example content.\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -I -s \"http://localhost:6789/local:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                           ]]\n  [[ \"${#lines[@]}\" ==  6                           ]]\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 400\\ Bad\\ Request ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                   ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                 ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html    ]]\n}\n\n# 302 #########################################################################\n\n@test \"'browse' with 'url=<url>' param responds with 302 redirect.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"     \\\n      --title     \"Example Title\"       \\\n      --content   \"Example content.\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -I -s \"http://localhost:6789/?url=http%3A%2F%2Fexample.test\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                               ]]\n  [[ \"${#lines[@]}\" ==  5                               ]]\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 302\\ Found            ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                       ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                    ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                     ]]\n  [[ \"${lines[4]}\"  =~  Location:\\ http://example.test  ]]\n}\n\n# 404 #########################################################################\n\n@test \"'browse' renders 404 when not found.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse no-matching-selector --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                      ]]\n\n  [[    \"${output}\"  =~  html                   ]]\n  [[    \"${output}\"  =~  \\<title\\>nb\\</title\\>  ]]\n  [[    \"${output}\"  =~  \\404\\ Not\\ Found       ]]\n}\n\n@test \"'browse' renders 404 when notebook is not found and id matches item in current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse example:1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                      ]]\n\n  [[    \"${output}\"  =~  html                   ]]\n  [[    \"${output}\"  =~  \\<title\\>nb\\</title\\>  ]]\n  [[    \"${output}\"  =~  \\404\\ Not\\ Found       ]]\n}\n\n# 415 #########################################################################\n\n@test \"'browse <file>' renders 415 with message when file is encrypted.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\"                \\\n      --content \"Example content.\"                \\\n      --encrypt                                   \\\n      --password password\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                   ]]\n\n  [[ \"${output}\" =~  html                                                 ]]\n  [[ \"${output}\" =~  header-crumbs                                        ]]\n  [[ \"${output}\" =~  \\<title\\>${_ME}\\ browse\\ home:1\\</title\\>            ]]\n  [[ \"${output}\" =~  415\\ Unsupported\\ Media\\ Type:\\ File\\ is\\ encrypted  ]]\n  [[ \"${output}\" =~  ↓                                                    ]]\n}\n\n@test \"'browse <folder>/<file>' renders 415 with message when file is encrypted.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" \\\n      --content \"Example content.\"                \\\n      --encrypt                                   \\\n      --password password\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1/1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                                                    ]]\n\n  [[ \"${output}\" =~  html                                                 ]]\n  [[ \"${output}\" =~  header-crumbs                                        ]]\n  [[ \"${output}\" =~  \\<title\\>${_ME}\\ browse\\ home:1/1\\</title\\>          ]]\n  [[ \"${output}\" =~  415\\ Unsupported\\ Media\\ Type:\\ File\\ is\\ encrypted  ]]\n  [[ \"${output}\" =~  ↓                                                    ]]\n}\n"
  },
  {
    "path": "test/browse-search.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --and / --or ################################################################\n\n@test \"'browse --container -q \\#tag2 --or \\#tag3' performs OR search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    \\\n      --title \"Title One\"         \\\n      --content \"Content one.\"\n\n    \"${_NB}\" add \"File Two.md\"    \\\n      --title \"Title Two\"         \\\n      --content \"Content #tag1 two.\"\n\n    \"${_NB}\" add \"File Three.md\"  \\\n      --title \"Title Three\"       \\\n      --content \"Content #tag2 three.\"\n\n    \"${_NB}\" add \"File Four.md\"   \\\n      --title \"Title Four\"        \\\n      --content \"Content #tag1 four.\"\n\n    \"${_NB}\" add \"File Five.md\"   \\\n      --title \"Title Five\"        \\\n      --content \"Content #tag2 #tag3 five.\"\n  }\n\n  run \"${_NB}\" browse --container -q \\#tag2 --or \\#tag3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}One    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Four   ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>    ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>     ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:5\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Five\\</a\\>\\<br\\>  ]]\n\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:3\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Three\\</a\\>\\<br\\> ]]\n}\n\n@test \"'browse --container -q \\#tag2 --and \\#tag3' performs AND search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    \\\n      --title \"Title One\"         \\\n      --content \"Content one.\"\n\n    \"${_NB}\" add \"File Two.md\"    \\\n      --title \"Title Two\"         \\\n      --content \"Content #tag1 two.\"\n\n    \"${_NB}\" add \"File Three.md\"  \\\n      --title \"Title Three\"       \\\n      --content \"Content #tag2 three.\"\n\n    \"${_NB}\" add \"File Four.md\"   \\\n      --title \"Title Four\"        \\\n      --content \"Content #tag1 four.\"\n\n    \"${_NB}\" add \"File Five.md\"   \\\n      --title \"Title Five\"        \\\n      --content \"Content #tag2 #tag3 five.\"\n  }\n\n  run \"${_NB}\" browse --container -q \\#tag2 --and \\#tag3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}One    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Three  ]]\n  [[ !  \"${output}\"   =~ Title${_S}Four   ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>    ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>     ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:5\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Five\\</a\\>\\<br\\>  ]]\n}\n\n# -t / --tag / --tags #########################################################\n\n@test \"'browse --container -t tag2 --and -t tag3' performs AND search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    \\\n      --title \"Title One\"         \\\n      --content \"Content one.\"\n\n    \"${_NB}\" add \"File Two.md\"    \\\n      --title \"Title Two\"         \\\n      --content \"Content #tag1 two.\"\n\n    \"${_NB}\" add \"File Three.md\"  \\\n      --title \"Title Three\"       \\\n      --content \"Content #tag2 three.\"\n\n    \"${_NB}\" add \"File Four.md\"   \\\n      --title \"Title Four\"        \\\n      --content \"Content #tag1 four.\"\n\n    \"${_NB}\" add \"File Five.md\"   \\\n      --title \"Title Five\"        \\\n      --content \"Content #tag2 #tag3 five.\"\n  }\n\n  run \"${_NB}\" browse --container -t tag2 --and -t tag3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}One    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Three  ]]\n  [[ !  \"${output}\"   =~ Title${_S}Four   ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>    ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>     ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:5\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Five\\</a\\>\\<br\\>  ]]\n}\n\n@test \"'browse --container -t tag2,tag3' performs AND search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    \\\n      --title \"Title One\"         \\\n      --content \"Content one.\"\n\n    \"${_NB}\" add \"File Two.md\"    \\\n      --title \"Title Two\"         \\\n      --content \"Content #tag1 two.\"\n\n    \"${_NB}\" add \"File Three.md\"  \\\n      --title \"Title Three\"       \\\n      --content \"Content #tag2 three.\"\n\n    \"${_NB}\" add \"File Four.md\"   \\\n      --title \"Title Four\"        \\\n      --content \"Content #tag1 four.\"\n\n    \"${_NB}\" add \"File Five.md\"   \\\n      --title \"Title Five\"        \\\n      --content \"Content #tag2 #tag3 five.\"\n  }\n\n  run \"${_NB}\" browse --container -t tag2,tag3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}One    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Three  ]]\n  [[ !  \"${output}\"   =~ Title${_S}Four   ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>    ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>     ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:5\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Five\\</a\\>\\<br\\>  ]]\n}\n\n@test \"'browse --container -t tag2 --or -t tag3' performs OR search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    \\\n      --title \"Title One\"         \\\n      --content \"Content one.\"\n\n    \"${_NB}\" add \"File Two.md\"    \\\n      --title \"Title Two\"         \\\n      --content \"Content #tag1 two.\"\n\n    \"${_NB}\" add \"File Three.md\"  \\\n      --title \"Title Three\"       \\\n      --content \"Content #tag2 three.\"\n\n    \"${_NB}\" add \"File Four.md\"   \\\n      --title \"Title Four\"        \\\n      --content \"Content #tag1 four.\"\n\n    \"${_NB}\" add \"File Five.md\"   \\\n      --title \"Title Five\"        \\\n      --content \"Content #tag2 #tag3 five.\"\n  }\n\n  run \"${_NB}\" browse --container -t tag2 --or -t tag3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}One    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Four   ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>    ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>     ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:5\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Five\\</a\\>\\<br\\>  ]]\n\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:3\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Three\\</a\\>\\<br\\> ]]\n}\n\n@test \"'browse --container -t tag2 -t tag3' performs AND search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    \\\n      --title \"Title One\"         \\\n      --content \"Content one.\"\n\n    \"${_NB}\" add \"File Two.md\"    \\\n      --title \"Title Two\"         \\\n      --content \"Content #tag1 two.\"\n\n    \"${_NB}\" add \"File Three.md\"  \\\n      --title \"Title Three\"       \\\n      --content \"Content #tag2 three.\"\n\n    \"${_NB}\" add \"File Four.md\"   \\\n      --title \"Title Four\"        \\\n      --content \"Content #tag1 four.\"\n\n    \"${_NB}\" add \"File Five.md\"   \\\n      --title \"Title Five\"        \\\n      --content \"Content #tag2 #tag3 five.\"\n  }\n\n  run \"${_NB}\" browse --container -t tag2 -t tag3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}One    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Three  ]]\n  [[ !  \"${output}\"   =~ Title${_S}Four   ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>    ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>     ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:5\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Five\\</a\\>\\<br\\>  ]]\n}\n\n@test \"'browse --container -t tag1' performs search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    \\\n      --title \"Title One\"         \\\n      --content \"Content one.\"\n\n    \"${_NB}\" add \"File Two.md\"    \\\n      --title \"Title Two\"         \\\n      --content \"Content #tag1 two.\"\n\n    \"${_NB}\" add \"File Three.md\"  \\\n      --title \"Title Three\"       \\\n      --content \"Content #tag2 three.\"\n\n    \"${_NB}\" add \"File Four.md\"   \\\n      --title \"Title Four\"        \\\n      --content \"Content #tag1 four.\"\n\n    \"${_NB}\" add \"File Five.md\"   \\\n      --title \"Title Five\"        \\\n      --content \"Content #tag3 five.\"\n  }\n\n  run \"${_NB}\" browse --container -t tag1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}One    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Three  ]]\n  [[ !  \"${output}\"   =~ Title${_S}Five   ]]\n\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:4\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Four\\</a\\>\\<br\\>  ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>    ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>     ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Two\\</a\\>\\<br\\>   ]]\n}\n\n@test \"'browse --container --tag #tag1' (hash) performs search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    \\\n      --title \"Title One\"         \\\n      --content \"Content one.\"\n\n    \"${_NB}\" add \"File Two.md\"    \\\n      --title \"Title Two\"         \\\n      --content \"Content #tag1 two.\"\n\n    \"${_NB}\" add \"File Three.md\"  \\\n      --title \"Title Three\"       \\\n      --content \"Content #tag2 three.\"\n\n    \"${_NB}\" add \"File Four.md\"   \\\n      --title \"Title Four\"        \\\n      --content \"Content #tag1 four.\"\n\n    \"${_NB}\" add \"File Five.md\"   \\\n      --title \"Title Five\"        \\\n      --content \"Content #tag3 five.\"\n  }\n\n  run \"${_NB}\" browse --container --tag \"#tag1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0           ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}One    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Three  ]]\n  [[ !  \"${output}\"   =~ Title${_S}Five   ]]\n\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:4\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Four\\</a\\>\\<br\\>  ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>    ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>     ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Two\\</a\\>\\<br\\>   ]]\n}\n\n@test \"'browse --container --tag tag1' (no hash) performs search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    \\\n      --title \"Title One\"         \\\n      --content \"Content one.\"\n\n    \"${_NB}\" add \"File Two.md\"    \\\n      --title \"Title Two\"         \\\n      --content \"Content #tag1 two.\"\n\n    \"${_NB}\" add \"File Three.md\"  \\\n      --title \"Title Three\"       \\\n      --content \"Content #tag2 three.\"\n\n    \"${_NB}\" add \"File Four.md\"   \\\n      --title \"Title Four\"        \\\n      --content \"Content #tag1 four.\"\n\n    \"${_NB}\" add \"File Five.md\"   \\\n      --title \"Title Five\"        \\\n      --content \"Content #tag3 five.\"\n  }\n\n  run \"${_NB}\" browse --container --tag \"tag1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}One    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Three  ]]\n  [[ !  \"${output}\"   =~ Title${_S}Five   ]]\n\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:4\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Four\\</a\\>\\<br\\>  ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>    ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>     ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Two\\</a\\>\\<br\\>   ]]\n}\n\n# notebook: selectors #########################################################\n\n@test \"'browse --query <query>' includes notebook selectors for results in the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.md\" --content \"Example 123 content.\"\n    \"${_NB}\" add \"Example Two.md\" --content \"Example content.\"\n\n    \"${_NB}\" add \"Sample Folder/Sample One.md\" --content \"Sample content.\"\n    \"${_NB}\" add \"Sample Folder/Sample Two.md\" --content \"Sample 123 content.\"\n  }\n\n  run \"${_NB}\" browse --query \"123\" --print\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:1\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]                   ]]\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>home:Sample${_S}Folder/2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n}\n\n@test \"'browse --query <query>' includes notebook selectors for results in a selected notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example One.md\" --content \"Example 123 content.\"\n    \"${_NB}\" add \"Example Notebook:Example Two.md\" --content \"Example content.\"\n\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample One.md\" --content \"Sample content.\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample Two.md\" --content \"Sample 123 content.\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:browse --query \"123\" --print\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>Example${_S}Notebook:1\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]                   ]]\n  [[    \"${output}\" =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>Example${_S}Notebook:Sample${_S}Folder/2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\] ]]\n}\n\n# local notebook ##############################################################\n\n@test \"'browse --query <query>' serves the search results from the local notebooks as a rendered HTML page with links to internal web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Title One\"         \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"File Two.md\"       \\\n      --title     \"Title Two\"         \\\n      --content   \"Example abcd efgh content.\"\n\n    \"${_NB}\" add  \"Example Folder\"    \\\n      --type      \"folder\"\n\n    declare _expected_param_pattern=\"--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\\&--columns=.*\\&--limit=.*\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print --query \"abcd efgh\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0                                             ]]\n  [[ \"${output}\"  =~  \\<\\!DOCTYPE\\ html\\>                           ]]\n\n  # header crumbs\n\n  [[ \"${output}\"  =~  \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>.*\\<a.*\\ href=\\\"//localhost:6789/\\?${_expected_param_pattern}\\\"\\>   ]]\n  [[ \"${output}\"  =~  \\\nhref=\\\"//localhost:6789/\\?${_expected_param_pattern}\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\> ]]\n  [[ \"${output}\"  =~  \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/local:\\?${_expected_param_pattern}\\\"\\>local\\</a\\>.*\\</nav\\>   ]]\n\n  # form\n\n  [[ \"${output}\"  =~  \\\naction=\\\"/local:\\?--columns=.*\\&--limit=.*\\&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\\\"      ]]\n\n  [[ \"${output}\"  =~  value=\\\"abcd\\ efgh\\\"\\>                                                ]]\n\n  [[ \"${output}\"  =~  \\\n\\<input\\ type=\\\"hidden\\\"\\ name=\\\"--local\\\"\\ \\ \\ \\ \\ value=\\\"${_TMP_DIR}/Local\\ Notebook\\\"\\> ]]\n\n  # list\n\n  [[ !  \"${output}\" =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/local:3\\?--columns=.*\\&--limit=.*\\&--local=.*\\\"\\ class=\\\"list-item\\\"\\> ]]\n  [[ !  \"${output}\" =~  .*\\[.*local:3.*\\].*${_S}📂${_S}Example${_S}Folder\\</a\\>\\<br\\>                 ]]\n\n  [[    \"${output}\" =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/local:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[    \"${output}\" =~  .*\\[.*local:2.*\\].*${_S}Title${_S}Two\\</a\\>\\<br\\>                   ]]\n\n  [[ !  \"${output}\" =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/local:1\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>   ]]\n  [[ !  \"${output}\" =~  .*\\[.*local:1.*\\].*${_S}Title${_S}One\\</a\\>\\<br\\>                   ]]\n}\n\n# normalization ###############################################################\n\n@test \"'browse --query' with spaces performs search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --title \"Title One\" --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\" --title \"Title Two\" --content \"Content abcd efgh two.\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -s \"http://localhost:6789/home:?--query=abcd%20efgh\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0         ]]\n\n  [[ !  \"${output}\"   =~ Title\\ One ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>   ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Two\\</a\\>\\<br\\> ]]\n\n  {\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -s \"http://localhost:6789/home:?--query=abcd+efgh\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0         ]]\n\n  [[ !  \"${output}\"   =~ Title\\ One ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>   ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Two\\</a\\>\\<br\\> ]]\n}\n\n# no matches ##################################################################\n\n@test \"'browse --container --query' with no match displays page with message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --title \"Title One\" --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\" --title \"Title Two\" --content \"Content abcde two.\"\n  }\n\n  run \"${_NB}\" browse --container --query \"non-matching-query\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n    \"Not${_NBSP}found:${_NBSP}non-matching-query\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n    \"placeholder=\\\"search\\\"${_NEWLINE}type=\\\"text\\\"${_NEWLINE}value=\\\"non-matching-query\\\">\"\n}\n\n@test \"'browse --container --query' with no match displays message with encoded query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --title \"Title One\" --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\" --title \"Title Two\" --content \"Content abcde two.\"\n  }\n\n  run \"${_NB}\" browse --container --query \"<script>alert(document.cookie)</script>\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  declare _amp='\\&'\n\n  [[    \"${status}\"  -eq  0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n    \"Not${_NBSP}found:${_NBSP}${_amp}#60;script${_amp}#62;alert${_amp}#40;document.cookie${_amp}#41;${_amp}#60;/script${_amp}#62;\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep   -q \\\n    \"placeholder=\\\"search\\\"${_NEWLINE}type=\\\"text\\\"${_NEWLINE}value=\\\"<script>alert(document.cookie)</script>\\\">\"\n}\n\n# search form #################################################################\n\n@test \"'browse' with container displays search form.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --title \"Title One\" --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\" --title \"Title Two\" --content \"Content abcde two.\"\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                       ]]\n\n  [[    \"${output}\"  =~   placeholder=\\\"search\\\"  ]]\n}\n\n@test \"'browse' with item does not display search form.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --title \"Title One\" --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\" --title \"Title Two\" --content \"Content abcde two.\"\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                       ]]\n\n  [[ !  \"${output}\"  =~   placeholder=\\\"search\\\"  ]]\n}\n\n# query #######################################################################\n\n@test \"'browse --container --query' with quotes performs search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"     \\\n      --title     \"Title One\"       \\\n      --content   \"One's content.\"\n    \"${_NB}\" add  \"File Two.md\"     \\\n      --title     \"Title Two\"       \\\n      --content   \"Two's \\\"quoted\\\" and unquoted content.\"\n  }\n\n  run \"${_NB}\" browse --container --query \"Two's \\\"quoted\\\" and\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0         ]]\n\n  [[ !  \"${output}\"   =~ Title\\ One ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>   ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Two\\</a\\>\\<br\\> ]]\n}\n\n@test \"'browse --container --query' with tag performs search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --title \"Title One\" --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\" --title \"Title Two\" --content \"Content #abcde two.\"\n  }\n\n  run \"${_NB}\" browse --container --query \"#abcde\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0         ]]\n\n  [[ !  \"${output}\"   =~ Title\\ One ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>   ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Two\\</a\\>\\<br\\> ]]\n}\n\n@test \"'browse --container --query' performs search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --title \"Title One\" --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\" --title \"Title Two\" --content \"Content abcde two.\"\n  }\n\n  run \"${_NB}\" browse --container --query \"abcde\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0         ]]\n\n  [[ !  \"${output}\"   =~ Title\\ One ]]\n\n  [[    \"${output}\"   =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>  ]]\n  [[    \"${output}\"   =~   \\\nclass=\\\"list-item\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>   ]]\n  [[    \"${output}\"   =~   \\\nidentifier\\\"\\>home:2\\</span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\</span\\>\\ Title\\ Two\\</a\\>\\<br\\> ]]\n}\n\n@test \"'browse --query' performs search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --title \"Title One\" --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\" --title \"Title Two\" --content \"Content abcde two.\"\n  }\n\n  run \"${_NB}\" browse --query \"abcde\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0         ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -v  -q \\\n    \"Title One\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n    \"placeholder=\\\"search\\\"${_NEWLINE}type=\\\"text\\\"${_NEWLINE}value=\\\"abcde\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n    \"<a.* href=\\\"//localhost:6789/home:2?--columns=.*&--limit=.*\\\" class=\\\"list-item\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n    \"class=\\\"list-item\\\"><span class=\\\"muted\\\">\\[</span><span class=\\\"identifier\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n    \"identifier\\\">home:2</span><span class=\\\"muted\\\">\\]</span> Title Two</a><br>\"\n}\n\n@test \"'browse --query \\\"<#hashtag>|<#hashtag>\\\"' performs OR search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"   --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"   --content \"Content #xyz two.\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\" --content \"Content #abcde three. #xyz\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"  --content \"Content #abcde four.\"\n    \"${_NB}\" add \"File Five.md\"   --title \"Title Five\"  --content \"Content #xyz five. #abcde\"\n  }\n\n\n  run \"${_NB}\" browse --query \"#xyz|#abcde\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                               ]]\n\n  [[    \"${output}\" =~ value=\\\"\\&#35\\;xyz\\|\\&#35\\;abcde\\\" ]]\n\n  [[    \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n\n  [[    \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n\n  [[    \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n\n  [[    \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n\n  [[ !  \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n\n}\n\n@test \"'browse --query <#hashtag> <#hashtag>' performs AND search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"   --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"   --content \"Content #xyz two.\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\" --content \"Content #abcde three. #xyz\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"  --content \"Content #abcde four.\"\n    \"${_NB}\" add \"File Five.md\"   --title \"Title Five\"  --content \"Content #xyz five. #abcde\"\n  }\n\n  run \"${_NB}\" browse --query \"#xyz #abcde\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                               ]]\n\n  [[    \"${output}\" =~ value=\\\"\\&#35\\;xyz\\ \\&#35\\;abcde\\\" ]]\n\n  [[    \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:5\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n\n  [[ !  \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:4\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n\n  [[    \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:3\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n\n  [[ !  \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n\n  [[ !  \"${output}\" =~ \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>\\<span\\  ]]\n}\n\n@test \"'browse --query <#hashtag>' performs search.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --title \"Title One\" --content \"Content one.\"\n    \"${_NB}\" add \"File Two.md\" --title \"Title Two\" --content \"Content #abcde two.\"\n  }\n\n  run \"${_NB}\" browse --query \"#abcde\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0         ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -v  -q \\\n    \"Title One\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n    \"placeholder=\\\"search\\\"${_NEWLINE}type=\\\"text\\\"${_NEWLINE}value=\\\"#abcde\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n    \"<a.* href=\\\"//localhost:6789/home:2?--columns=.*&--limit=.*\\\" class=\\\"list-item\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n    \"class=\\\"list-item\\\"><span class=\\\"muted\\\">\\[</span><span class=\\\"identifier\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep     -q \\\n    \"identifier\\\">home:2</span><span class=\\\"muted\\\">\\]</span> Title Two</a><br>\"\n}\n\n@test \"'browse --query' performs paginated search.\" {\n  {\n    \"${_NB}\" init\n\n    local _counter=0\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      _counter=\"$((_counter+1))\"\n\n      if (($((_counter % 2))))\n      then\n        \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n      else\n        \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\" \\\n          --content \"abcde${_NEWLINE}${_NEWLINE}abcde\"\n      fi\n    done\n  }\n\n  run \"${_NB}\" browse --query \"abcde\" --print --limit 2 --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[    \"${output}\"   =~ Title${_S}Eight  ]]\n  [[    \"${output}\"   =~ Title${_S}Four   ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}Six    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Ten    ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}Two    ]]\n\n  run \"${_NB}\" browse --query \"abcde\" --print --limit 2 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}Eight  ]]\n  [[ !  \"${output}\"   =~ Title${_S}Four   ]]\n\n  [[    \"${output}\"   =~ Title${_S}Six    ]]\n  [[    \"${output}\"   =~ Title${_S}Ten    ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}Two    ]]\n\n  run \"${_NB}\" browse --query \"abcde\" --print --limit 2 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0               ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}Eight  ]]\n  [[ !  \"${output}\"   =~ Title${_S}Four   ]]\n\n  [[ !  \"${output}\"   =~ Title${_S}Six    ]]\n  [[ !  \"${output}\"   =~ Title${_S}Ten    ]]\n\n  [[    \"${output}\"   =~ Title${_S}Two    ]]\n}\n"
  },
  {
    "path": "test/browse-serve.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# browse --serve ##############################################################\n\n@test \"'browse --serve' displays message with selector when notebook selector is specified before subcommand.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" Example\\ Notebook: browse --serve <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                ]]\n\n  [[    \"${output}\"  =~  \\\n^Listening:\\ .*http://localhost:${NB_SERVER_PORT}.*/Example%20Notebook:$  ]]\n}\n\n@test \"'browse --serve' displays message with selector and --local parameter with local notebook and notebook selector.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    declare _encoded_tmp_dir=\"${_TMP_DIR//$'/'/%2F}\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Notebook: --serve <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_encoded_tmp_dir}: '%s'\\\\n\" \"${_encoded_tmp_dir}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n\n  [[    \"${output}\"  =~  \\\n^Listening:\\ .*http://localhost:${NB_SERVER_PORT}.*/Example%20Notebook:\\?--local=${_encoded_tmp_dir}%2FLocal%20Notebook$ ]]\n}\n\n@test \"'browse --serve' displays message with selector and --local parameter with local notebook and folder.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    declare _encoded_tmp_dir=\"${_TMP_DIR//$'/'/%2F}\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/ --serve <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n\n  [[    \"${output}\"  =~  \\\n^Listening:\\ .*http://localhost:${NB_SERVER_PORT}.*/local:Example%20Folder/\\?--local=${_encoded_tmp_dir}%2FLocal%20Notebook$ ]]\n}\n\n@test \"'browse --serve' displays message with selector and --local parameter with local notebook.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    declare _encoded_tmp_dir=\"${_TMP_DIR//$'/'/%2F}\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --serve <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n\n  [[    \"${output}\"  =~  \\\n^Listening:\\ .*http://localhost:${NB_SERVER_PORT}.*/local:\\?--local=${_encoded_tmp_dir}%2FLocal%20Notebook$ ]]\n}\n\n@test \"'browse --serve' displays message without selector or params with current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --serve <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                ]]\n\n  [[    \"${output}\"  =~  \\\n^Listening:\\ .*http://localhost:${NB_SERVER_PORT}.*$      ]]\n  [[ !  \"${output}\"  =~  \\\n^Listening:\\ .*http://localhost:${NB_SERVER_PORT}/home:$  ]]\n}\n\n@test \"'browse --serve' displays message with selector when notebook selector is specified.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Notebook: --serve <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                ]]\n\n  [[    \"${output}\"  =~  \\\n^Listening:\\ .*http://localhost:${NB_SERVER_PORT}.*/Example%20Notebook:$  ]]\n}\n\n@test \"'browse --serve' displays message with selector when folder selector is specified.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Folder/ --serve <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                  ]]\n\n  [[    \"${output}\"  =~  \\\n^Listening:\\ .*http://localhost:${NB_SERVER_PORT}.*/home:Example%20Folder/$ ]]\n}\n\n@test \"'browse --serve' displays message with selector when notebook and folder selector is specified.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder/Example File.md\" --content \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse Example\\ Notebook:Example\\ Folder/ --serve <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                                ]]\n\n  [[    \"${output}\"  =~  \\\n^Listening:\\ .*http://localhost:${NB_SERVER_PORT}.*/Example%20Notebook:Example%20Folder/$ ]]\n}\n"
  },
  {
    "path": "test/browse.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# vustom css and javascript ####################################################\n\n@test \"'browse' omits custom css or javascript tags by default.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                           ]]\n\n  [[ !  \"${output}\"  =~   \\<link\\ rel=\\\"stylesheet\\\"  ]]\n  [[ !  \"${output}\"  =~   \\<script\\ src=              ]]\n}\n\n@test \"'browse' includes custom css and javascript tags with NB_CUSTOM_CSS and NB_CUSTOM_JS assigned.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n\n    declare _custom_css=\".example { color: blue; }\"\n    declare _custom_js=\"function example() { console.log(\\\"Example.\\\"); }\"\n\n    declare _custom_css_url=\"//--original/home/example.css\"\n    declare _custom_js_url=\"//--original/home/example.js\"\n  }\n\n  NB_CUSTOM_CSS=\"${_custom_css:-}\"  \\\n    NB_CUSTOM_JS=\"${_custom_js:-}\"  \\\n    run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0 ]]\n\n  [[ !  \"${output}\"  =~   \\<link\\ rel=\\\"stylesheet\\\"  ]]\n  [[ !  \"${output}\"  =~   \\<script\\ src=              ]]\n  [[    \"${output}\"  =~   \\\n\\<style\\>${_NEWLINE}.example\\ \\{\\ color:\\ blue\\;\\ \\}${_NEWLINE}\\</style\\>  ]]\n  [[    \"${output}\"  =~   \\\n\\<script\\>${_NEWLINE}function\\ example\\(\\)\\ \\{\\ console.log\\(\\\"Example.\\\"\\)\\;\\ \\}${_NEWLINE}\\</script\\> ]]\n}\n\n@test \"'browse' includes custom css and javascript tags with NB_CUSTOM_CSS and NB_CUSTOM_JAVASCRIPT assigned.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n\n    declare _custom_css=\".example { color: blue; }\"\n    declare _custom_js=\"function example() { console.log(\\\"Example.\\\"); }\"\n\n    declare _custom_css_url=\"//--original/home/example.css\"\n    declare _custom_js_url=\"//--original/home/example.js\"\n  }\n\n  NB_CUSTOM_CSS=\"${_custom_css:-}\"          \\\n    NB_CUSTOM_JAVASCRIPT=\"${_custom_js:-}\"  \\\n    run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0 ]]\n\n  [[ !  \"${output}\"  =~   \\<link\\ rel=\\\"stylesheet\\\"  ]]\n  [[ !  \"${output}\"  =~   \\<script\\ src=              ]]\n  [[    \"${output}\"  =~   \\\n\\<style\\>${_NEWLINE}.example\\ \\{\\ color:\\ blue\\;\\ \\}${_NEWLINE}\\</style\\> ]]\n  [[    \"${output}\"  =~   \\\n\\<script\\>${_NEWLINE}function\\ example\\(\\)\\ \\{\\ console.log\\(\\\"Example.\\\"\\)\\;\\ \\}${_NEWLINE}\\</script\\> ]]\n}\n\n@test \"'browse' includes custom css and javascript tags with NB_CUSTOM_CSS_URL and NB_CUSTOM_JS_URL assigned.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n\n    declare _custom_css=\".example { color: blue; }\"\n    declare _custom_js=\"function example() { console.log(\\\"Example.\\\"); }\"\n\n    declare _custom_css_url=\"//--original/home/example.css\"\n    declare _custom_js_url=\"//--original/home/example.js\"\n  }\n\n  NB_CUSTOM_CSS_URL=\"${_custom_css_url:-}\"  \\\n    NB_CUSTOM_JS_URL=\"${_custom_js_url:-}\"  \\\n    run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0 ]]\n\n  [[    \"${output}\"  =~   \\\n\\<link\\ rel=\\\"stylesheet\\\"\\ href=\\\"//--original/home/example.css\\\"/\\>     ]]\n  [[    \"${output}\"  =~   \\\n\\<script\\ src=\\\"//--original/home/example.js\\\"\\>\\</script\\>               ]]\n  [[ !  \"${output}\"  =~   \\\n\\<style\\>${_NEWLINE}.example\\ \\{\\ color:\\ blue\\;\\ \\}${_NEWLINE}\\</style\\> ]]\n  [[ !  \"${output}\"  =~   \\\n\\<script\\>${_NEWLINE}function\\ example\\(\\)\\ \\{\\ console.log\\(\\\"Example.\\\"\\)\\;\\ \\}${_NEWLINE}\\</script\\> ]]\n}\n\n@test \"'browse' includes custom css and javascript tags with NB_CUSTOM_CSS_URL and NB_CUSTOM_JAVASCRIPT_URL assigned.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n\n    declare _custom_css=\".example { color: blue; }\"\n    declare _custom_js=\"function example() { console.log(\\\"Example.\\\"); }\"\n\n    declare _custom_css_url=\"//--original/home/example.css\"\n    declare _custom_js_url=\"//--original/home/example.js\"\n  }\n\n  NB_CUSTOM_CSS_URL=\"${_custom_css_url:-}\"          \\\n    NB_CUSTOM_JAVASCRIPT_URL=\"${_custom_js_url:-}\"  \\\n    run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0 ]]\n\n  [[    \"${output}\"  =~   \\\n\\<link\\ rel=\\\"stylesheet\\\"\\ href=\\\"//--original/home/example.css\\\"/\\>     ]]\n  [[    \"${output}\"  =~   \\\n\\<script\\ src=\\\"//--original/home/example.js\\\"\\>\\</script\\>               ]]\n  [[ !  \"${output}\"  =~   \\\n\\<style\\>${_NEWLINE}.example\\ \\{\\ color:\\ blue\\;\\ \\}${_NEWLINE}\\</style\\> ]]\n  [[ !  \"${output}\"  =~   \\\n\\<script\\>${_NEWLINE}function\\ example\\(\\)\\ \\{\\ console.log\\(\\\"Example.\\\"\\)\\;\\ \\}${_NEWLINE}\\</script\\> ]]\n}\n\n# configuration ###############################################################\n\n@test \"'browse' sets the server hostname to localhost by default.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                       ]]\n\n  [[    \"${output}\"  =~   //localhost:6789/home:  ]]\n  [[ !  \"${output}\"  =~   //127.0.0.1:6789/home:  ]]\n}\n\n@test \"'browse' sets the server hostname to the value in \\$NB_SERVER_HOST.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  NB_SERVER_HOST=\"127.0.0.1\" run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                       ]]\n\n  [[    \"${output}\"  =~   //127.0.0.1:6789/home:  ]]\n  [[ !  \"${output}\"  =~   //localhost:6789/home:  ]]\n}\n\n@test \"'browse' sets the server port to 6789 by default.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                       ]]\n\n  [[    \"${output}\"  =~   //localhost:6789/home:  ]]\n  [[ !  \"${output}\"  =~   //localhost:4321/home:  ]]\n}\n\n@test \"'browse' sets the server port to the value in \\$NB_SERVER_PORT.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  NB_SERVER_PORT=\"4321\" run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq  0                       ]]\n\n  [[    \"${output}\"  =~   //localhost:4321/home:  ]]\n  [[ !  \"${output}\"  =~   //localhost:6789/home:  ]]\n}\n\n# conflicting folder and notebook names #######################################\n\n@test \"'browse <folder-id>' with conflicting folder and notebook names renders folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Conflicting Name/Example Folder File.md\"  \\\n      --content \"Example folder file content.\"\n\n    \"${_NB}\" notebooks add \"Example Conflicting Name\"\n    \"${_NB}\" notebooks use \"Example Conflicting Name\"\n\n    \"${_NB}\" add  \"Example Notebook File.md\"                        \\\n      --content   \"Example notebook file content.\"\n\n    \"${_NB}\" notebooks use \"home\"\n\n    [[   -f \"${NB_DIR}/home/Example Conflicting Name/Example Folder File.md\"  ]]\n    [[   -f \"${NB_DIR}/Example Conflicting Name/Example Notebook File.md\"     ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0 ]]\n\n  [[ \"${output}\"  =~  \\\nhref=\\\"//localhost:6789/\\?--columns=.*\\&--limit=.*\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>  ]]\n  [[ \"${output}\"  =~  \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>.*\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*\\&--limit=.*\\\"\\>    ]]\n  [[ \"${output}\"  =~  \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*\\&--limit=.*\\\"\\>home\\</a\\>\\ .*:.*\\        ]]\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1/\\?--columns=.*\\&--limit=.*\\\"\\>Example\\ Conflicting\\ Name\\</a\\>\\ .*/.*\\</strong\\>\\</nav\\>           ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1/1\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>.*\\[.*Example${_S}Conflicting${_S}Name/1.*\\].* ]]\n  [[ \"${output}\"  =~  \\\nclass=\\\"list-item\\\"\\>.*\\[.*Example${_S}Conflicting${_S}Name/1.*\\].*${_S}Example${_S}Folder${_S}File.md${_S}·  ]]\n  [[ \"${output}\"  =~  \\\n${_S}Example${_S}Folder${_S}File.md${_S}·${_S}\\\"Example${_S}folder.*\\</a\\>\\<br\\>                              ]]\n}\n\n# --original ##################################################################\n\n@test \"GET to --original URL with .svg file serves original svg file as 'Content-Type: image/svg+xml'.\" {\n  {\n    \"${_NB}\" init\n\n    cat <<HEREDOC > \"${_TMP_DIR}/example.svg\"\n<svg width=\"100\" height=\"100\">\n  <circle cx=\"50\" cy=\"50\" r=\"40\"\n  stroke=\"red\" stroke-width=\"4\" fill=\"blue\" />\n</svg>\nHEREDOC\n\n    \"${_NB}\" import \"${_TMP_DIR}/example.svg\"\n\n    declare _original_file_size=\n    _original_file_size=\"$(\n      wc -c <\"${_TMP_DIR}/example.svg\" | xargs\n    )\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D -                                           \\\n    \"http://localhost:6789/--original/home/example.svg\"       \\\n    -o \"${_TMP_DIR}/download.svg\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                       ]]\n\n  [[ \"${output}\"  =~  Content-Type:\\ image/svg\\+xml           ]]\n  [[ \"${output}\"  =~  Content-Length:\\ ${_original_file_size} ]]\n\n  diff                                                        \\\n    <(wc -c <\"${_TMP_DIR}/download.svg\")                      \\\n    <(wc -c <\"${_TMP_DIR}/example.svg\")\n\n  diff                                                        \\\n    <(_get_hash \"${_TMP_DIR}/download.svg\")                   \\\n    <(_get_hash \"${_TMP_DIR}/example.svg\")\n}\n\n@test \"GET to --original URL with .png file serves original png file as 'Content-Type: image/png'.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/nb.png\"\n\n    declare _original_file_size=\n    _original_file_size=\"$(\n      wc -c <\"${NB_TEST_BASE_PATH}/fixtures/nb.png\" | xargs\n    )\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D -                                           \\\n    \"http://localhost:6789/--original/home/nb.png\"            \\\n    -o \"${_TMP_DIR}/nb.png\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                       ]]\n\n  [[ \"${output}\"  =~  Content-Type:\\ image/png                ]]\n  [[ \"${output}\"  =~  Content-Length:\\ ${_original_file_size} ]]\n\n  diff                                                        \\\n    <(wc -c <\"${_TMP_DIR}/nb.png\")                            \\\n    <(wc -c <\"${NB_TEST_BASE_PATH}/fixtures/nb.png\")\n\n  diff                                                        \\\n    <(_get_hash \"${_TMP_DIR}/nb.png\")                         \\\n    <(_get_hash \"${NB_TEST_BASE_PATH}/fixtures/nb.png\")\n}\n\n@test \"GET to --original URL with .pdf file serves original pdf file as 'Content-Type: application/pdf'.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/example.pdf\"\n\n    declare _original_file_size=\n    _original_file_size=\"$(\n      wc -c <\"${NB_TEST_BASE_PATH}/fixtures/nb.pdf\" | xargs\n    )\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D -                                           \\\n    \"http://localhost:6789/--original/home/example.pdf\"       \\\n    -o \"${_TMP_DIR}/example.pdf\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                       ]]\n\n  [[ \"${output}\"  =~  Content-Type:\\ application/pdf          ]]\n  [[ \"${output}\"  =~  Content-Length:\\ ${_original_file_size} ]]\n\n  diff                                                        \\\n    <(wc -c <\"${_TMP_DIR}/example.pdf\")                       \\\n    <(wc -c <\"${NB_TEST_BASE_PATH}/fixtures/example.pdf\")\n\n  diff                                                        \\\n    <(_get_hash \"${_TMP_DIR}/example.pdf\")                    \\\n    <(_get_hash \"${NB_TEST_BASE_PATH}/fixtures/example.pdf\")\n}\n\n@test \"GET to --original URL with .html extension serves original html file as 'Content-Type: text/plain; charset=UTF-8'.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Example File.html\"  \\\n      --title     \"Example Title\"                     \\\n      --content   \"<!DOCTYPE html><html><head></head><body>Example</body></html>\"\n\n    declare _original_file_size=\n    _original_file_size=\"$(\n      wc -c <\"${NB_DIR}/home/Example Folder/Example File.html\" | xargs\n    )\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/--original/home/Example%20Folder/Example%20File.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                       ]]\n\n  [[ \"${output}\"  =~  Content-Type:\\ text/plain\\;\\ charset=UTF-8              ]]\n  [[ \"${output}\"  =~  Content-Length:\\ ${_original_file_size}                 ]]\n\n  [[ \"${output}\"  =~  \\#\\ Example\\ Title                                      ]]\n  [[ \"${output}\"  =~  \\\n\\<!DOCTYPE\\ html\\>\\<html\\>\\<head\\>\\</head\\>\\<body\\>Example\\</body\\>\\</html\\>  ]]\n}\n\n@test \"GET to --original URL with .md extension serves original markdown file with html content as 'Content-Type: text/plain; charset=UTF-8'.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Example File.md\"  \\\n      --title     \"Example Title\"                   \\\n      --content   \"<html><head></head><body>Example</body></html>\"\n\n    declare _original_file_size=\n    _original_file_size=\"$(\n      wc -c <\"${NB_DIR}/home/Example Folder/Example File.md\" | xargs\n    )\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/--original/home/Example%20Folder/Example%20File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n\n  [[ \"${output}\"  =~  Content-Type:\\ text/plain\\;\\ charset=UTF-8  ]]\n  [[ \"${output}\"  =~  Content-Length:\\ ${_original_file_size}     ]]\n\n  [[ \"${output}\"  =~  \\#\\ Example\\ Title                          ]]\n  [[ \"${output}\"  =~  \\\n\\<html\\>\\<head\\>\\</head\\>\\<body\\>Example\\</body\\>\\</html\\>        ]]\n}\n\n@test \"GET to --original URL serves file with no newlines.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Example File.md\"  \\\n      --title     \"Example Title\"\n\n    printf \"# Example Title\" > \"${NB_DIR}/home/Example Folder/Example File.md\"\n\n    \"${_NB}\" git checkpoint\n\n    declare _original_file_size=\n    _original_file_size=\"$(\n      wc -c <\"${NB_DIR}/home/Example Folder/Example File.md\" | xargs\n    )\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS --verbose -D - \\\n    \"http://localhost:6789/--original/home/Example%20Folder/Example%20File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n\n  [[ \"${output}\"  =~  Content-Type:\\ text/plain\\;\\ charset=UTF-8  ]]\n  [[ \"${output}\"  =~  Content-Length:\\ ${_original_file_size}     ]]\n\n  [[ \"${output}\"  =~  \\#\\ Example\\ Title                          ]]\n}\n\n@test \"GET to --original URL serves original markdown file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Example File.md\"  \\\n      --title       \"Example Title\"                 \\\n      --content     \"Example content.\"\n\n    declare _original_file_size=\n    _original_file_size=\"$(\n      wc -c <\"${NB_DIR}/home/Example Folder/Example File.md\" | xargs\n    )\"\n\n    (ncat                               \\\n      --exec \"${_NB} browse --respond\"  \\\n      --listen                          \\\n      --source-port \"6789\"              \\\n      2>/dev/null) &\n\n    sleep 1\n  }\n\n  run curl -sS -D - \"http://localhost:6789/--original/home/Example%20Folder/Example%20File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n\n  [[ \"${output}\"  =~  Content-Type:\\ text/plain\\;\\ charset=UTF-8  ]]\n  [[ \"${output}\"  =~  Content-Length:\\ ${_original_file_size}     ]]\n\n  [[ \"${output}\"  =~  \\#\\ Example\\ Title                          ]]\n  [[ \"${output}\"  =~  Example\\ content.                           ]]\n}\n\n# title #######################################################################\n\n@test \"'browse' sets HTML title.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                  ]]\n\n  [[    \"${output}\"  =~  '<title>nb browse home:</title>'   ]]\n  [[ !  \"${output}\"  =~  'h1 class=\"title\"'                 ]]\n  [[ !  \"${output}\"  =~  'title-block-header'               ]]\n}\n\n# css / styles ################################################################\n\n@test \"'browse' includes application styles.\" {\n  {\n    \"${_NB}\" init\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0         ]]\n\n  [[ \"${output}\"  =~  'html {'  ]]\n}\n\n# conflicting folder id / name ################################################\n\n@test \"'browse <folder>/' with conflicting id / folder name renders links to ids and labels to names.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n    \"${_NB}\" add \"Sample Folder/File One.md\" --content \"Example content.\"\n\n    \"${_NB}\" move \"Sample Folder\" \"1\" --force\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n    [[ -f \"${NB_DIR}/home/1/File One.md\"  ]]\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1/ --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0 ]]\n\n  [[ \"${output}\"  =~  \\\nhref=\\\"//localhost:6789/\\?--columns=.*\\&--limit=.*\\\"\\>\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>                    ]]\n  [[ \"${output}\"  =~  \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>.*\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*\\&--limit=.*\\\"\\>                      ]]\n  [[ \"${output}\"  =~  \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*\\&--limit=.*\\\"\\>home\\</a\\>\\ .*:.*\\                          ]]\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:1/\\?--columns=.*\\&--limit=.*\\\"\\>Example\\ Folder\\</a\\>\\ .*/.*\\</strong\\>\\</nav\\>  ]]\n\n  [[ \"${output}\"  =~  0${_NBSP}items. ]]\n\n  run \"${_NB}\" browse 2/ --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  ==  0 ]]\n\n  [[ \"${output}\"  =~  \\\n\\<nav\\ class=\\\"header-crumbs\\\"\\>\\<strong\\>\\<a.*\\ href=\\\"//localhost:6789/\\?--columns=.*\\&--limit=.*\\\"\\>\\<span ]]\n  [[ \"${output}\"  =~  \\\n\\<span\\ class=\\\"muted\\\"\\>❯\\</span\\>nb\\</a\\>                                                                   ]]\n  [[ \"${output}\"  =~  \\\n.*·.*\\ \\<a.*\\ href=\\\"//localhost:6789/home:\\?--columns=.*\\&--limit=.*\\\"\\>home\\</a\\>\\ .*:.*\\                   ]]\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2/\\?--columns=.*\\&--limit=.*\\\"\\>1\\</a\\>\\ .*/.*\\</strong\\>\\</nav\\>         ]]\n\n  [[ \"${output}\"  =~  \\\n\\<a.*\\ href=\\\"//localhost:6789/home:2/1\\?--columns=.*\\&--limit=.*\\\"\\ class=\\\"list-item\\\"\\>.*\\[.*1/1.*\\].*     ]]\n  [[ \"${output}\"  =~  \\\nclass=\\\"list-item\\\"\\>.*\\[.*1/1.*\\].*${_S}File${_S}One.md${_S}·${_S}\\\"Example${_S}content\\.\\\"\\</a\\>\\<br\\>      ]]\n}\n\n# headers #######################################################################\n\n@test \"'browse <selector> --print --headers' prints response headers.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" browse 1 --print --headers\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${#lines[@]}\" ==  5                                         ]]\n\n  [[ \"${lines[0]}\"  =~  HTTP/1.0\\ 200\\ OK                         ]]\n  [[ \"${lines[1]}\"  =~  Date:\\ .*                                 ]]\n  [[ \"${lines[2]}\"  =~  Expires:\\ .*                              ]]\n  [[ \"${lines[3]}\"  =~  Server:\\ nb                               ]]\n  [[ \"${lines[4]}\"  =~  Content-Type:\\ text/html\\;\\ charset=UTF-8 ]]\n}\n"
  },
  {
    "path": "test/configuration.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# configuration validation ####################################################\n\n@test \"'nb' with Bash 4 on macOS does not display prompt.\" {\n  if [[ \"${OSTYPE}\" =~ ^darwin ]]\n  then\n    if [[ \"${BASH_VERSINFO[0]:-}\" == 3  ]]\n    then\n      NB_TEST_MOCK_TTY=1 NB_BASH_UPDATE_PROMPT_ENABLED=0 run \"${_NB}\"\n    else\n      NB_TEST_MOCK_TTY=1 run \"${_NB}\"\n    fi\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[    \"${status}\"  -eq 0                            ]]\n\n    [[ !  \"${output}\"  =~  !.*\\ Update\\ Bash.*          ]]\n    [[ !  \"${output}\"   =~ Bash\\ 3.2\\ support\\ enabled. ]]\n    [[ !  \"${output}\"  =~  !.*\\ Updating\\ Bash.*\\.\\.\\.  ]]\n    [[ !  \"${output}\"  =~  Updated.*\\ to\\ .*Bash\\ 5     ]]\n\n    [[ ! -e \"${NB_DIR}/.nb-bash-3-enabled\"              ]]\n  fi\n}\n\n@test \"'nb' with Bash 3 on macOS displays prompt and updates Bash with affirmative response.\" {\n  if [[ \"${OSTYPE}\" =~ ^darwin ]]\n  then\n    if [[ \"${BASH_VERSINFO[0]:-}\" == 3  ]]\n    then\n      NB_TEST_MOCK_TTY=1 run \"${_NB}\" <<< \"y${_NEWLINE}\"\n    else\n      NB_TEST_MOCK_TTY=1 NB_BASH_UPDATE_PROMPT_ENABLED=1 run \"${_NB}\" <<< \"y${_NEWLINE}\"\n    fi\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n\n    [[ \"${status}\"  -eq 0                               ]]\n\n    [[    \"${output}\"  =~  !.*\\ Update\\ Bash.*          ]]\n    [[ !  \"${output}\"   =~ Bash\\ 3.2\\ support\\ enabled. ]]\n    [[    \"${output}\"  =~  !.*\\ Updating\\ Bash.*\\.\\.\\.  ]]\n    [[    \"${output}\"  =~  Updated.*\\ to\\ .*Bash\\ 5     ]]\n\n    [[ ! -e \"${NB_DIR}/.nb-bash-3-enabled\"              ]]\n  fi\n}\n\n@test \"'nb' with Bash 3 on macOS displays prompt and does not update Bash with disaffirmative response.\" {\n  if [[ \"${OSTYPE}\" =~ ^darwin ]]\n  then\n    if [[ \"${BASH_VERSINFO[0]:-}\" == 3  ]]\n    then\n      NB_TEST_MOCK_TTY=1 run \"${_NB}\" <<< \"n${_NEWLINE}\"\n    else\n      NB_TEST_MOCK_TTY=1 NB_BASH_UPDATE_PROMPT_ENABLED=1 run \"${_NB}\" <<< \"n${_NEWLINE}\"\n    fi\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n\n    [[ \"${status}\"  -eq 0                               ]]\n\n    [[    \"${output}\"  =~  !.*\\ Update\\ Bash.*          ]]\n    [[    \"${output}\"   =~ Bash\\ 3.2\\ support\\ enabled. ]]\n    [[ !  \"${output}\"  =~  !.*\\ Updating\\ Bash.*\\.\\.\\.  ]]\n    [[ !  \"${output}\"  =~  Updated.*\\ to\\ .*Bash\\ 5     ]]\n\n    [[   -e \"${NB_DIR}/.nb-bash-3-enabled\"              ]]\n  fi\n}\n\n# .nbrc #######################################################################\n\n@test \"'nb' recognizes setting in .nbrc.\" {\n  {\n    \"${_NB}\" init\n\n    printf \"export NB_COLOR_PRIMARY=123\\\\n\" >> \"${NBRC_PATH}\"\n  }\n\n  run \"${_NB}\" set get color_primary\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NBRC_PATH}\"\n\n\n  [[ \"${status}\"    -eq 0   ]]\n\n  [[ \"${lines[0]}\"  =~  123 ]]\n}\n\n@test \"'nb' resolves .nbrc with symlinked relative path.\" {\n  {\n    \"${_NB}\" init\n\n    printf \"export NB_COLOR_PRIMARY=123\\\\n\" >> \"${NBRC_PATH}\"\n\n    [[ \"$(\"${_NB}\" set get color_primary)\" == 123 ]]\n\n    _pwd=\"${PWD}\"\n\n    mkdir \"${_TMP_DIR}/Symlink Test\"\n\n    cd \"${_TMP_DIR}/Symlink Test\"\n\n    ln -s ../.nbrc .nbrc\n\n    cd \"${_pwd}\"\n\n    export NBRC_PATH=\"${_TMP_DIR}/Symlink Test/.nbrc\"\n  }\n\n  NBRC_PATH=\"${_TMP_DIR}/Symlink Test/.nbrc\" run \"${_NB}\" set get color_primary\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n\n  [[ \"${lines[0]}\"  =~  123 ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                           ]]\n\n  [[ \"${output}\"  =~  NBRC_PATH=.*${_TMP_DIR}/.nbrc ]]\n}\n"
  },
  {
    "path": "test/copy.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# templates ###################################################################\n\n@test \"'copy <item> <notebook>:' with \\$NB_DEFAULT_TEMPLATE assigned skips the template and copies item with <item> into <notebook>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    export NB_DEFAULT_TEMPLATE=\"Example template with no template tags.\"\n  }\n\n  run \"${_NB}\" copy \"Example Folder/Sample Folder/Example File.md\" \"Example Notebook:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                  ]]\n  [[ \"${lines[0]}\"  =~ Added                              ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Notebook:Example\\ File.md ]]\n\n  # Copies file:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example File.md'\n\n  # Adds to .index\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")  \\\n    <(printf \"Example File.md\\\\n\")\n}\n\n# argument ordering ###########################################################\n\n@test \"'<item> copy <notebook>:<existing-folder>/' (slash) with copies <item> into <notebook>:<existing-folder>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add \"Example Notebook:Demo Folder\" --type folder\n  }\n\n  run \"${_NB}\"                                      \\\n    \"Example Folder/Sample Folder/Example File.md\"  \\\n    copy                                            \\\n    \"Example Notebook:Demo Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                                ]]\n  [[ \"${lines[0]}\"  =~ Added                                            ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Notebook:Demo\\ Folder/Example\\ File.md  ]]\n\n  # Copies file:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Example File.md'\n\n  # Adds to .index\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")                            \\\n    <(printf \"Demo Folder\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/.index\")                \\\n    <(printf \"Example File.md\\\\n\")\n}\n\n@test \"'<item> <notebook>:<existing-folder>/ copy' (slash) with copies <item> into <notebook>:<existing-folder>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add \"Example Notebook:Demo Folder\" --type folder\n  }\n\n  run \"${_NB}\"                                      \\\n    \"Example Folder/Sample Folder/Example File.md\"  \\\n    \"Example Notebook:Demo Folder/\"                 \\\n    copy\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                                ]]\n  [[ \"${lines[0]}\"  =~ Added                                            ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Notebook:Demo\\ Folder/Example\\ File.md  ]]\n\n  # Copies file:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Example File.md'\n\n  # Adds to .index\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")                            \\\n    <(printf \"Demo Folder\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/.index\")                \\\n    <(printf \"Example File.md\\\\n\")\n}\n\n# `copy <item> <destination>` #################################################\n\n@test \"'copy <item> <notebook>:' with copies item with <item> into <notebook>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" copy \"Example Folder/Sample Folder/Example File.md\" \"Example Notebook:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                  ]]\n  [[ \"${lines[0]}\"  =~ Added                              ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Notebook:Example\\ File.md ]]\n\n  # Copies file:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example File.md'\n\n  # Adds to .index\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")  \\\n    <(printf \"Example File.md\\\\n\")\n}\n\n@test \"'copy <item> <notebook>:<existing-folder>/' (slash) with copies <item> into <notebook>:<existing-folder>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add \"Example Notebook:Demo Folder\" --type folder\n  }\n\n  run \"${_NB}\" copy                                 \\\n    \"Example Folder/Sample Folder/Example File.md\"  \\\n    \"Example Notebook:Demo Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                                ]]\n  [[ \"${lines[0]}\"  =~ Added                                            ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Notebook:Demo\\ Folder/Example\\ File.md  ]]\n\n  # Copies file:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Example File.md'\n\n  # Adds to .index\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")                            \\\n    <(printf \"Demo Folder\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/.index\")                \\\n    <(printf \"Example File.md\\\\n\")\n}\n\n@test \"'copy <item> <notebook>:<new-folder>/' (slash) with copies <item> into <notebook>:<new-folder>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[    -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/Example Notebook/Demo Folder\"       ]]\n  }\n\n  run \"${_NB}\" copy                                 \\\n    \"Example Folder/Sample Folder/Example File.md\"  \\\n    \"Example Notebook:Demo Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                                ]]\n  [[ \"${lines[0]}\"  =~ Added                                            ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Notebook:Demo\\ Folder/Example\\ File.md  ]]\n\n  # Copies file:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Example File.md'\n\n  # Adds to .index\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")                            \\\n    <(printf \"Demo Folder\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/.index\")                \\\n    <(printf \"Example File.md\\\\n\")\n}\n\n@test \"'copy <item> <notebook>:<new-filename>'with copies <item> to <notebook>:<new-filename>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[    -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/Example Notebook/Demo Identifier\"   ]]\n  }\n\n  run \"${_NB}\" copy                                 \\\n    \"Example Folder/Sample Folder/Example File.md\"  \\\n    \"Example Notebook:Demo Identifier\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[    \"${status}\"    == 0                                   ]]\n  [[    \"${lines[0]}\"  =~ Added                               ]]\n  [[    \"${lines[0]}\"  =~ Example\\ Notebook:Demo\\ Identifier  ]]\n  [[ !  \"${lines[0]}\"  =~ Example\\ File.md                    ]]\n\n  # Copies folder with contents:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Identifier\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Demo Identifier'\n\n  # Adds to .index\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")                            \\\n    <(printf \"Demo Identifier\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Identifier\")                   \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")\n}\n\n@test \"'copy <folder> <notebook>:<existing-file>' prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"   ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add \"Example Notebook:Demo Identifier\" --content \"Example new content.\"\n  }\n\n  run \"${_NB}\" copy                                 \\\n    \"Example Folder/Sample Folder/Example File.md\"  \\\n    \"Example Notebook:Demo Identifier\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 1                                      ]]\n  [[ \"${lines[0]}\"  =~ \\\n\\!.*\\ Already\\ exists:\\ .*Example\\ Notebook:Demo\\ Identifier  ]]\n\n  # Does not copy file:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Identifier\")                   \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  ||\n    return 0\n}\n\n# `copy <folder> <destination>` ###############################################\n\n@test \"'copy <folder> <notebook>:' with copies <folder> into <notebook>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" copy \"Example Folder/Sample Folder\" \"Example Notebook:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                ]]\n  [[ \"${lines[0]}\"  =~ Added                            ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Notebook:Sample\\ Folder ]]\n\n  # Copies folder with contents:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Sample Folder/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Sample Folder'\n\n  # Adds to .index\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")  \\\n    <(printf \"Sample Folder\\\\n\")\n}\n\n@test \"'copy <folder> <notebook>:<existing-folder>/' (slash) with copies <folder> into <notebook>:<existing-folder>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add \"Example Notebook:Demo Folder\" --type folder\n  }\n\n  run \"${_NB}\" copy \"Example Folder/Sample Folder\" \"Example Notebook:Demo Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                              ]]\n  [[ \"${lines[0]}\"  =~ Added                                          ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Notebook:Demo\\ Folder/Sample\\ Folder  ]]\n\n  # Copies folder with contents:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/Sample Folder/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Sample Folder'\n\n  # Adds to .index\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")                            \\\n    <(printf \"Demo Folder\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/.index\")                \\\n    <(printf \"Sample Folder\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/Sample Folder/.index\")  \\\n    <(printf \"Example File.md\\\\n\")\n}\n\n@test \"'copy <folder> <notebook>:<new-folder>/' (slash) with copies <folder> into <notebook>:<new-folder>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[    -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/Example Notebook/Demo Folder\"       ]]\n  }\n\n  run \"${_NB}\" copy \"Example Folder/Sample Folder\" \"Example Notebook:Demo Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                              ]]\n  [[ \"${lines[0]}\"  =~ Added                                          ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Notebook:Demo\\ Folder/Sample\\ Folder  ]]\n\n  # Copies folder with contents:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/Sample Folder/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Sample Folder'\n\n  # Adds to .index\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")                            \\\n    <(printf \"Demo Folder\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/.index\")                \\\n    <(printf \"Sample Folder\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/Sample Folder/.index\")  \\\n    <(printf \"Example File.md\\\\n\")\n}\n\n@test \"'copy <folder> <notebook>:<new-folder>' (no slash) with copies <folder> to <notebook>:<new-folder>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[    -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/Example Notebook/Demo Folder\"       ]]\n  }\n\n  run \"${_NB}\" copy \"Example Folder/Sample Folder\" \"Example Notebook:Demo Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[    \"${status}\"    == 0                               ]]\n  [[    \"${lines[0]}\"  =~ Added                           ]]\n  [[    \"${lines[0]}\"  =~ Example\\ Notebook:Demo\\ Folder  ]]\n  [[ !  \"${lines[0]}\"  =~ Sample\\ Folder                  ]]\n\n  # Copies folder with contents:\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Demo Folder'\n\n  # Adds to .index\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")                            \\\n    <(printf \"Demo Folder\\\\n\")\n\n  diff                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/.index\")                \\\n    <(printf \"Example File.md\\\\n\")\n}\n\n@test \"'copy <folder> <notebook>:<existing-folder>' (no slash) prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"   ]]\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add \"Example Notebook:Demo Folder\" --type folder\n  }\n\n  run \"${_NB}\" copy \"Example Folder/Sample Folder\" \"Example Notebook:Demo Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 1                                  ]]\n  [[ \"${lines[0]}\"  =~ \\\n\\!.*\\ Already\\ exists:\\ .*Example\\ Notebook:Demo\\ Folder  ]]\n\n  # Does not copy folder with contents:\n\n  [[ ! -e \"${NB_DIR}/Example Notebook/Demo Folder/Sample Folder\" ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Add: Demo Folder/Sample Folder'\n\n  # Does not add to .index\n\n  diff                                                      \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")              \\\n    <(printf \"Demo Folder\\\\n\")\n\n  diff                                                      \\\n    <(cat \"${NB_DIR}/Example Notebook/Demo Folder/.index\")  \\\n    <(printf \"\")\n}\n\n# `copy <folder>` #############################################################\n\n@test \"'copy <folder>' with folder copies folder.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n        --title   \"Example Title\"                                 \\\n        --content \"Example content.\"\n  }\n\n  run \"${_NB}\" copy \"Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\"    == 0                                ]]\n  [[ \"${lines[0]}\"  =~ Added                            ]]\n  [[ \"${lines[0]}\"  =~ Example\\ Folder/Sample\\ Folder-1 ]]\n\n  # Copies folder with contents:\n\n  diff                                                                      \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\")    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder-1/Example File.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example Folder/Sample Folder-1'\n\n  # Adds to .index\n\n  diff                                              \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")   \\\n    <(printf \"Sample Folder\\\\nSample Folder-1\\\\n\")\n}\n\n@test \"'copy <folder>/<filename>' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Example File.md\"  \\\n        --title   \"Example Title\"                   \\\n        --content \"Example content.\"\n  }\n\n  run \"${_NB}\" copy \"Example Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Prints output:\n\n  [[ \"${status}\" == 0                                     ]]\n  [[ \"${lines[0]}\" =~ Added                               ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/Example\\ File-1.md  ]]\n\n  # Copies file:\n\n  diff                                                        \\\n    <(cat \"${NB_DIR}/home/Example Folder/Example File.md\")    \\\n    <(cat \"${NB_DIR}/home/Example Folder/Example File-1.md\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example Folder/Example File-1.md'\n\n  # Adds to .index\n\n  diff                                                        \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")             \\\n    <(printf \"Example File.md\\\\nExample File-1.md\\\\n\")\n}\n\n# `copy <name>` ###############################################################\n\n@test \"'copy <name>' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" copy \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    == 0                ]]\n  [[ \"${lines[0]}\"  =~ Added            ]]\n  [[ \"${lines[0]}\"  =~ example-1.md     ]]\n\n  diff                                  \\\n    <(cat \"${NB_DIR}/home/example.md\")  \\\n    <(cat \"${NB_DIR}/home/example-1.md\")\n}\n\n@test \"'copy <name>' with binary file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"           \\\n      --title \"Example\"                 \\\n      --content \"Example content.\"      \\\n      --encrypt                         \\\n      --password password\n  }\n\n  run \"${_NB}\" copy \"example.md.enc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                   ]]\n  [[ \"${lines[0]}\" =~ Added             ]]\n  [[ \"${lines[0]}\" =~ example-1.md.enc  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/example.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR}/home/example-1.md.enc\")\" ]]\n\n  [[ \"$(\n        \"${_NB}\" show example.md.enc --password password --print --no-color\n      )\" =~ Example\\ content\\. ]]\n  [[ \"$(\n        \"${_NB}\" show example-1.md.enc --password password --print --no-color\n      )\" =~ Example\\ content\\. ]]\n}\n\n# `copy <id>` #################################################################\n\n@test \"'copy <id>' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" copy 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/example.md\")\" == \\\n     \"$(_get_hash \"${NB_DIR}/home/example-1.md\")\" ]]\n}\n\n@test \"'copy <id>' with binary file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"       \\\n      --title \"Example\"             \\\n      --content \"Example content.\"  \\\n      --encrypt                     \\\n      --password password\n  }\n\n  run \"${_NB}\" copy 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                   ]]\n  [[ \"${lines[0]}\" =~ Added             ]]\n  [[ \"${lines[0]}\" =~ example-1.md.enc  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/example.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR}/home/example-1.md.enc\")\" ]]\n\n  [[ \"$(\n        \"${_NB}\" show example.md.enc --password password --print --no-color\n      )\" =~ Example\\ content\\. ]]\n  [[ \"$(\n        \"${_NB}\" show example-1.md.enc --password password --print --no-color\n      )\" =~ Example\\ content\\. ]]\n}\n\n# `copy <title>` ##############################################################\n\n@test \"'copy <title>' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" copy Example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/example.md\")\" == \\\n     \"$(_get_hash \"${NB_DIR}/home/example-1.md\")\" ]]\n}\n\n# `copy <invalid>` ############################################################\n\n@test \"'copy <invalid>' exits with error message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" copy \"not-valid\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 1             ]]\n  [[ \"${lines[0]}\" =~ Not\\ found  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  [[ \"${#_files[@]}\" == 1 ]]\n}\n\n# `copy <selector>` filenames #################################################\n\n@test \"'copy <name>' with text file copies the note with sequential names.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" copy \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  run \"${_NB}\" copy \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-2.md  ]]\n\n  run \"${_NB}\" copy \"example-1.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                 ]]\n  [[ \"${lines[0]}\" =~ Added           ]]\n  [[ \"${lines[0]}\" =~ example-1-1.md  ]]\n\n  run \"${_NB}\" copy \"example-1.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                 ]]\n  [[ \"${lines[0]}\" =~ Added           ]]\n  [[ \"${lines[0]}\" =~ example-1-2.md  ]]\n\n  run \"${_NB}\" copy \"example-2.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                 ]]\n  [[ \"${lines[0]}\" =~ Added           ]]\n  [[ \"${lines[0]}\" =~ example-2-1.md  ]]\n\n  run \"${_NB}\" copy \"example-2.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                 ]]\n  [[ \"${lines[0]}\" =~ Added           ]]\n  [[ \"${lines[0]}\" =~ example-2-2.md  ]]\n}\n\n@test \"'copy <name>' with binary file copies the file with sequential names.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"       \\\n      --title \"Example\"             \\\n      --content \"Example content.\"  \\\n      --encrypt                     \\\n      --password password\n  }\n\n  run \"${_NB}\" copy \"example.md.enc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                   ]]\n  [[ \"${lines[0]}\" =~ Added             ]]\n  [[ \"${lines[0]}\" =~ example-1.md.enc  ]]\n\n  run \"${_NB}\" copy \"example.md.enc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                   ]]\n  [[ \"${lines[0]}\" =~ Added             ]]\n  [[ \"${lines[0]}\" =~ example-2.md.enc  ]]\n\n  run \"${_NB}\" copy \"example-1.md.enc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                     ]]\n  [[ \"${lines[0]}\" =~ Added               ]]\n  [[ \"${lines[0]}\" =~ example-1-1.md.enc  ]]\n\n  run \"${_NB}\" copy \"example-1.md.enc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                     ]]\n  [[ \"${lines[0]}\" =~ Added               ]]\n  [[ \"${lines[0]}\" =~ example-1-2.md.enc  ]]\n\n  run \"${_NB}\" copy \"example-2.md.enc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                     ]]\n  [[ \"${lines[0]}\" =~ Added               ]]\n  [[ \"${lines[0]}\" =~ example-2-1.md.enc  ]]\n\n  run \"${_NB}\" copy \"example-2.md.enc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                     ]]\n  [[ \"${lines[0]}\" =~ Added               ]]\n  [[ \"${lines[0]}\" =~ example-2-2.md.enc  ]]\n}\n\n# `<selector>` copy alternative ###############################################\n\n@test \"'<id> copy' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" 1 copy\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/example.md\")\" == \\\n     \"$(_get_hash \"${NB_DIR}/home/example-1.md\")\" ]]\n}\n\n# `copy <scope:selector>` #####################################################\n\n@test \"'copy <notebook>:<id>' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"example.md\" --title \"Example\" --content \"Example content.\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" copy one:1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR}/one/example.md\")\" == \\\n     \"$(_get_hash \"${NB_DIR}/one/example-1.md\")\" ]]\n}\n\n@test \"'<notebook>:<id> copy' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"example.md\" --title \"Example\" --content \"Example content.\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" one:1 copy\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR}/one/example.md\")\" == \\\n     \"$(_get_hash \"${NB_DIR}/one/example-1.md\")\" ]]\n}\n\n# `<notebook>:copy <selector>` ################################################\n\n@test \"'<notebook>:copy <id>' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"example.md\" --title \"Example\" --content \"Example content.\"\n\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" one:copy 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR}/one/example.md\")\" == \\\n     \"$(_get_hash \"${NB_DIR}/one/example-1.md\")\" ]]\n}\n\n@test \"'<id> <notebook>:copy' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"example.md\" --title \"Example\" --content \"Example content.\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" 1 one:copy\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR}/one/example.md\")\" == \\\n     \"$(_get_hash \"${NB_DIR}/one/example-1.md\")\" ]]\n}\n\n# duplicate ###################################################################\n\n@test \"'duplicate <id>' with text file copies file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" duplicate 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${lines[0]}\" =~ Added         ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/example.md\")\" == \\\n     \"$(_get_hash \"${NB_DIR_2}/home/example-1.md\")\" ]]\n}\n\n# help ########################################################################\n\n@test \"'copy' with no argument exits with status 1 and prints usage.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" copy\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1            ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\: ]]\n  [[ \"${lines[1]}\" =~ nb\\ copy  ]]\n}\n\n\n@test \"'help copy' exits with status 0 and prints usage.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" help copy\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0            ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\: ]]\n  [[ \"${lines[1]}\" =~ nb\\ copy  ]]\n}\n"
  },
  {
    "path": "test/count.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_count() {\n  \"${_NB}\" init\n  cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n  cat <<HEREDOC | \"${_NB}\" add \"second.md\"\n# two\nline two\nline three\nline four\nHEREDOC\n  cat <<HEREDOC | \"${_NB}\" add \"third.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n}\n\n# `count` #####################################################################\n\n@test \"'count' exits with 0 and prints count.\" {\n  {\n    _setup_count\n  }\n\n  run \"${_NB}\" count\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 3 ]]\n}\n\n@test \"'count --type <type>' exits with 0 and counts items of type.\" {\n  {\n    \"${_NB}\" init\n\n    cat <<HEREDOC | \"${_NB}\" add \"example.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"example.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" count --type document\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 2 ]]\n}\n\n# help ########################################################################\n\n@test \"'help count' exits with status 0.\" {\n  run \"${_NB}\" help count\n\n  [[ \"${status}\"    -eq 0       ]]\n}\n\n@test \"'help count' prints help information.\" {\n  run \"${_NB}\" help count\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Usage.*:  ]]\n  [[ \"${lines[1]}\" =~ nb\\ count ]]\n}\n"
  },
  {
    "path": "test/delete.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --quiet #####################################################################\n\n@test \"'rm <id> --quiet' deletes properly without printing output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"     ]]\n  }\n\n  run \"${_NB}\" rm 1 --force --quiet\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ -z \"${output:-}\" ]]\n}\n\n# notebooks ###################################################################\n\n_setup_notebooks() {\n  \"${_NB}\" init\n\n  mkdir -p \"${NB_DIR}/Example Notebook\"\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  git init\n\n  git remote add origin \"${_GIT_REMOTE_URL}\"\n\n  touch \"${NB_DIR}/Example Notebook/.index\"\n\n  cd \"${NB_DIR}\" || return 1\n}\n\n@test \"'delete <notebook>' with non-affirmative prompt response prints message and exits.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" delete \"Example Notebook\" <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                  ]]\n\n  [[ \"${output}\" =~ \\\nDeleting\\ .*Example\\ Notebook.*\\.|Moving\\ to\\ Trash:\\ .*Example\\ Notebook.* ]]\n  [[ \"${output}\" =~ Exiting.*\\.\\.\\.   ]]\n\n  [[ -e \"${NB_DIR}/Example Notebook\"  ]]\n}\n\n@test \"'delete <notebook>:' exits with 0 and deletes notebook.\" {\n  {\n    _setup_notebooks\n\n    [[   -e \"${NB_DIR}/Example Notebook\"      ]]\n  }\n\n  run \"${_NB}\" delete \"Example Notebook:\" <<< \"Example Notebook${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${output}\" =~ Notebook\\ deleted\\:       ]]\n  [[ \"${output}\" =~ Example\\ Notebook         ]]\n  [[ ! -e \"${NB_DIR}/Example Notebook\"        ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n}\n\n@test \"'delete <notebook>' exits with 0 and deletes notebook.\" {\n  {\n    _setup_notebooks\n\n    [[   -e \"${NB_DIR}/Example Notebook\"      ]]\n  }\n\n  run \"${_NB}\" delete \"Example Notebook\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${output}\" =~ Notebook\\ deleted\\:       ]]\n  [[ \"${output}\" =~ Example\\ Notebook         ]]\n  [[ ! -e \"${NB_DIR}/Exampl Notebook\"         ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n}\n\n# aliases #####################################################################\n\n@test \"'<notebook>:trash <id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example File.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/Example Notebook/.index\")\"\n\n    [[ -e \"${NB_DIR}/Example Notebook/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" Example\\ Notebook:trash 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                                  ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/Example Notebook/Example File.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"             ]]\n  [[    \"$(ls \"${NB_DIR}/Example Notebook\")\"  == \\\n          \"$(cat \"${NB_DIR}/Example Notebook/.index\")\"  ]]\n  [[    \"${_original_index}\"                  != \\\n          \"$(cat \"${NB_DIR}/Example Notebook/.index\")\"  ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                                                     ]]\n  [[ \"${output}\" =~   Deleted:                                              ]]\n  [[ \"${output}\" =~   Example\\ Notebook:1.*Example\\ File.md.*\\\"mock_editor  ]]\n}\n\n@test \"'<notebook>:rm <id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example File.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/Example Notebook/.index\")\"\n\n    [[ -e \"${NB_DIR}/Example Notebook/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" Example\\ Notebook:rm 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                                  ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/Example Notebook/Example File.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"             ]]\n  [[    \"$(ls \"${NB_DIR}/Example Notebook\")\"  == \\\n          \"$(cat \"${NB_DIR}/Example Notebook/.index\")\"  ]]\n  [[    \"${_original_index}\"                  != \\\n          \"$(cat \"${NB_DIR}/Example Notebook/.index\")\"  ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                                                     ]]\n  [[ \"${output}\" =~   Deleted:                                              ]]\n  [[ \"${output}\" =~   Example\\ Notebook:1.*Example\\ File.md.*\\\"mock_editor  ]]\n}\n\n@test \"'rm <id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"     ]]\n  }\n\n  run \"${_NB}\" rm 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                             ]]\n  [[ \"${output}\" =~   Deleted:                      ]]\n  [[ \"${output}\" =~   1.*example.md.*\\\"mock_editor  ]]\n}\n\n@test \"'<notebook>:- <id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example File.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/Example Notebook/.index\")\"\n\n    [[ -e \"${NB_DIR}/Example Notebook/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" Example\\ Notebook:- 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                                  ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/Example Notebook/Example File.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"             ]]\n  [[    \"$(ls \"${NB_DIR}/Example Notebook\")\"  == \\\n          \"$(cat \"${NB_DIR}/Example Notebook/.index\")\"  ]]\n  [[    \"${_original_index}\"                  != \\\n          \"$(cat \"${NB_DIR}/Example Notebook/.index\")\"  ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                                                     ]]\n  [[ \"${output}\" =~   Deleted:                                              ]]\n  [[ \"${output}\" =~   Example\\ Notebook:1.*Example\\ File.md.*\\\"mock_editor  ]]\n}\n\n@test \"'- <id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"     ]]\n  }\n\n  run \"${_NB}\" - 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                             ]]\n  [[ \"${output}\" =~   Deleted:                      ]]\n  [[ \"${output}\" =~   1.*example.md.*\\\"mock_editor  ]]\n}\n\n@test \"'d <id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"     ]]\n  }\n\n  run \"${_NB}\" d 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                             ]]\n  [[ \"${output}\" =~   Deleted:                      ]]\n  [[ \"${output}\" =~   1.*example.md.*\\\"mock_editor  ]]\n}\n\n# pins ########################################################################\n\n@test \"'delete' removes .pindex entry.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"Example Folder/File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin Example\\ Folder/1\n    \"${_NB}\" pin Example\\ Folder/4\n\n    diff                                        \\\n      <(printf \"File One.md\\\\nFile Four.md\\\\n\") \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n\n    run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"    -eq 0                             ]]\n    [[ \"${#lines[@]}\" -eq 4                             ]]\n\n    [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ 📌\\ Title\\ One  ]]\n    [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Folder/4.*].*\\ 📌\\ Title\\ Four ]]\n    [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/3.*].*\\ Title\\ Three    ]]\n    [[ \"${lines[3]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n  }\n\n  run \"${_NB}\" delete Example\\ Folder/4 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                               ]]\n  [[ \"${#lines[@]}\" -eq 1                               ]]\n\n  diff                          \\\n    <(printf \"File One.md\\\\n\")  \\\n    <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n\n  [[ \"${lines[0]}\"  =~  \\\nDeleted\\:\\ \\ .*[.*Example\\ Folder/4.*].*\\ .*File\\ Four.md.*\\ \\\"Title\\ Four\\\"   ]]\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                               ]]\n  [[ \"${#lines[@]}\" -eq 3                               ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ 📌\\ Title\\ One    ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Folder/3.*].*\\ Title\\ Three      ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two        ]]\n}\n\n# multiple selectors ##########################################################\n\n@test \"'delete <scope>:<selector>...' with multiple arguments deletes all.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Notebook One\"\n    \"${_NB}\" notebooks add \"Notebook Two\"\n    \"${_NB}\" notebooks add \"Notebook Three\"\n\n    \"${_NB}\" add  \"Home File.md\"                \\\n      --title     \"Example Title Home\"          \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Notebook One:Example Folder/Example File.md\" \\\n      --title     \"Example Title One\"                           \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Notebook Two:Sample File.md\" \\\n      --title     \"Example Title Two\"           \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Notebook Three:Demo Folder/Demo File.md\" \\\n      --title     \"Example Title Three\"                     \\\n      --content   \"Example content.\"\n\n\n    [[ -f \"${NB_DIR}/home/Home File.md\"                             ]]\n    [[ -f \"${NB_DIR}/Notebook One/Example Folder/Example File.md\"   ]]\n    [[ -f \"${NB_DIR}/Notebook Two/Sample File.md\"                   ]]\n    [[ -f \"${NB_DIR}/Notebook Three/Demo Folder/Demo File.md\"       ]]\n  }\n\n  run \"${_NB}\" delete --force         \\\n    1                                 \\\n    Notebook\\ One:1/Example\\ File.md  \\\n    Notebook\\ Two:Sample\\ File.md     \\\n    Notebook\\ Three:Demo\\ Folder/1    \\\n    --prompt-list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n  [[ \"${#lines[@]}\" -eq 9         ]]\n\n  [[ \"${lines[0]}\"  =~ Deleting:  ]]\n\n  [[ \"${lines[1]}\"  =~ \\\n      .*[.*1.*].*\\ .*Home\\ File.md.*\\ \\\"Example\\ Title\\ Home\\\"                  ]]\n\n  [[ \"${lines[2]}\"  =~ \\\n      .*[.*Notebook\\ One:Example\\ Folder/1.*].*\\ .*Notebook\\ One                ]]\n  [[ \"${lines[2]}\"  =~ \\\n      Notebook\\ One:Example\\ Folder/Example\\ File.md.*\\ \\\"Example\\ Title\\ One\\\" ]]\n\n  [[ \"${lines[3]}\"  =~ \\\n      .*[.*Notebook\\ Two:1.*].*\\ .*Notebook\\ Two:Sample\\ File.md                ]]\n  [[ \"${lines[3]}\"  =~ \\\n      Two:Sample\\ File.md.*\\ \\\"Example\\ Title\\ Two\\\"                            ]]\n\n  [[ \"${lines[4]}\"  =~ \\\n      .*[.*Notebook\\ Three:Demo\\ Folder/1.*].*\\ .*Notebook\\ Three:Demo          ]]\n  [[ \"${lines[4]}\"  =~ \\\n      Three:Demo\\ Folder/Demo\\ File.md.*\\ \\\"Example\\ Title\\ Three\\\"             ]]\n\n  [[ \"${lines[5]}\"  =~ \\\n      Deleted:\\ .*[.*1.*].*\\ .*Home\\ File.md.*\\ \\\"Example\\ Title\\ Home\\\"        ]]\n\n  [[ \"${lines[6]}\"  =~ \\\n      Deleted:\\ .*[.*Notebook\\ One:Example\\ Folder/1.*].*\\ .*Notebook\\ One      ]]\n  [[ \"${lines[6]}\"  =~ \\\n      Notebook\\ One:Example\\ Folder/Example\\ File.md.*\\ \\\"Example\\ Title\\ One\\\" ]]\n  [[ \"${lines[7]}\"  =~ \\\n      Deleted:\\ .*[.*Notebook\\ Two:1.*].*\\ .*Notebook\\ Two:Sample\\ File.md      ]]\n  [[ \"${lines[7]}\"  =~ \\\n      Two:Sample\\ File.md.*\\ \\\"Example\\ Title\\ Two\\\"                            ]]\n\n  [[ \"${lines[8]}\"  =~ \\\n      Deleted:\\ .*[.*Notebook\\ Three:Demo\\ Folder/1.*].*\\ .*Notebook\\           ]]\n  [[ \"${lines[8]}\"  =~ \\\n      Folder/1.*].*\\ .*Notebook\\ Three:Demo                                     ]]\n  [[ \"${lines[8]}\"  =~ \\\n      Three:Demo\\ Folder/Demo\\ File.md.*\\ \\\"Example\\ Title\\ Three\\\"             ]]\n}\n\n# no argument #################################################################\n\n@test \"'delete' with no argument exits with 1, prints help, and does not delete.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    [[ -e \"${NB_DIR}/home/example.md\" ]]\n  }\n\n  run \"${_NB}\" delete --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 1:\n\n  [[ \"${status}\" -eq 1                    ]]\n\n  # Does not delete file:\n\n  [[ -e \"${NB_DIR}/home/example.md\"       ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Delete'\n\n  # Prints help information:\n\n  [[ \"${lines[0]}\" =~ Usage.*\\:           ]]\n  [[ \"${lines[1]}\" =~ \\ \\ nb\\ delete      ]]\n}\n\n# .gitignored #################################################################\n\n@test \"'delete <selector>' with gitignored file returns 0 and deletes file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"sample.md\" --content \"Sample content.\"\n\n    printf \"example.md\\\\n\" > \"${NB_DIR}/home/.gitignore\"\n\n    \"${_NB}\" git add --all\n    \"${_NB}\" git checkpoint\n\n    printf \"Example content.\\\\n\" > \"${NB_DIR}/home/example.md\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"  ]]\n\n    \"${_NB}\" git check-ignore \"example.md\" > /dev/null\n  }\n\n  run \"${_NB}\" delete \"example.md\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0                       ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"             ]]\n  [[      \"${output}\" =~ Deleted\\:.*2.*example.md ]]\n}\n\n# <selector> ##################################################################\n\n@test \"'delete <selector>' with empty repo exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" delete 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1             ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found\\:  ]]\n  [[ \"${lines[0]}\"  =~  1             ]]\n}\n\n@test \"'delete <selector> (no force)' returns 0 and deletes file.\" {\n  skip \"Determine how to test interactive prompt.\"\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"  ]]\n  }\n\n  run \"${_NB}\" delete \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0           ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\" ]]\n}\n\n# <scope>:<selector> ##########################################################\n\n@test \"'delete <scope>:<selector>' with <filename> argument prints scoped output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n    \"${_NB}\" add \"example.md\"\n\n    printf \"home:list\\\\n\" && \"${_NB}\" home:list --no-id --filenames\n    printf \"one:list\\\\n\"  && \"${_NB}\" one:list  --no-id --filenames\n\n    \"${_NB}\" use \"home\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" delete one:example.md --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                     ]]\n  [[ \"${output}\" =~   Deleted:              ]]\n  [[ \"${output}\" =~   one:1.*one:example.md ]]\n}\n\n@test \"'<scope>:delete <selector>' with <filename> argument prints scoped output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n    \"${_NB}\" add \"example.md\"\n\n    printf \"home:list\\\\n\" && \"${_NB}\" home:list --no-id --filenames\n    printf \"one:list\\\\n\"  && \"${_NB}\" one:list  --no-id --filenames\n\n    \"${_NB}\" use \"home\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" one:delete \"example.md\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                     ]]\n  [[ \"${output}\" =~   Deleted:              ]]\n  [[ \"${output}\" =~   one:1.*one:example.md ]]\n}\n\n@test \"'<scope>:<selector> delete' with <filename> argument prints scoped output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n    \"${_NB}\" add \"example.md\"\n\n\n    printf \"home:list\\\\n\" && \"${_NB}\" home:list --no-id --filenames\n    printf \"one:list\\\\n\"  && \"${_NB}\" one:list  --no-id --filenames\n\n    \"${_NB}\" use \"home\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" one:example.md delete --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                     ]]\n  [[ \"${output}\" =~   Deleted:              ]]\n  [[ \"${output}\" =~   one:1.*one:example.md ]]\n}\n\n@test \"'<selector> <scope>:delete' with <filename> argument prints scoped output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n    \"${_NB}\" add \"example.md\"\n\n    printf \"home:list\\\\n\" && \"${_NB}\" home:list --no-id --filenames\n    printf \"one:list\\\\n\"  && \"${_NB}\" one:list  --no-id --filenames\n\n    \"${_NB}\" use \"home\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" example.md one:delete --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                     ]]\n  [[ \"${output}\" =~   Deleted:              ]]\n  [[ \"${output}\" =~   one:1.*one:example.md ]]\n}\n\n# <filename> ##################################################################\n\n@test \"'delete' with <filename> argument deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"     ]]\n  }\n\n  run \"${_NB}\" delete example.md --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                             ]]\n  [[ \"${output}\" =~   Deleted:                      ]]\n  [[ \"${output}\" =~   1.*example.md.*\\\"mock_editor  ]]\n}\n\n# <id> ########################################################################\n\n@test \"'delete <id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"  ]]\n  }\n\n  run \"${_NB}\" delete 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                             ]]\n  [[ \"${output}\" =~   Deleted:                      ]]\n  [[ \"${output}\" =~   1.*example.md.*\\\"mock_editor  ]]\n}\n\n@test \"'<id> delete' with deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"     ]]\n  }\n\n  run \"${_NB}\" 1 delete --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                             ]]\n  [[ \"${output}\" =~   Deleted:                      ]]\n  [[ \"${output}\" =~   1.*example.md.*\\\"mock_editor  ]]\n}\n\n# <path> ######################################################################\n\n@test \"'delete' with <path> argument deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/example.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"${NB_DIR}/home/example.md\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                             ]]\n  [[ \"${output}\" =~   Deleted:                      ]]\n  [[ \"${output}\" =~   1.*example.md.*\\\"mock_editor  ]]\n}\n\n# <title> #####################################################################\n\n@test \"'delete' with <title> argument deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/example.md\"     ]]\n  }\n\n  run \"${_NB}\" delete \"Example Title\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes note file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                               ]]\n  [[ \"${output}\" =~   Deleted:                        ]]\n  [[ \"${output}\" =~   1.*example.md.*\\\"Example\\ Title ]]\n}\n\n# <folder> #################################################################\n\n@test \"'delete' with <folder> argument deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ -e \"${NB_DIR}/home/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" delete \"Example Folder\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                    ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n  [[    \"${_original_index}\"      != \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                       ]]\n  [[ \"${output}\" =~   Deleted:                ]]\n  [[ \"${output}\" =~   1.*📂.*Example\\ Folder  ]]\n}\n\n# help ########################################################################\n\n@test \"'help delete' exits with status 0 and prints help information.\" {\n  run \"${_NB}\" help delete\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:    ]]\n  [[ \"${lines[1]}\"  =~  nb\\ delete  ]]\n}\n\n@test \"'help d' exits with status 0 and prints help information.\" {\n  run \"${_NB}\" help d\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:    ]]\n  [[ \"${lines[1]}\"  =~  nb\\ delete  ]]\n}\n\n@test \"'help -' exits with status 0 and prints help information.\" {\n  run \"${_NB}\" help -\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:    ]]\n  [[ \"${lines[1]}\"  =~  nb\\ delete  ]]\n}\n"
  },
  {
    "path": "test/do-undo.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031,SC2063\n\nload test_helper\n\n# error handling ##############################################################\n\n@test \"'do <id> <task-number>' with non-existent todo <id> exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" \"do\" 654 123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 1                         ]]\n  [[    \"${#lines[@]}\"  -eq 1                         ]]\n\n  [[    \"${lines[0]}\"   =~  .*!.*\\ Todo\\ not\\ found\\. ]]\n}\n\n@test \"'undo <id> <task-number>' with non-existent todo <id> exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" \"undo\" 654 123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 1                         ]]\n  [[    \"${#lines[@]}\"  -eq 1                         ]]\n\n  [[    \"${lines[0]}\"   =~  .*!.*\\ Todo\\ not\\ found\\. ]]\n}\n\n@test \"'do <id> <task-number>' with non-existent task exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" \"do\" Example\\ Folder/1 123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 1                         ]]\n  [[    \"${#lines[@]}\"  -eq 1                         ]]\n\n  [[    \"${lines[0]}\"   =~  .*!.*\\ Task\\ not\\ found\\. ]]\n}\n\n@test \"'undo <id> <task-number>' with non-existent task exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" \"undo\" Example\\ Folder/1 123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 1                         ]]\n  [[    \"${#lines[@]}\"  -eq 1                         ]]\n\n  [[    \"${lines[0]}\"   =~  .*!.*\\ Task\\ not\\ found\\. ]]\n}\n\n@test \"'do' with non-todo exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                          \\\n      --content   \"Example content one.\"  \\\n      --filename  \"File One.md\"\n  }\n\n  run \"${_NB}\" \"do\" 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                     ]]\n  [[ \"${output}\"    =~  \\!.*\\ Not\\ a\\ todo\\.  ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/File One.md\")   \\\n    <(printf \"Example content one.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Done'\n}\n\n@test \"'undo' with non-todo exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                          \\\n      --content   \"Example content one.\"  \\\n      --filename  \"File One.md\"\n  }\n\n  run \"${_NB}\" \"undo\" 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                     ]]\n  [[ \"${output}\"    =~  \\!.*\\ Not\\ a\\ todo\\.  ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/File One.md\")   \\\n    <(printf \"Example content one.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Done'\n}\n\n# do todo #####################################################################\n\n@test \"'do <notebook>:<folder>/<id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" \"do\" Example\\ Notebook:Example\\ Folder/2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nDone:\\ .*\\[.*Example\\ Notebook:Example\\ Folder/2.*\\].*\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\. ]]\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/One.todo.md\")    \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Two.todo.md\")    \\\n    <(printf \"# [x] Example todo description two.\\\\n\")\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Three.todo.md\")  \\\n    <(printf \"# [x] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/Example Notebook\" log | grep -q '\\[nb\\] Done: Example Folder/Two.todo.md'\n}\n\n@test \"'do <id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Three.todo.md\"\n  }\n\n  run \"${_NB}\" \"do\" 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nDone:\\ .*\\[.*2.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/One.todo.md\")   \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Two.todo.md\")   \\\n    <(printf \"# [x] Example todo description two.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Three.todo.md\") \\\n    <(printf \"# [x] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Done: Two.todo.md'\n}\n\n@test \"'do' with no selector exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" \"do\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                     ]]\n  [[ \"${lines[0]}\"  =~  Usage.*:              ]]\n  [[ \"${lines[1]}\"  =~  ${_ME}\\ todo          ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0                    ]]\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Done'\n}\n\n# do task #####################################################################\n\n@test \"'tasks do <folder>/<id> <task-number>' with non-todo and open task with no space in brackets exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" \"do\" Example\\ Folder/1 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  .*\\[.*Example\\ Folder/1.*].*\\ Example\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  [^-]------------------------------------[^-]      ]]\n  [[    \"${lines[2]}\"   =~  \\\nDone:\\ .*\\[.*Example\\ Folder/1\\ 2.*\\].*\\ .*[.*x.*].*\\ Task\\ two\\.             ]]\n}\n\n@test \"'tasks do <folder>/<id> <task-number>' with non-todo and open task with space in brackets exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" \"do\" Example\\ Folder/1 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  .*\\[.*Example\\ Folder/1.*].*\\ Example\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  [^-]------------------------------------[^-]      ]]\n  [[    \"${lines[2]}\"   =~  \\\nDone:\\ .*\\[.*Example\\ Folder/1\\ 2.*\\].*\\ .*[.*x.*].*\\ Task\\ two\\.             ]]\n}\n\n@test \"'tasks do <folder>/<id> <task-number>' with open task with no space in brackets exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" \"do\" Example\\ Folder/1 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/Todo One.todo.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\nDone:\\ .*\\[.*Example\\ Folder/1\\ 2.*\\].*\\ .*[.*x.*].*\\ Task\\ two\\. ]]\n}\n\n@test \"'tasks do <folder>/<id> <task-number>' with open task with space in brackets exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks \"do\" Example\\ Folder/1 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/Todo One.todo.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\nDone:\\ .*\\[.*Example\\ Folder/1\\ 2.*\\].*\\ .*[.*x.*].*\\ Task\\ two\\. ]]\n}\n\n# undo todo ###################################################################\n\n@test \"'undo <notebook>:<folder>/<id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" \"undo\" Example\\ Notebook:Example\\ Folder/3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nUndone:\\ .*\\[.*Example\\ Notebook:Example\\ Folder/3.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ three\\.  ]]\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/One.todo.md\")    \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Two.todo.md\")    \\\n    <(printf \"# [ ] Example todo description two.\\\\n\")\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Three.todo.md\")  \\\n    <(printf \"# [ ] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/Example Notebook\" log | grep -q '\\[nb\\] Undone: Example Folder/Three.todo.md'\n}\n\n@test \"'undo <id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Three.todo.md\"\n  }\n\n  run \"${_NB}\" \"undo\" 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nUndone:\\ .*\\[.*3.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ three\\. ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/One.todo.md\")   \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Two.todo.md\")   \\\n    <(printf \"# [ ] Example todo description two.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Three.todo.md\") \\\n    <(printf \"# [ ] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Undone: Three.todo.md'\n}\n\n@test \"'undo' with no selector exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" \"undo\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1             ]]\n  [[ \"${lines[0]}\"  =~  Usage.*:      ]]\n  [[ \"${lines[1]}\"  =~  ${_ME}\\ todo  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0            ]]\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Undone'\n}\n\n# undo task ###################################################################\n\n@test \"'undo <folder>/<id> <task-number>' with non-todo and closed task exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" \"undo\" Example\\ Folder/1 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  .*\\[.*Example\\ Folder/1.*].*\\ Example\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  [^-]------------------------------------[^-]      ]]\n  [[    \"${lines[2]}\"   =~  \\\nUndone:\\ .*\\[.*Example\\ Folder/1\\ 3.*\\].*\\ .*[\\ ].*\\ Task\\ three\\.            ]]\n}\n\n@test \"'undo <folder>/<id> <task-number>' with closed task exits with 0 and marks task open.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" \"undo\" Example\\ Folder/1 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/Todo One.todo.md\"\n\n  [[    \"${status}\"     -eq 0                                       ]]\n  [[    \"${#lines[@]}\"  -eq 3                                       ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\nUndone:\\ .*\\[.*Example\\ Folder/1\\ 3.*\\].*\\ .*[\\ ].*\\ Task\\ three\\.  ]]\n}\n\n# close alias #################################################################\n\n@test \"'close <id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Three.todo.md\"\n  }\n\n  run \"${_NB}\" \"close\" 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nDone:\\ .*\\[.*2.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/One.todo.md\")   \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Two.todo.md\")   \\\n    <(printf \"# [x] Example todo description two.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Three.todo.md\") \\\n    <(printf \"# [x] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Done: Two.todo.md'\n}\n\n# done alias ##################################################################\n\n@test \"'done <id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Three.todo.md\"\n  }\n\n  run \"${_NB}\" \"done\" 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nDone:\\ .*\\[.*2.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/One.todo.md\")   \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Two.todo.md\")   \\\n    <(printf \"# [x] Example todo description two.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Three.todo.md\") \\\n    <(printf \"# [x] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Done: Two.todo.md'\n}\n\n# undone alias ################################################################\n\n@test \"'undone <id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Three.todo.md\"\n  }\n\n  run \"${_NB}\" \"undone\" 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nUndone:\\ .*\\[.*3.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ three\\. ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/One.todo.md\")   \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Two.todo.md\")   \\\n    <(printf \"# [ ] Example todo description two.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Three.todo.md\") \\\n    <(printf \"# [ ] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Undone: Three.todo.md'\n}\n"
  },
  {
    "path": "test/edit.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031\n\nload test_helper\n\n# --quiet #####################################################################\n\n@test \"'<scope>:<selector> edit --quiet' edits  without printing output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"Example initial content.\"\n\n    _filename=$(\"${_NB}\" one:list -n 1 --no-id --filenames | head -1)\n\n    echo \"\\${_filename:-}: ${_filename:-}\"\n\n    [[ -n \"${_filename}\"                ]]\n    [[ -e \"${NB_DIR}/one/${_filename}\"  ]]\n  }\n\n  run \"${_NB}\" \"one:${_filename}\" edit --content \"Example content.\" --quiet\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/one/${_filename}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"EDITOR: '%s'\\\\n\" \"${EDITOR:-}\"\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/one/${_filename}\" \\\n    \"$(cat \"${NB_DIR}/one/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/one/${_filename}\")\" =~ Example\\ content\\.  ]]\n\n  # Does not print output:\n\n  [[ -z \"${output:-}\" ]]\n}\n\n# encrypted ###################################################################\n\n@test \"'edit' with openssl -md sha256 encrypted file edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n\n    diff                                                                      \\\n      <(\"${_NB}\" env | grep NB_ENCRYPTION_TOOL --color=never | cut -d= -f 2)  \\\n      <(printf \"openssl\\\\n\")\n\n    \"${_NB}\" add \"Example File.md\" --content \"# Content\"\n\n    [[    -f \"${NB_DIR}/home/Example File.md\"     ]]\n\n    openssl enc                                   \\\n      -aes-256-cbc                                \\\n      -md   sha256                                \\\n      -in   \"${NB_DIR}/home/Example File.md\"      \\\n      -out  \"${NB_DIR}/home/Example File.md.enc\"  \\\n      -pass file:<(printf \"password\\\\n\") 2> /dev/null\n\n    [[    -f \"${NB_DIR}/home/Example File.md.enc\" ]]\n\n    rm \"${NB_DIR}/home/Example File.md\"\n\n    [[ !  -f \"${NB_DIR}/home/Example File.md\"     ]]\n    [[    -f \"${NB_DIR}/home/Example File.md.enc\" ]]\n\n    declare _original_hash=\n    _original_hash=\"$(_get_hash \"${NB_DIR}/home/Example File.md.enc\")\"\n  }\n\n  run \"${_NB}\" edit \"Example File.md.enc\" --password=password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/Example File.md.enc\")\" != \"${_original_hash}\" ]]\n\n  \"${_NB}\" show \"Example File.md.enc\" --no-color --password=password\n\n  [[ \"$(\"${_NB}\" show \"Example File.md.enc\" --no-color --password=password)\"  =~ \\\n\\#\\ Content${_NEWLINE}\\#\\ mock_editor\\    ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'edit' with openssl -md md5 encrypted file edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n\n    diff                                                                      \\\n      <(\"${_NB}\" env | grep NB_ENCRYPTION_TOOL --color=never | cut -d= -f 2)  \\\n      <(printf \"openssl\\\\n\")\n\n    \"${_NB}\" add \"Example File.md\" --content \"# Content\"\n\n    [[    -f \"${NB_DIR}/home/Example File.md\"     ]]\n\n    openssl enc                                   \\\n      -aes-256-cbc                                \\\n      -md   md5                                   \\\n      -in   \"${NB_DIR}/home/Example File.md\"      \\\n      -out  \"${NB_DIR}/home/Example File.md.enc\"  \\\n      -pass file:<(printf \"password\\\\n\") 2> /dev/null\n\n    [[    -f \"${NB_DIR}/home/Example File.md.enc\" ]]\n\n    rm \"${NB_DIR}/home/Example File.md\"\n\n    [[ !  -f \"${NB_DIR}/home/Example File.md\"     ]]\n    [[    -f \"${NB_DIR}/home/Example File.md.enc\" ]]\n\n    declare _original_hash=\n    _original_hash=\"$(_get_hash \"${NB_DIR}/home/Example File.md.enc\")\"\n  }\n\n  run \"${_NB}\" edit \"Example File.md.enc\" --password=password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/Example File.md.enc\")\" != \"${_original_hash}\" ]]\n\n  \"${_NB}\" show \"Example File.md.enc\" --no-color --password=password\n\n  [[ \"$(\"${_NB}\" show \"Example File.md.enc\" --no-color --password=password)\"  =~ \\\n\\#\\ Content${_NEWLINE}\\#\\ mock_editor\\    ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'edit' with openssl-encrypted file and gpg NB_ENCRYPTION_TOOL edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set encryption_tool \"gpg\"\n\n    diff                                                                      \\\n      <(\"${_NB}\" env | grep NB_ENCRYPTION_TOOL --color=never | cut -d= -f 2)  \\\n      <(printf \"gpg\\\\n\")\n\n    NB_ENCRYPTION_TOOL=openssl \"${_NB}\" add \"# Content\" --encrypt --password=example\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n    _original_hash=\"$(_get_hash \"${NB_DIR}/home/${_filename}\")\"\n  }\n\n  run \"${_NB}\" edit 1 --password=example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/${_filename}\")\" != \"${_original_hash}\" ]]\n\n  [[ \"$(\"${_NB}\" show 1 --no-color --password=example)\"  =~ \\\n\\#\\ Content${_NEWLINE}\\#\\ mock_editor\\    ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'edit' with gpg-encrypted file and openssl NB_ENCRYPTION_TOOL edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n\n    diff                                                                      \\\n      <(\"${_NB}\" env | grep NB_ENCRYPTION_TOOL --color=never | cut -d= -f 2)  \\\n      <(printf \"openssl\\\\n\")\n\n    NB_ENCRYPTION_TOOL=gpg \"${_NB}\" add \"# Content\" --encrypt --password=example\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n    _original_hash=\"$(_get_hash \"${NB_DIR}/home/${_filename}\")\"\n  }\n\n  run \"${_NB}\" edit 1 --password=example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/${_filename}\")\" != \"${_original_hash}\" ]]\n\n  [[ \"$(\"${_NB}\" show 1 --no-color --password=example)\"  =~ \\\n\\#\\ Content${_NEWLINE}\\#\\ mock_editor\\  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'edit' with encrypted file edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Content\" --encrypt --password=example\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n    _original_hash=\"$(_get_hash \"${NB_DIR}/home/${_filename}\")\"\n  }\n\n  run \"${_NB}\" edit 1 --password=example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/${_filename}\")\" != \"${_original_hash}\" ]]\n\n  [[ \"$(\"${_NB}\" show 1 --no-color --password=example)\"  =~ \\\n\\#\\ Content${_NEWLINE}\\#\\ mock_editor\\    ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'edit' with piped content and encrypted file edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Example\" --encrypt --password=example\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n    _original_hash=\"$(_get_hash \"${NB_DIR}/home/${_filename}\")\"\n  }\n\n  run bash -c \"echo '## Piped' | ${_NB} edit 1 --password=example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  \"${_NB}\" show 1 --no-color --password=example\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/${_filename}\")\" != \"${_original_hash}\" ]]\n\n  [[ \"$(\"${_NB}\" show 1 --no-color --password=example)\"  =~ \\\n\\#\\ Example${_NEWLINE}\\#\\#\\ Piped         ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n# no argument #################################################################\n\n@test \"'edit' with no argument exits and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example initial content.\" --filename \"example.md\"\n\n    _original=\"$(cat \"${NB_DIR}/home/example.md\")\"\n  }\n\n  run \"${_NB}\" edit\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1 ]]\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/example.md\" \\\n    \"$(cat \"${NB_DIR}/home/example.md\")\"\n\n  # Does not update note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/example.md\" \\\n    \"$(cat \"${NB_DIR}/home/example.md\")\"\n\n  diff <(cat \"${NB_DIR}/home/example.md\") <(printf \"%s\\\\n\" \"${_original}\")\n\n  [[ ! \"$(cat \"${NB_DIR}/home/example.md\")\" =~ mock_editor ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  if [[ -n \"$(git status --porcelain)\" ]]\n  then\n    sleep 1\n  fi\n  git log | grep -q -v '\\[nb\\] Edit'\n\n  # Prints help information:\n\n  [[ \"${lines[0]}\" =~ Usage.*\\:     ]]\n  [[ \"${lines[1]}\" =~ \\ \\ nb\\ edit  ]]\n}\n\n# --content option ############################################################\n\n@test \"'edit' with --content option and content with leading dash appends new content.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add --title \"Example Title\" --content \"Example initial content.\"\n  }\n\n  run \"${_NB}\" edit 1 --content \"- Example new content with dash.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates note file:\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample initial content.\n\n- Example new content with dash.\nHEREDOC\n)\n\n  run \"${_NB}\" edit 1 --content \"- Sample new content with dash.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates note file:\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample initial content.\n\n- Example new content with dash.\n\n- Sample new content with dash.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Updated:\\ .*[.*1.*].*\\ .*example_title.md.*\\ \\\"Example\\ Title\\\" ]]\n}\n\n@test \"'edit' with --content option appends new content.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add --title \"Example Title\" --content \"Example initial content.\"\n  }\n\n  run \"${_NB}\" edit 1 --content \"Example new content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates note file:\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/example_title.md\")  \\\n    <(cat <<HEREDOC\n# Example Title\n\nExample initial content.\n\nExample new content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Updated:\\ .*[.*1.*].*\\ .*example_title.md.*\\ \\\"Example\\ Title\\\" ]]\n}\n\n@test \"'edit' with empty --content option exits with 1\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example initial content.\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n    _original=\"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n    [[ ! \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor ]]\n  }\n\n  run \"${_NB}\" edit 1 --content\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 1:\n\n  [[ ${status} -eq 1 ]]\n\n  # Does not update note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/${_filename}\" \\\n    \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  [[ ! \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor   ]]\n\n  diff <(cat \"${NB_DIR}/home/${_filename}\") <(printf \"%s\\\\n\" \"${_original}\")\n\n  # Prints error message:\n\n  [[ \"${output}\" =~ requires\\ a\\ valid\\ argument ]]\n}\n\n# --append, --overwite, & --prepend  ##########################################\n\n@test \"'edit --append --content <content>' appends <content> to file with extra newline.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                        \\\n      --filename \"Example Filename.md\"  \\\n      --content  \"Example initial content.\"\n  }\n\n  ##########\n  # edit 1 #\n\n  run \"${_NB}\" edit 1 --append --content \"Example new content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  cat \"${NB_DIR}/home/Example Filename.md\"\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample initial content.\n\nExample new content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n\n  ##########\n  # edit 2 #\n\n  run \"${_NB}\" edit 1 --append --content \"Example new content two.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample initial content.\n\nExample new content.\n\nExample new content two.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n}\n\n@test \"'edit --append <content>' appends <content> to file without extra newline.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                        \\\n      --filename \"Example Filename.md\"  \\\n      --content  \"Example initial content.\"\n  }\n\n  ##########\n  # edit 1 #\n\n  run \"${_NB}\" edit 1 --append \"Example new content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  cat \"${NB_DIR}/home/Example Filename.md\"\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample initial content.\nExample new content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n\n  ##########\n  # edit 2 #\n\n  run \"${_NB}\" edit 1 --append \"Example new content two.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  cat \"${NB_DIR}/home/Example Filename.md\"\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample initial content.\nExample new content.\nExample new content two.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n\n  ##########\n  # edit 3 #\n\n  run \"${_NB}\" edit 1 --append \"- Example new content three.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  cat \"${NB_DIR}/home/Example Filename.md\"\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample initial content.\nExample new content.\nExample new content two.\n- Example new content three.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n}\n\n\n@test \"'edit --prepend --content <content>' prepends <content> to file with extra newline.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                        \\\n      --filename \"Example Filename.md\"  \\\n      --content  \"Example initial content.\"\n  }\n\n  ##########\n  # edit 1 #\n\n  run \"${_NB}\" edit 1 --prepend --content \"Example new content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample new content.\n\nExample initial content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n\n  ##########\n  # edit 2 #\n\n  run \"${_NB}\" edit 1 --prepend --content \"Example new content two.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample new content two.\n\nExample new content.\n\nExample initial content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n}\n\n@test \"'edit --prepend <content>' prepends <content> to file without extra newline.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                        \\\n      --filename \"Example Filename.md\"  \\\n      --content  \"Example initial content.\"\n  }\n\n  ##########\n  # edit 1 #\n\n  run \"${_NB}\" edit 1 --prepend \"Example new content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  cat \"${NB_DIR}/home/Example Filename.md\"\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample new content.\nExample initial content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n\n  ##########\n  # edit 2 #\n\n  run \"${_NB}\" edit 1 --prepend \"Example new content two.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  cat \"${NB_DIR}/home/Example Filename.md\"\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample new content two.\nExample new content.\nExample initial content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n\n  ##########\n  # edit 3 #\n\n  run \"${_NB}\" edit 1 --prepend \"- Example new content three.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  cat \"${NB_DIR}/home/Example Filename.md\"\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\n- Example new content three.\nExample new content two.\nExample new content.\nExample initial content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n}\n\n@test \"'edit --prepend' prepends standard input to file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                        \\\n      --filename \"Example Filename.md\"  \\\n      --content  \"Example initial content.\"\n  }\n\n  run bash -c \"echo '## Piped Content' | ${_NB} edit 1 --prepend\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\n## Piped Content\nExample initial content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n}\n\n@test \"'edit --overwrite --content <content>' overwrites existing file content with content.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                        \\\n      --filename \"Example Filename.md\"  \\\n      --content  \"Example initial content.\"\n  }\n\n  run \"${_NB}\" edit 1 --overwrite --content \"Example new content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  diff \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\nExample new content.\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n}\n\n@test \"'edit --overwrite' overwrites existing content with standard input.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                        \\\n      --filename \"Example Filename.md\"  \\\n      --content  \"Example initial content.\"\n  }\n\n  run bash -c \"echo '## Piped Content' | ${_NB} edit 1 --overwrite\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Updates file:\n\n  diff \\\n    <(cat \"${NB_DIR}/home/Example Filename.md\") \\\n    <(cat <<HEREDOC\n## Piped Content\nHEREDOC\n)\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:              ]]\n  [[ \"${output}\" =~ [0-9]+                ]]\n  [[ \"${output}\" =~ Example\\ Filename.md  ]]\n}\n\n# --last option ###############################################################\n\n@test \"'edit --last' with empty repo exits and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" edit --last\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1 ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  if [[ -n \"$(git status --porcelain)\" ]]\n  then\n    sleep 1\n  fi\n  git log | grep -q -v '\\[nb\\] Edit'\n\n  # Prints help information:\n\n  [[ \"${lines[0]}\" =~ Usage.*\\:     ]]\n  [[ \"${lines[1]}\" =~ \\ \\ nb\\ edit  ]]\n}\n\n@test \"'edit --last' edits last modified item.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example initial content one.\" --filename \"example one.md\"\n    sleep 1\n    \"${_NB}\" add \"Example initial content two.\" --filename \"example two.md\"\n    sleep 1\n    \"${_NB}\" add \"Example initial content three.\" --filename \"example three.md\"\n    sleep 1\n\n    declare _original_content_one=\n    _original_content_one=\"$(cat \"${NB_DIR}/home/example one.md\")\"\n    declare _original_content_two=\n    _original_content_two=\"$(cat \"${NB_DIR}/home/example two.md\")\"\n    declare _original_content_three=\n    _original_content_three=\"$(cat \"${NB_DIR}/home/example three.md\")\"\n\n    declare -a _items_unedited=($(\n      \"${_NB}\" list \\\n        --empty     \\\n        --filenames \\\n        --no-color  \\\n        --no-id     \\\n        2>/dev/null || :))\n\n    printf \"\\$_items_unedited[0]: %s\\\\n\" \"${_items_unedited[0]}\"\n    printf \"\\$_items_unedited[1]: %s\\\\n\" \"${_items_unedited[1]}\"\n    printf \"\\$_items_unedited[2]: %s\\\\n\" \"${_items_unedited[2]}\"\n\n    [[ \"${_items_unedited[0]}\" == \"example three.md\" ]]\n    [[ \"${_items_unedited[1]}\" == \"example two.md\"   ]]\n    [[ \"${_items_unedited[2]}\" == \"example one.md\"   ]]\n\n    run \"${_NB}\" edit \"example two.md\" --content \"edit one\"\n\n    declare -a _items_after_edit_one=($(\n      \"${_NB}\" list \\\n        --empty     \\\n        --filenames \\\n        --no-color  \\\n        --no-id     \\\n        2>/dev/null || :))\n\n    printf \"\\$_items_after_edit_one[0]: %s\\\\n\" \"${_items_after_edit_one[0]}\"\n    printf \"\\$_items_after_edit_one[1]: %s\\\\n\" \"${_items_after_edit_one[1]}\"\n    printf \"\\$_items_after_edit_one[2]: %s\\\\n\" \"${_items_after_edit_one[2]}\"\n\n    [[ \"${_items_after_edit_one[0]}\" == \"example two.md\"    ]]\n    [[ \"${_items_after_edit_one[1]}\" == \"example three.md\"  ]]\n    [[ \"${_items_after_edit_one[2]}\" == \"example one.md\"    ]]\n\n\n    [[    \"$(cat \"${NB_DIR}/home/example two.md\")\" =~ edit\\ one   ]]\n    [[ !  \"$(cat \"${NB_DIR}/home/example two.md\")\" =~ mock_editor ]]\n  }\n\n  run \"${_NB}\" edit --last\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/example two.md\" \\\n    \"$(cat \"${NB_DIR}/home/example two.md\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/example two.md\")\" =~ edit\\ one   ]]\n  [[ \"$(cat \"${NB_DIR}/home/example two.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ example\\ two.md ]]\n}\n\n@test \"'edit --last' edits last modified item in subdirectory.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" folder add \"Example Folder\"\n\n    \"${_NB}\" add \"Example initial content one.\" --filename \"example one.md\"\n    sleep 1\n    \"${_NB}\" add \"Example initial content two.\" --filename \"Example Folder/example two.md\"\n    sleep 1\n    \"${_NB}\" add \"Example initial content three.\" --filename \"example three.md\"\n    sleep 1\n\n    declare _original_content_one=\n    _original_content_one=\"$(cat \"${NB_DIR}/home/example one.md\")\"\n    declare _original_content_two=\n    _original_content_two=\"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\"\n    declare _original_content_three=\n    _original_content_three=\"$(cat \"${NB_DIR}/home/example three.md\")\"\n\n    run \"${_NB}\" edit \"Example Folder/example two.md\" --content \"edit one\"\n\n    [[    \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\" =~ edit\\ one   ]]\n    [[ !  \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\" =~ mock_editor ]]\n  }\n\n  run \"${_NB}\" edit --last\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/Example Folder/example two.md\" \\\n    \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\" =~ edit\\ one   ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                        ]]\n  [[ \"${output}\" =~ [0-9]+                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/example\\ two.md ]]\n}\n\n@test \"'edit -l' edits last modified item.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example initial content one.\" --filename \"example one.md\"\n    sleep 1\n    \"${_NB}\" add \"Example initial content two.\" --filename \"example two.md\"\n    sleep 1\n    \"${_NB}\" add \"Example initial content three.\" --filename \"example three.md\"\n    sleep 1\n\n    declare _original_content_one=\n    _original_content_one=\"$(cat \"${NB_DIR}/home/example one.md\")\"\n    declare _original_content_two=\n    _original_content_two=\"$(cat \"${NB_DIR}/home/example two.md\")\"\n    declare _original_content_three=\n    _original_content_three=\"$(cat \"${NB_DIR}/home/example three.md\")\"\n\n    declare -a _items_unedited=($(\n      \"${_NB}\" list \\\n        --empty     \\\n        --filenames \\\n        --no-color  \\\n        --no-id     \\\n        2>/dev/null || :))\n\n    printf \"\\$_items_unedited[0]: %s\\\\n\" \"${_items_unedited[0]}\"\n    printf \"\\$_items_unedited[1]: %s\\\\n\" \"${_items_unedited[1]}\"\n    printf \"\\$_items_unedited[2]: %s\\\\n\" \"${_items_unedited[2]}\"\n\n    [[ \"${_items_unedited[0]}\" == \"example three.md\" ]]\n    [[ \"${_items_unedited[1]}\" == \"example two.md\"   ]]\n    [[ \"${_items_unedited[2]}\" == \"example one.md\"   ]]\n\n    run \"${_NB}\" edit \"example two.md\" --content \"edit one\"\n\n    declare -a _items_after_edit_one=($(\n      \"${_NB}\" list \\\n        --empty     \\\n        --filenames \\\n        --no-color  \\\n        --no-id     \\\n        2>/dev/null || :))\n\n    printf \"\\$_items_after_edit_one[0]: %s\\\\n\" \"${_items_after_edit_one[0]}\"\n    printf \"\\$_items_after_edit_one[1]: %s\\\\n\" \"${_items_after_edit_one[1]}\"\n    printf \"\\$_items_after_edit_one[2]: %s\\\\n\" \"${_items_after_edit_one[2]}\"\n\n    [[ \"${_items_after_edit_one[0]}\" == \"example two.md\"    ]]\n    [[ \"${_items_after_edit_one[1]}\" == \"example three.md\"  ]]\n    [[ \"${_items_after_edit_one[2]}\" == \"example one.md\"    ]]\n\n\n    [[    \"$(cat \"${NB_DIR}/home/example two.md\")\" =~ edit\\ one   ]]\n    [[ !  \"$(cat \"${NB_DIR}/home/example two.md\")\" =~ mock_editor ]]\n  }\n\n  run \"${_NB}\" edit -l\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/example two.md\" \\\n    \"$(cat \"${NB_DIR}/home/example two.md\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/example two.md\")\" =~ edit\\ one   ]]\n  [[ \"$(cat \"${NB_DIR}/home/example two.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ example\\ two.md ]]\n}\n\n@test \"'edit -l' edits last modified item in subdirectory.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" folder add \"Example Folder\"\n\n    \"${_NB}\" add \"Example initial content one.\" --filename \"example one.md\"\n    sleep 1\n    \"${_NB}\" add \"Example initial content two.\" --filename \"Example Folder/example two.md\"\n    sleep 1\n    \"${_NB}\" add \"Example initial content three.\" --filename \"example three.md\"\n    sleep 1\n\n    declare _original_content_one=\n    _original_content_one=\"$(cat \"${NB_DIR}/home/example one.md\")\"\n    declare _original_content_two=\n    _original_content_two=\"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\"\n    declare _original_content_three=\n    _original_content_three=\"$(cat \"${NB_DIR}/home/example three.md\")\"\n\n    run \"${_NB}\" edit \"Example Folder/example two.md\" --content \"edit one\"\n\n    [[    \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\" =~ edit\\ one   ]]\n    [[ !  \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\" =~ mock_editor ]]\n  }\n\n  run \"${_NB}\" edit -l\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/Example Folder/example two.md\" \\\n    \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\" =~ edit\\ one   ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/example two.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                        ]]\n  [[ \"${output}\" =~ [0-9]+                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/example\\ two.md ]]\n}\n\n# <selector> ##################################################################\n\n@test \"'edit <selector>' with empty repo exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" edit 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                ]]\n  [[ \"${lines[0]}\" =~ Not\\ found\\:  ]]\n  [[ \"${lines[0]}\" =~ 1             ]]\n}\n\n# <scope>:<selector> ##########################################################\n\n@test \"'edit <scope>:<selector>' with <filename> argument prints scoped output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"Example initial content.\" --filename \"example.md\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"                        ]]\n    [[ ! \"$(cat \"${NB_DIR}/one/example.md\")\" =~ mock_editor ]]\n  }\n\n  run \"${_NB}\" edit \"one:example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"EDITOR: '%s'\\\\n\" \"${EDITOR:-}\"\n  printf \"env EDITOR: '%s'\\\\n\" \"$(\"${_NB}\" env | grep 'EDITOR')\"\n\n  touch \"${_TMP_DIR}/editor-test.md\"\n  eval \"${EDITOR} \\\"${_TMP_DIR}/editor-test.md\\\"\"\n  printf \"cat \\${_TMP_DIR}/editor-test.md: '%s'\\\\n\"   \\\n    \"$(cat \"${_TMP_DIR}/editor-test.md\")\"\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/one/example.md\" \\\n    \"$(cat \"${NB_DIR}/one/example.md\")\"\n\n  [[ \"$(cat \"${NB_DIR}/one/example.md\")\" =~ mock_editor  ]]\n\n  [[ \"${output}\" =~ Updated:            ]]\n  [[ \"${output}\" =~ one\\:[0-9]+         ]]\n  [[ \"${output}\" =~ one:[A-Za-z0-9]+.md ]]\n}\n\n@test \"'<scope>:edit <selector>' with <filename> argument prints scoped output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"Example initial content.\"\n\n    _filename=$(\"${_NB}\" one: -n 1 --no-id --filenames | head -1)\n\n    echo \"\\${_filename:-}: ${_filename:-}\"\n\n    [[ -n \"${_filename}\"                                      ]]\n    [[ -e \"${NB_DIR}/one/${_filename}\"                        ]]\n    [[ ! \"$(cat \"${NB_DIR}/one/${_filename}\")\" =~ mock_editor ]]\n  }\n\n  run \"${_NB}\" one:edit \"${_filename}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"EDITOR: '%s'\\\\n\" \"${EDITOR:-}\"\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/one/${_filename}\" \\\n    \"$(cat \"${NB_DIR}/one/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/one/${_filename}\")\" =~ mock_editor  ]]\n\n  [[ \"${output}\" =~ Updated:            ]]\n  [[ \"${output}\" =~ one\\:[0-9]+         ]]\n  [[ \"${output}\" =~ one:[A-Za-z0-9]+.md ]]\n}\n\n@test \"'<scope>:<selector> edit' alternative with edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"Example initial content.\"\n\n    _filename=$(\"${_NB}\" one:list -n 1 --no-id --filenames | head -1)\n\n    echo \"\\${_filename:-}: ${_filename:-}\"\n\n    [[ -n \"${_filename}\"                ]]\n    [[ -e \"${NB_DIR}/one/${_filename}\"  ]]\n  }\n\n  run \"${_NB}\" \"one:${_filename}\" edit --content \"Example content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/one/${_filename}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"EDITOR: '%s'\\\\n\" \"${EDITOR:-}\"\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/one/${_filename}\" \\\n    \"$(cat \"${NB_DIR}/one/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/one/${_filename}\")\" =~ Example\\ content\\.  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:            ]]\n  [[ \"${output}\" =~ one\\:[0-9]+         ]]\n  [[ \"${output}\" =~ one:[A-Za-z0-9]+.md ]]\n}\n\n@test \"'<selector> <scope>:edit' alternative with edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"Example initial content.\"\n\n    _filename=$(\"${_NB}\" one:list -n 1 --no-id --filenames | head -1)\n\n    echo \"\\${_filename:-}: ${_filename:-}\"\n\n    [[ -n \"${_filename}\"                ]]\n    [[ -e \"${NB_DIR}/one/${_filename}\"  ]]\n  }\n\n  run \"${_NB}\" \"${_filename}\" one:edit --content \"Example content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/one/${_filename}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/one/${_filename}\" \\\n    \"$(cat \"${NB_DIR}/one/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/one/${_filename}\")\" =~ Example\\ content\\.  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:            ]]\n  [[ \"${output}\" =~ one\\:[0-9]+         ]]\n  [[ \"${output}\" =~ one:[A-Za-z0-9]+.md ]]\n}\n\n# <selector> (no changes) #####################################################\n\n@test \"'edit' with no changes does not print output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  export EDITOR=\"${NB_TEST_BASE_PATH}/fixtures/bin/mock_editor_no_op\" &&\n    run \"${_NB}\" edit \"${_filename}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0  ]]\n  [[ -z ${output}     ]]\n}\n\n@test \"'edit' encrypted with no changes does not print output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\" \\\n      --encrypt --password example\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  export EDITOR=\"${NB_TEST_BASE_PATH}/fixtures/bin/mock_editor_no_op\" &&\n    run \"${_NB}\" edit \"${_filename}\" --password example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0  ]]\n  [[ -z ${output}     ]]\n}\n\n# <filename> ##################################################################\n\n@test \"'edit' with <filename> argument edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  run \"${_NB}\" edit \"${_filename}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"EDITOR: '%s'\\\\n\" \"${EDITOR:-}\"\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/${_filename}\"    \\\n    \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'edit' with <filename> with spaces edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Note name with spaces.md\"\n\n    _filename=\"Note name with spaces.md\"\n\n    [[ -e \"${NB_DIR}/home/${_filename}\" ]]\n  }\n\n  run \"${_NB}\" edit \"${_filename}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/${_filename}\"    \\\n    \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                    ]]\n  [[ \"${output}\" =~ [0-9]+                      ]]\n  [[ \"${output}\" =~ Note\\ name\\ with\\ spaces.md ]]\n}\n\n# <id> ########################################################################\n\n@test \"'edit <id>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  run \"${_NB}\" edit 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/${_filename}\" \\\n    \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'<id> edit' alternative edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example initial content.\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n    [[ ! \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor ]]\n  }\n\n  run \"${_NB}\" 1 edit\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/${_filename}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/${_filename}\"    \\\n    \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n# <path> ######################################################################\n\n@test \"'edit' with <path> argument edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  run \"${_NB}\" edit \"${NB_DIR}/home/${_filename}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/${_filename}\"    \\\n    \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n# <title> #####################################################################\n\n@test \"'edit' with <title> argument edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add --title \"Example Title\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  run \"${_NB}\" edit \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/${_filename}\"    \\\n    \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n# piped #######################################################################\n\n@test \"'edit' with piped content edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Example\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n    _original=\"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  }\n\n  run bash -c \"echo '## Piped' | ${_NB} edit 1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/${_filename}\"        \\\n    \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" != \"${_original}\"   ]]\n  grep -q '# Example' \"${NB_DIR}/home\"/*\n  grep -q '## Piped' \"${NB_DIR}/home\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n# $EDITOR #####################################################################\n\n@test \"'edit <id>' with multi-word \\$EDITOR edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add --content \"Example\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n    \"${_NB}\" set editor \"mock_editor --flag\"\n  }\n\n  run \"${_NB}\" edit 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/${_filename}\"    \\\n    \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ mock_editor  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n@test \"'edit <id>' with multi-word \\$EDITOR edits properly with filename with spaces.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add --filename \"multi-word filename.md\"\n\n    \"${_NB}\" set editor \"mock_editor --flag\"\n  }\n\n  run \"${_NB}\" edit 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates note file:\n\n  printf \"cat %s:\\\\n%s\\\\n\" \"${NB_DIR}/home/multi-word filename.md\"    \\\n    \"$(cat \"${NB_DIR}/home/multi-word filename.md\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/multi-word filename.md\")\" =~ mock_editor  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"git log --stat:\\\\n%s\\\\n\" \"$(git log --stat)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:        ]]\n  [[ \"${output}\" =~ [0-9]+          ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n# help ########################################################################\n\n@test \"'help edit' exits with status 0 and prints help information.\" {\n  run \"${_NB}\" help edit\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\:     ]]\n  [[ \"${lines[1]}\" =~ \\ \\ nb\\ edit  ]]\n}\n"
  },
  {
    "path": "test/env.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'env' exits with status 0 and prints output.\" {\n  run \"${_NB}\" env\n\n  printf \"\\${status}:       '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:       '%s'\\\\n\" \"${output}\"\n  printf \"\\$(tput colors):  '%s'\\\\n\" \"$(tput colors)\"\n\n  [[ \"${status}\"  -eq 0         ]]\n  [[ \"${output}\"  =~  NB_EDITOR ]]\n}\n\n# EDITOR ######################################################################\n\n@test \"'env' with EDITOR sets editor.\" {\n  EDITOR='example-editor' run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[30]}\" =~ NB_EDITOR=example-editor     ]]\n}\n\n@test \"'env' with NB_EDITOR sets editor.\" {\n  EDITOR='' NB_EDITOR='example-nb-editor' VISUAL='' run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[30]}\" =~ NB_EDITOR=example-nb-editor  ]]\n}\n\n@test \"'env' with VISUAL sets editor.\" {\n  EDITOR='' VISUAL='example-visual' run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[30]}\" =~ NB_EDITOR=example-visual     ]]\n}\n"
  },
  {
    "path": "test/export.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# edge cases ##################################################################\n\n@test \"'export pandoc' with front matter title containing a colon requires quotes around title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                      \\\n        --filename  \"Example File.md\" \\\n        --content   \"$(cat <<HEREDOC\n---\ntitle: 20240101010101 - Example Title Prefix: Example Title Content\npublic: true\ndate: 2024-01-01T01:01:01.010101+00:00\nid: 20240101010101\n---\n\n# Example Title Content\n\n<https://example.com>\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" export 1 \"${_TMP_DIR}/example.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0               ]]\n\n  [[ ! -e \"${_TMP_DIR}/example.html\"    ]]\n\n  [[    \"${output}\" =~ YAML             ]]\n\n  [[ !  \"${output}\" =~ Exported         ]]\n  [[ !  \"${output}\" =~ Example\\ File    ]]\n\n  {\n    \"${_NB}\" add                      \\\n        --filename  \"Example File.md\" \\\n        --content   \"$(cat <<HEREDOC\n---\ntitle: \"20240101010101 - Example Title Prefix: Example Title Content\"\npublic: true\ndate: 2024-01-01T01:01:01.010101+00:00\nid: 20240101010101\n---\n\n# Example Title Content\n\n<https://example.com>\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" export 2 \"${_TMP_DIR}/example.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0               ]]\n\n  cat \"${_TMP_DIR}/example.html\"\n\n  [[ -e \"${_TMP_DIR}/example.html\"      ]]\n  grep -q 'DOCTYPE html' \"${_TMP_DIR}/example.html\"\n\n  [[ !  \"${output}\" =~ YAML             ]]\n\n  [[    \"${output}\" =~ Exported         ]]\n  [[    \"${output}\" =~ Example\\ File-1  ]]\n}\n\n# embedded resources ##########################################################\n\n@test \"'export pandoc --self-contained' with reference to image in same directory embeds image.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                                                      \\\n      --content   \"# Export Example${_NEWLINE}${_NEWLINE}![](nb.png)\" \\\n      --filename  \"Example File.md\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/nb.png\"\n\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n    [[ -f \"${NB_DIR}/home/nb.png\"           ]]\n  }\n\n  run \"${_NB}\" export pandoc 1 --self-contained <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${output}\" =~ \\<p\\>\\<img\\ role=\\\"img\\\"\\ src=\\\"data:image/png\\;base64,iVBORw0KGgoAAAA ]]\n\n  run ! diff                      \\\n    <(printf \"%s\\\\n\" \"${output}\") \\\n    <(cat <<HEREDOC\n[WARNING] Could not fetch resource nb.png\n<h1 id=\"export-example\">Export Example</h1>\n<p><img src=\"nb.png\" /></p>\nHEREDOC\n    )\n}\n\n@test \"'export --self-contained' with reference to image in same directory embeds image.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                                                      \\\n      --content   \"# Export Example${_NEWLINE}${_NEWLINE}![](nb.png)\" \\\n      --filename  \"Example File.md\"\n\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/nb.png\"\n\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n    [[ -f \"${NB_DIR}/home/nb.png\"           ]]\n  }\n\n  run \"${_NB}\" export 1 \"${_TMP_DIR}/example.html\" --self-contained <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"$(cat \"${_TMP_DIR}/example.html\")\" =~ \\<p\\>\\<img\\ role=\\\"img\\\"\\ src=\\\"data:image/png\\;base64,iVBORw0KGgoAAAA ]]\n}\n\n# existing file ###############################################################\n\n@test \"'export' with file at export path prompts user to confirm overwrite.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"# Export Example\"\n\n    echo \"Example existing content.\" >> \"${_TMP_DIR}/example.md\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n    [[ -f \"${_TMP_DIR}/example.md\"          ]]\n  }\n\n  run \"${_NB}\" export 1 \"${_TMP_DIR}/example.md\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls  \"${_TMP_DIR}\"\n  cat \"${_TMP_DIR}/example.md\"\n\n  [[ -f \"${_TMP_DIR}/example.md\" ]]\n\n  grep -q '# Export Example' \"${_TMP_DIR}/example.md\"\n\n  diff                              \\\n    <(cat \"${_TMP_DIR}/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example File.md\")\n\n  [[ \"${output}\" =~ Exported    ]]\n  [[ \"${output}\" =~ example.md  ]]\n}\n\n@test \"'export' with file at export path and non-affirmative prompt response exits without overwriting.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"# Export Example\"\n\n    echo \"Example existing content.\" >> \"${_TMP_DIR}/example.md\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n    [[ -f \"${_TMP_DIR}/example.md\"          ]]\n  }\n\n  run \"${_NB}\" export 1 \"${_TMP_DIR}/example.md\" <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls  \"${_TMP_DIR}\"\n  cat \"${_TMP_DIR}/example.md\"\n\n  [[ -f \"${_TMP_DIR}/example.md\" ]]\n\n  grep -q -v '# Export Example' \"${_TMP_DIR}/example.md\"\n\n  diff                              \\\n    <(cat \"${_TMP_DIR}/example.md\") \\\n    <(printf \"Example existing content.\\\\n\")\n\n  [[ \"${lines[0]}\" =~ File\\ exists\\ at\\ .*${_TMP_DIR}/example.md  ]]\n  [[ \"${lines[1]}\" =~ Exiting.*\\.\\.\\.                             ]]\n}\n\n# no argument #################################################################\n\n@test \"'export' with no arguments exits with status 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n  }\n\n  run \"${_NB}\" export\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 1               ]]\n  [[ \"${lines[0]}\" =~ Usage           ]]\n  [[ \"${lines[1]}\" =~ \\ \\ nb\\ export  ]]\n}\n\n# <id> ######################################################################\n\n@test \"'export' with valid <id> and <path> exports a new note file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"# Export Example\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" export 1 \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls  \"${_TMP_DIR}\"\n  cat \"${_TMP_DIR}/example.md\"\n\n  [[ -f \"${_TMP_DIR}/example.md\" ]]\n\n  grep -q '# Export Example' \"${_TMP_DIR}/example.md\"\n\n  diff                              \\\n    <(cat \"${_TMP_DIR}/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example File.md\")\n\n  [[ \"${output}\" =~ Exported    ]]\n  [[ \"${output}\" =~ example.md  ]]\n}\n\n@test \"'export' with valid <id> and directory <path> exports a new note file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Export Example\" --filename \"example.md\"\n  }\n\n  run \"${_NB}\" export 1 \"${_TMP_DIR}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n  cat \"${_TMP_DIR}/example.md\"\n\n  [[ -e \"${_TMP_DIR}/example.md\" ]]\n  grep -q '# Export Example' \"${_TMP_DIR}/example.md\"\n\n  # Prints output\n  [[ \"${output}\" =~ Exported    ]]\n  [[ \"${output}\" =~ example.md  ]]\n}\n\n@test \"'export' with valid <id> and different basename <path> exports a new note file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Export Example\" --filename \"example.md\"\n  }\n\n  run \"${_NB}\" export 1 \"${_TMP_DIR}/sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n  cat \"${_TMP_DIR}/sample.md\"\n\n  [[ -e \"${_TMP_DIR}/sample.md\" ]]\n  grep -q '# Export Example' \"${_TMP_DIR}/sample.md\"\n\n  # Prints output\n  [[ \"${output}\" =~ Exported    ]]\n  [[ \"${output}\" =~ example.md  ]]\n  [[ \"${output}\" =~ sample.md   ]]\n}\n\n@test \"'export' with valid <id> and <path> to HTML file type converts.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Export Example\"\n  }\n\n  run \"${_NB}\" export 1 \"${_TMP_DIR}/example.html\"\n\n  cat \"${_TMP_DIR}/example.html\"\n\n  [[ -e \"${_TMP_DIR}/example.html\" ]]\n  grep -q 'DOCTYPE html' \"${_TMP_DIR}/example.html\"\n\n  # Prints output\n  [[ \"${output}\" =~ Exported        ]]\n  [[ \"${output}\" =~ Export\\ Example ]]\n  [[ \"${output}\" =~ example.html    ]]\n}\n\n@test \"'export' with valid <id> and <path> to docx file type converts.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add --title \"Export Example\"\n  }\n\n  run \"${_NB}\" export 1 \"${_TMP_DIR}/example.docx\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  file \"${_TMP_DIR}/example.docx\"\n\n  [[ -e \"${_TMP_DIR}/example.docx\"                            ]]\n  [[ \"$(file \"${_TMP_DIR}/example.docx\")\" =~ Microsoft\\ Word  ]]\n\n  # Prints output\n\n  [[ \"${lines[0]}\" =~ \\\n^Exported:\\ .*\\[.*1.*\\].*\\ .*export_example\\.md.*\\ \\\"Export\\ Example\\\"$ ]]\n  [[ \"${lines[1]}\" =~ \\\n^To:\\ \\ \\ \\ \\ \\ \\ \\ .*${_TMP_DIR}/example.docx.*$                       ]]\n}\n\n# `notebook` ##################################################################\n\n@test \"'export notebook' with valid <name> and <path> exports.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"example\"\n\n    [[ -d \"${NB_DIR}/example\"     ]]\n    [[ ! -d \"${_TMP_DIR}/example\" ]]\n  }\n\n  run \"${_NB}\" export notebook \"example\" \"${_TMP_DIR}/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ -d \"${_TMP_DIR}/example\"       ]]\n  [[ -d \"${_TMP_DIR}/example/.git\"  ]]\n  [[ \"${lines[0]}\" =~ \"Exported\"    ]]\n}\n\n# `pandoc <id>` ###############################################################\n\n@test \"'export pandoc' with valid <id> and <path> exports a new note file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Export Example\"\n  }\n\n  run \"${_NB}\" export pandoc 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                              ]]\n  [[ \"${output}\" =~ '<h1 id=\"export-example\">Export Example</h1>' ]]\n}\n\n@test \"'export pandoc' with invalid <id> returns error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" export pandoc 100\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1            ]]\n  [[ \"${output}\" =~ 'Not found' ]]\n}\n\n# help ########################################################################\n\n@test \"'help export' returns usage information.\" {\n  run \"${_NB}\" help export\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ Usage.*:      ]]\n  [[ \"${lines[1]}\" =~ '  nb export' ]]\n}\n"
  },
  {
    "path": "test/fixtures/Example Folder/example.com.html",
    "content": "<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"description\" content=\"Example description.\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 2em;\n        background-color: #fdfdff;\n        border-radius: 0.5em;\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        div {\n            margin: 0 auto;\n            width: auto;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "test/fixtures/Example Folder/example.md",
    "content": "# Example Title\n\nExample body with *formatting*.\n"
  },
  {
    "path": "test/fixtures/bin/bookmark",
    "content": "#!/usr/bin/env bash\n"
  },
  {
    "path": "test/fixtures/bin/mock_editor",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# mock_editor\n###############################################################################\n\n###############################################################################\n# Shell Options & Strict Mode\n#\n# More Information:\n#   https://github.com/xwmx/bash-boilerplate#bash-strict-mode\n###############################################################################\n\nset -o errexit\nset -o noglob\nset -o nounset\nset -o pipefail\n\nset +o noclobber\n\nIFS=$'\\n\\t'\n\n###############################################################################\n\n# _mock_editor()\n#\n# Usage:\n#   _mock_editor <path>\n#\n# Description:\n#   Save a string as the only content in a new file named <path>.\n_mock_editor() {\n  local _path=\n\n  for __arg in \"${@:-}\"\n  do\n    if [[ ! \"${__arg}\" =~ ^-- ]]\n    then\n      _path=\"${__arg}\"\n    fi\n  done\n\n  if [[ -z \"${_path:-}\"       ]]\n  then\n    printf \"Usage: mock_editor <path>\\\\n\"\n    return 1\n  fi\n\n  # if [[ -e \"${_path:-}\"       ]]\n  # then\n  #   printf \"[mock_editor] Already exists: %s\\\\n\" \"${_path:-}\"\n  # fi\n\n  printf \"# mock_editor %s\\\\n\" \"${_path%.*}\" >> \"${_path:-}\"\n}\n\n_mock_editor \"$@\"\n"
  },
  {
    "path": "test/fixtures/bin/mock_editor_no_op",
    "content": "#!/usr/bin/env bash\n\n# _mock_editor_no_op()\n#\n# Usage:\n#   _mock_editor_no_op <filename>\n#\n# Description:\n#   Take a filename and do nothing.\n_mock_editor_no_op() {\n  local _filename=\"${1:-}\"\n\n  if [[ -z \"${_filename}\" ]]\n  then\n    printf \"Usage: _mock_editor <filename>\\n\"\n    return 1\n  else\n    return 0\n  fi\n}\n\n_mock_editor_no_op \"$@\"\n"
  },
  {
    "path": "test/fixtures/bin/nb",
    "content": "#!/usr/bin/env bash\n"
  },
  {
    "path": "test/fixtures/bin/notes",
    "content": "#!/usr/bin/env bash\n"
  },
  {
    "path": "test/fixtures/copy-deprecated.nb-plugin",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# copy / duplicate\n#\n# A plugin for `nb` providing copy / duplicate functionality.\n#\n# Install with:\n#   nb plugin install https://github.com/xwmx/nb/blob/master/plugins/copy.nb-plugin\n#\n# https://github.com/xwmx/nb\n###############################################################################\n\n# Add the new subcommand name(s) to the $NB_PLUGIN_SUBCOMMANDS array.\nNB_PLUGIN_SUBCOMMANDS+=(\n  copy\n  duplicate\n)\n\n# Define help and usage text with `describe <subcommand> <usage>`.\ndescribe \"copy\" <<HEREDOC\nUsage:\n  nb copy (<id> | <filename> | <path> | <title>)\n\nDescription:\n  Create a copy of the specified item in the current notebook.\n\nAlias: \\`duplicate\\`\nHEREDOC\n\n# Define the subcommand as a function, named with a leading underscore.\n_copy() {\n  local _selection=\"${1:-}\"\n\n  # Check for the presence of a selection, exiting and printing help if not\n  # found.\n  if [[ -z \"${_selection:-}\" ]]\n  then\n    _exit_1 _help \"copy\"\n  fi\n\n  # Get the basename from the selection. The selection argument can be an\n  # <id>, <filename>, <path>, or <title>.\n  local _source_basename\n  _source_basename=\"$(_get_selection_basename \"${_selection}\")\"\n\n  # Set the current notebook using the selection.\n  #\n  # NOTE: Important!\n  # This sets the current notebook for all subsequent operations.\n  _set_selection_notebook \"${_selection}\"\n\n  # Validate that the selection is a file.\n  if [[ -z \"${_source_basename:-}\"                      ]] ||\n     [[ ! -e \"${_NOTEBOOK_PATH}/${_source_basename}\"    ]]\n  then\n    _exit_1 printf \"Not found: %s\\\\n\" \"${_selection}\"\n  elif [[ ! -f \"${_NOTEBOOK_PATH}/${_source_basename}\"  ]]\n  then\n    _exit_1 printf \"Not a file: %s\\\\n\" \"${_selection}\"\n  fi\n  # Get a unique basename based on the source basename.\n  local _target_basename\n  _target_basename=\"$(_get_unique_basename \"${_source_basename}\")\"\n\n  if _file_is_text \"${_source_basename}\"\n  then # Text can use `_add()`.\n    # Print the source contents and pipe to `_add()`.\n    _show \"${_source_basename}\" --no-color --print | _add \"${_target_basename}\"\n  else # Binary files must be copied manually.\n    # Copy the binary file to the new basename.\n    cp                                        \\\n      \"${_NOTEBOOK_PATH}/${_source_basename}\" \\\n      \"${_NOTEBOOK_PATH}/${_target_basename}\"\n\n    # Add the new basename to the index.\n    _index add \"${_target_basename}\"\n\n    # Record the change in git.\n    _git_checkpoint \"[nb] Add: ${_target_basename}\"\n\n    # Operation complete.\n    #\n    # Build the feedback message for the user since we can't use `_add()` here.\n\n    # Get the new id.\n    local _id\n    _id=\"$(_index get_id \"${_target_basename}\")\"\n\n    # Set the scoped basename and id to the current basename and id.\n    local _maybe_scoped_basename=\"${_target_basename}\"\n    local _maybe_scoped_id=\"${_id}\"\n\n    # $_SCOPED indicates whether the current notebook context\n    # differs from the configured current notebook, meaning the user used\n    # a selection with a notebook colon prefix. 1 == scoped, 0 == unscoped\n    if ((_SCOPED))\n    then # Selection includes a notebook prefix, e.g., \"notebook:123\".\n      # Add the notebook identifier to the id and basename.\n      local _notebook_identifier\n      _notebook_identifier=\"$(_get_notebook_identifier \"${_SCOPE}\")\"\n\n      _maybe_scoped_basename=\"${_notebook_identifier}:${_target_basename}\"\n      _maybe_scoped_id=\"${_notebook_identifier}:${_id}\"\n    fi\n\n    # Print feedback with scoped id and basename.\n    printf \"Added %s %s\\\\n\"                         \\\n      \"$(_id_brackets_color \"${_maybe_scoped_id}\")\" \\\n      \"$(_highlight \"${_maybe_scoped_basename}\")\"\n  fi\n}\n# Use `_alias_subcommand` to create a full alias, with linked help / usage.\n# NOTE: Aliases also have to be added to the $NB_PLUGIN_SUBCOMMANDS array.\n_alias_subcommand \"copy\" \"duplicate\"\n"
  },
  {
    "path": "test/fixtures/example-chrome-bookmarks.html",
    "content": "<!DOCTYPE NETSCAPE-Bookmark-file-1>\n<!-- This is an automatically generated file.\n     It will be read and overwritten.\n     DO NOT EDIT! -->\n<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n<TITLE>Bookmarks</TITLE>\n<H1>Bookmarks</H1>\n<DL><p>\n    <DT><H3 ADD_DATE=\"1598537181\" LAST_MODIFIED=\"1659297581\" PERSONAL_TOOLBAR_FOLDER=\"true\">Bookmarks</H3>\n    <DL><p>\n        <DT><A HREF=\"https://example.com/\" ADD_DATE=\"1659293640\">Example Com</A>\n        <DT><H3 ADD_DATE=\"1659293790\" LAST_MODIFIED=\"1659297596\">Example Bookmark Folder</H3>\n        <DL><p>\n            <DT><H3 ADD_DATE=\"1659293815\" LAST_MODIFIED=\"1659293818\">Example Nested Folder</H3>\n            <DL><p>\n                <DT><A HREF=\"https://example.org/\" ADD_DATE=\"1659293644\">Example Org</A>\n            </DL><p>\n            <DT><A HREF=\"https://example.net/\" ADD_DATE=\"1659293642\">Example Net</A>\n            <DT><H3 ADD_DATE=\"1659297596\" LAST_MODIFIED=\"1659297596\">Example Empty Nested Folder</H3>\n            <DL><p>\n            </DL><p>\n        </DL><p>\n        <DT><A HREF=\"https://example.edu/\" ADD_DATE=\"1659293762\">Example Edu</A>\n        <DT><H3 ADD_DATE=\"1659297581\" LAST_MODIFIED=\"1659297581\">Example Empty Folder</H3>\n        <DL><p>\n        </DL><p>\n    </DL><p>\n    <DT><A HREF=\"https://example.org/#example\" ADD_DATE=\"1659294150\">Example Org Other</A>\n    <DT><A HREF=\"https://example.net/#example\" ADD_DATE=\"1659294155\">Example Net Other</A>\n    <DT><H3 ADD_DATE=\"1659294234\" LAST_MODIFIED=\"1659297624\">Example Folder Other</H3>\n    <DL><p>\n        <DT><A HREF=\"https://example.edu/#example\" ADD_DATE=\"1659294142\">Example Edu Other</A>\n        <DT><H3 ADD_DATE=\"1659294260\" LAST_MODIFIED=\"1659294265\">Example Nested Folder Other</H3>\n        <DL><p>\n            <DT><A HREF=\"https://example.com/#example\" ADD_DATE=\"1659294134\">Example Com Other</A>\n        </DL><p>\n        <DT><H3 ADD_DATE=\"1659297624\" LAST_MODIFIED=\"1659297624\">Example Nested Empty Folder Other</H3>\n        <DL><p>\n        </DL><p>\n    </DL><p>\n    <DT><H3 ADD_DATE=\"1659297609\" LAST_MODIFIED=\"1659297609\">Example Empty Folder Other</H3>\n    <DL><p>\n    </DL><p>\n</DL><p>\n"
  },
  {
    "path": "test/fixtures/example-edge-bookmarks.html",
    "content": "<!DOCTYPE NETSCAPE-Bookmark-file-1>\n<!-- This is an automatically generated file.\n     It will be read and overwritten.\n     DO NOT EDIT! -->\n<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n<TITLE>Bookmarks</TITLE>\n<H1>Bookmarks</H1>\n<DL><p>\n    <DT><H3 ADD_DATE=\"1659475749\" LAST_MODIFIED=\"0\" PERSONAL_TOOLBAR_FOLDER=\"true\">Favorites Bar</H3>\n    <DL><p>\n        <DT><H3 ADD_DATE=\"1659475829\" LAST_MODIFIED=\"0\">Bookmarks</H3>\n        <DL><p>\n            <DT><A HREF=\"https://example.com/\" ADD_DATE=\"1659293640\">Example Com</A>\n            <DT><H3 ADD_DATE=\"1659475829\" LAST_MODIFIED=\"0\">Example Bookmark Folder</H3>\n            <DL><p>\n                <DT><H3 ADD_DATE=\"1659475829\" LAST_MODIFIED=\"0\">Example Nested Folder</H3>\n                <DL><p>\n                    <DT><A HREF=\"https://example.org/\" ADD_DATE=\"1659293644\">Example Org</A>\n                </DL><p>\n                <DT><A HREF=\"https://example.net/\" ADD_DATE=\"1659293642\">Example Net</A>\n                <DT><H3 ADD_DATE=\"1659475829\" LAST_MODIFIED=\"1659475829\">Example Empty Nested Folder</H3>\n                <DL><p>\n                </DL><p>\n            </DL><p>\n            <DT><A HREF=\"https://example.edu/\" ADD_DATE=\"1659293762\">Example Edu</A>\n            <DT><H3 ADD_DATE=\"1659475829\" LAST_MODIFIED=\"1659475829\">Example Empty Folder</H3>\n            <DL><p>\n            </DL><p>\n        </DL><p>\n    </DL><p>\n    <DT><A HREF=\"https://example.org/#example\" ADD_DATE=\"1659294150\">Example Org Other</A>\n    <DT><A HREF=\"https://example.net/#example\" ADD_DATE=\"1659294155\">Example Net Other</A>\n    <DT><H3 ADD_DATE=\"1659475829\" LAST_MODIFIED=\"0\">Example Folder Other</H3>\n    <DL><p>\n        <DT><A HREF=\"https://example.edu/#example\" ADD_DATE=\"1659294142\">Example Edu Other</A>\n        <DT><H3 ADD_DATE=\"1659475829\" LAST_MODIFIED=\"0\">Example Nested Folder Other</H3>\n        <DL><p>\n            <DT><A HREF=\"https://example.com/#example\" ADD_DATE=\"1659294134\">Example Com Other</A>\n        </DL><p>\n        <DT><H3 ADD_DATE=\"1659475829\" LAST_MODIFIED=\"1659475829\">Example Nested Empty Folder Other</H3>\n        <DL><p>\n        </DL><p>\n    </DL><p>\n    <DT><H3 ADD_DATE=\"1659475829\" LAST_MODIFIED=\"1659475829\">Example Empty Folder Other</H3>\n    <DL><p>\n    </DL><p>\n</DL><p>\n"
  },
  {
    "path": "test/fixtures/example-firefox-bookmarks-backup.json",
    "content": "{\"guid\":\"root________\",\"title\":\"\",\"index\":0,\"dateAdded\":1597805921435000,\"lastModified\":1659320551346000,\"id\":1,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"root\":\"placesRoot\",\"children\":[{\"guid\":\"menu________\",\"title\":\"menu\",\"index\":0,\"dateAdded\":1597805921435000,\"lastModified\":1659320513616000,\"id\":2,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"root\":\"bookmarksMenuFolder\",\"children\":[{\"guid\":\"HALQHwn_0CjS\",\"title\":\"Example Folder Menu\",\"index\":0,\"dateAdded\":1659320406835000,\"lastModified\":1659320505693000,\"id\":38,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"children\":[{\"guid\":\"g_5iO_2sZM97\",\"title\":\"Example Nested Folder Menu\",\"index\":0,\"dateAdded\":1659320406841000,\"lastModified\":1659320492336000,\"id\":39,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"children\":[{\"guid\":\"-KUEzm7KX7ID\",\"title\":\"Example Org Menu\",\"index\":0,\"dateAdded\":1659320406847000,\"lastModified\":1659320448970000,\"id\":40,\"typeCode\":1,\"tags\":\"tag2,tag6,tag7\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.org/#menu\"}]},{\"guid\":\"wmFWJknxFpOY\",\"title\":\"Example Net Menu\",\"index\":1,\"dateAdded\":1659320406852000,\"lastModified\":1659320458107000,\"id\":41,\"typeCode\":1,\"tags\":\"tag1,tag4,tag5\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.net/#menu\"}]},{\"guid\":\"92CdH6-s_4Jh\",\"title\":\"Example Edu Menu\",\"index\":1,\"dateAdded\":1659320406860000,\"lastModified\":1659320527008000,\"id\":42,\"typeCode\":1,\"tags\":\"tag2,tag3\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.edu/#menu\"},{\"guid\":\"JEeytQFIk23M\",\"title\":\"Example Com Menu\",\"index\":2,\"dateAdded\":1659320406870000,\"lastModified\":1659320520514000,\"id\":43,\"typeCode\":1,\"tags\":\"tag1,tag2\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.com/#menu\"},{\"guid\":\"BelkgQaHw7kh\",\"title\":\"Mozilla Firefox\",\"index\":3,\"dateAdded\":1597805921675000,\"lastModified\":1597805921675000,\"id\":7,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"children\":[{\"guid\":\"HmPPPD1mhV_r\",\"title\":\"Help and Tutorials\",\"index\":0,\"dateAdded\":1597805921675000,\"lastModified\":1597805921675000,\"id\":8,\"typeCode\":1,\"iconUri\":\"fake-favicon-uri:https://support.mozilla.org/en-US/products/firefox\",\"type\":\"text/x-moz-place\",\"uri\":\"https://support.mozilla.org/en-US/products/firefox\"},{\"guid\":\"Ss6yP0tPnt94\",\"title\":\"Customize Firefox\",\"index\":1,\"dateAdded\":1597805921675000,\"lastModified\":1597805921675000,\"id\":9,\"typeCode\":1,\"iconUri\":\"fake-favicon-uri:https://support.mozilla.org/en-US/kb/customize-firefox-controls-buttons-and-toolbars?utm_source=firefox-browser&utm_medium=default-bookmarks&utm_campaign=customize\",\"type\":\"text/x-moz-place\",\"uri\":\"https://support.mozilla.org/en-US/kb/customize-firefox-controls-buttons-and-toolbars?utm_source=firefox-browser&utm_medium=default-bookmarks&utm_campaign=customize\"},{\"guid\":\"URAAa0yZi89D\",\"title\":\"Get Involved\",\"index\":2,\"dateAdded\":1597805921675000,\"lastModified\":1597805921675000,\"id\":10,\"typeCode\":1,\"iconUri\":\"fake-favicon-uri:https://www.mozilla.org/en-US/contribute/\",\"type\":\"text/x-moz-place\",\"uri\":\"https://www.mozilla.org/en-US/contribute/\"},{\"guid\":\"PvLOqSUWjH2o\",\"title\":\"About Us\",\"index\":3,\"dateAdded\":1597805921675000,\"lastModified\":1597805921675000,\"id\":11,\"typeCode\":1,\"iconUri\":\"fake-favicon-uri:https://www.mozilla.org/en-US/about/\",\"type\":\"text/x-moz-place\",\"uri\":\"https://www.mozilla.org/en-US/about/\"}]}]},{\"guid\":\"toolbar_____\",\"title\":\"toolbar\",\"index\":1,\"dateAdded\":1597805921435000,\"lastModified\":1659320166318000,\"id\":3,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"root\":\"toolbarFolder\",\"children\":[{\"guid\":\"0-CTF5qA5VIS\",\"title\":\"Getting Started\",\"index\":0,\"dateAdded\":1597805921725000,\"lastModified\":1597805921725000,\"id\":12,\"typeCode\":1,\"iconUri\":\"fake-favicon-uri:https://www.mozilla.org/en-US/firefox/central/\",\"type\":\"text/x-moz-place\",\"uri\":\"https://www.mozilla.org/en-US/firefox/central/\"},{\"guid\":\"CNpZzBuZCtRV\",\"title\":\"Example Folder Toolbar\",\"index\":1,\"dateAdded\":1659320194421000,\"lastModified\":1659320276978000,\"id\":15,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"children\":[{\"guid\":\"fmYCsHtD8Af6\",\"title\":\"Example Nested Folder Toolbar\",\"index\":0,\"dateAdded\":1659320232407000,\"lastModified\":1659320276978000,\"id\":17,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"children\":[{\"guid\":\"7edv6xbF6FUE\",\"title\":\"Example Org Toolbar\",\"index\":0,\"dateAdded\":1659320254600000,\"lastModified\":1659320276978000,\"id\":18,\"typeCode\":1,\"tags\":\"tag2,tag6,tag7\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.org/#toolbar\"}]},{\"guid\":\"GQze06wxnhu-\",\"title\":\"Example Net Toolbar\",\"index\":1,\"dateAdded\":1659320211190000,\"lastModified\":1659320226329000,\"id\":16,\"typeCode\":1,\"tags\":\"tag4,tag5,tag1\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.net/#toolbar\"}]},{\"guid\":\"Y30BUoZ3j1Si\",\"title\":\"Example Edu Toolbar\",\"index\":2,\"dateAdded\":1659320286016000,\"lastModified\":1659320298654000,\"id\":19,\"typeCode\":1,\"tags\":\"tag2,tag3\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.edu/#toolbar\"},{\"guid\":\"MhRNmr5qRCja\",\"title\":\"Example Com Toolbar\",\"index\":3,\"dateAdded\":1659320158024000,\"lastModified\":1659320166318000,\"id\":14,\"typeCode\":1,\"tags\":\"tag2,tag1\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.com/#toolbar\"}]},{\"guid\":\"unfiled_____\",\"title\":\"unfiled\",\"index\":3,\"dateAdded\":1597805921435000,\"lastModified\":1659320551346000,\"id\":5,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"root\":\"unfiledBookmarksFolder\",\"children\":[{\"guid\":\"0YuLvZfxEjOc\",\"title\":\"Example Com Other\",\"index\":0,\"dateAdded\":1659320430086000,\"lastModified\":1659320564445000,\"id\":51,\"typeCode\":1,\"tags\":\"tag1,tag2\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.com/#other\"},{\"guid\":\"FIX9Noo-EZ0h\",\"title\":\"Example Folder Other\",\"index\":1,\"dateAdded\":1659320410553000,\"lastModified\":1659320570576000,\"id\":44,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"children\":[{\"guid\":\"x9ln52NxrA53\",\"title\":\"Example Nested Folder Other\",\"index\":0,\"dateAdded\":1659320410558000,\"lastModified\":1659320581151000,\"id\":45,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"children\":[{\"guid\":\"bBQk3TL_PHgA\",\"title\":\"Example Org Other\",\"index\":0,\"dateAdded\":1659320410562000,\"lastModified\":1659320599790000,\"id\":46,\"typeCode\":1,\"tags\":\"tag2,tag6,tag7\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.org/#other\"}]},{\"guid\":\"6UaVq3aEPqdd\",\"title\":\"Example Net Other\",\"index\":1,\"dateAdded\":1659320410570000,\"lastModified\":1659320588474000,\"id\":47,\"typeCode\":1,\"tags\":\"tag1,tag4,tag5\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.net/#other\"}]},{\"guid\":\"AZt6lulETxjN\",\"title\":\"Example Edu Other\",\"index\":2,\"dateAdded\":1659320410577000,\"lastModified\":1659320576005000,\"id\":48,\"typeCode\":1,\"tags\":\"tag2,tag3\",\"type\":\"text/x-moz-place\",\"uri\":\"http://example.edu/#other\"}]},{\"guid\":\"mobile______\",\"title\":\"mobile\",\"index\":4,\"dateAdded\":1597805921455000,\"lastModified\":1597805921665000,\"id\":6,\"typeCode\":2,\"type\":\"text/x-moz-place-container\",\"root\":\"mobileFolder\"}]}"
  },
  {
    "path": "test/fixtures/example-firefox-bookmarks.html",
    "content": "<!DOCTYPE NETSCAPE-Bookmark-file-1>\n<!-- This is an automatically generated file.\n     It will be read and overwritten.\n     DO NOT EDIT! -->\n<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n<meta http-equiv=\"Content-Security-Policy\"\n      content=\"default-src 'self'; script-src 'none'; img-src data: *; object-src 'none'\"></meta>\n<TITLE>Bookmarks</TITLE>\n<H1>Bookmarks Menu</H1>\n\n<DL><p>\n    <DT><H3 ADD_DATE=\"1659320406\" LAST_MODIFIED=\"1659320505\">Example Folder Menu</H3>\n    <DL><p>\n        <DT><H3 ADD_DATE=\"1659320406\" LAST_MODIFIED=\"1659320492\">Example Nested Folder Menu</H3>\n        <DL><p>\n            <DT><A HREF=\"https://example.org/#menu\" ADD_DATE=\"1659320406\" LAST_MODIFIED=\"1659320448\" TAGS=\"tag2,tag6,tag7\">Example Org Menu</A>\n        </DL><p>\n        <DT><A HREF=\"https://example.net/#menu\" ADD_DATE=\"1659320406\" LAST_MODIFIED=\"1659320458\" TAGS=\"tag1,tag4,tag5\">Example Net Menu</A>\n    </DL><p>\n    <DT><A HREF=\"https://example.edu/#menu\" ADD_DATE=\"1659320406\" LAST_MODIFIED=\"1659320527\" TAGS=\"tag2,tag3\">Example Edu Menu</A>\n    <DT><A HREF=\"https://example.com/#menu\" ADD_DATE=\"1659320406\" LAST_MODIFIED=\"1659320520\" TAGS=\"tag1,tag2\">Example Com Menu</A>\n    <DT><H3 ADD_DATE=\"1597805921\" LAST_MODIFIED=\"1597805921\">Mozilla Firefox</H3>\n    <DL><p>\n        <DT><A HREF=\"https://support.mozilla.org/en-US/products/firefox\" ADD_DATE=\"1597805921\" LAST_MODIFIED=\"1597805921\" ICON_URI=\"fake-favicon-uri:https://support.mozilla.org/en-US/products/firefox\" ICON=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH4QsJCyMZzYMsXAAACVZJREFUWMOtl3mMX1UVxz/n3vve7/d+2yyd6bQdp6UtSwGrkgKW1FjFDdyDCAQTFTHGLRo33OMSExdwC0bREP8AFyLRGDVEa1gkYmuLWCmmFNvpQJm2Q6fTzm99y1384/dry6ZR40u+ue8l773zOffcc+65wv/pKvaCGV1CyLPLkVxE4tutbROt+Pffyf8LwB9S4P1yKZ/zK+jZYPdfIaIPuNRhVv4XAJ2xjU95rs5vIwDqrQcRZ7WvJhNUSmuolFZSMkOUAiS2RRQ/+tirz3zp1NCyzyGJwj58W/AH3s8NHOc0NJCr9z4TwDz5YW7ly+lASYs7H/HbnUgx9sJtrCiyWqP5xOZuZehyj1yEqOcgkqBEoT2YEIZqs73DxaRMqVhBFcy6KyQ02uGFe7bQtFo63GZ/JpgrwlMA1ImbfZOvJYhQYC6xor4QdBheOna3NI7PbRbvbiOE271EbxelzkpMWo20U2gg8mCCnFafrqypHkwgAgJQUajT3ibnnvVdGY8+FlazUtXCv56BAsVCUauWTf4eJ/birsTXbrLfz1vR0CdyauMi8KLKdt609LdUahlfzj7NPjkdlAcNk8ksddOCIAMAIOiIidVjRHpMju79gO91P+634tRFzwKQIgTxqx2cVxUnQ6XeZ79duU274VB6vD7KYqPC6ye3UNQV1y5+j32sAXPCo4AEj4QMQgHoAUToDyNTEKtrVHv6d5jk9/k9c8QveRpAhsMjK8ckHV5uFimXupVlSQ+qPS4cTmEkgyTjs8c+yR3dS6E6sOEFvDDbWU6z0CyJjoMsgxD6gv5YnhhFuC6099xvJkePwcKpNfDY8tegZ18lU9K7YJnuxCVVgPF9D430FfVfL3cgDin4AE6BVWBhb/N0/rqwDtx+8PkpAO8h+D6sGd0syZmXyej55H+uAaC3jV5FXVvK1f2bEl1cn5i0ZqICSSxULVSLvmoFiHBeb4ZNjft50dg2njM0y8PZOgoicl/GWsdrlv4aIx4YHsxAOAUTRBPMeFg88ktVWdL7wo1zqMRHzLZWRN6b9whMKDwigAqgnyQVAKHuu1wS3cm7h27i2tEfktgUMgOF4ZcHLuOWRy4j5Pug2A/egvPg3CkF2UDUuFjiOs1tz8P4oIl18VwX1CtEfL80SRiMT1PsQXuaeYN7Dr+E63vvZd6NQCTgDT0zzmd2fpHEpVy99ldo0wO9qr/UToTC+1hCeH2+0PxF0oid0eJIXXRuCDL8jCR9etqWHA+Vl3PdzEe5x2ymVxmHpBjEWoNVHJG1fPDP3yLppFx+1h0QdcCsBsrgXR/E+wtMyUyAP6jKCBLUkoCKQ5BB9sjJLCKAdwqXG7wTdri13N28kDwzkKbQy/tKC0gtZJZj6STfefAaFmdq0DoKnYchXwRrBypWyHxnQzjnAcwZkzvYOn3xmT4oPAqPEALIIL2azQqd4zW2ujVs0c9jPhqnmjbJVCDzHuvKhCKCyIFRoBUg7Oycze7OajYe3AUTbcimIR6Eo7B15tL3h5sn/mB+9Pe3lKZK85Pea7zXhKDAK3BClkYstsrUyhm7W1Pc2b2AUKlQSVpoAso5cpdT5GV8FBOMBqVACa1eiWm1jI1qFxwHKh0oDkM0DoVHLEvCUGxMBwlF0AetN7igcUETvCBO4dOIEXHUopxLxh/iT7PrmOlNISGADYTCI7lFRzk+Nngd4ZUmKEXodshyBSuA+UFxlEVwCVhDEJf7YefM+eX5/JiNdhc+pnARzht8UKhCUTIWKTuIPBsmpvniilv5wT8u5ZHuKmrVgjOnDlJp5OxcOIf759aTS6lvXBQqm2MiPjIoYEAGKAe+DT6Bsp/rRLZrFoqEInAgd7EtXGwK34fQtkB56ee/6deBDaP7uGHyJo6qOvXhLiNLWqhqoBWqfOmud/GTnZeCEnxQLKvs4ezRxyAHPFAMUtmmoCAY/+Bo5guTeYULsjd38ULmyksLF2O9IXIasa6fBdZQLI4gVKmOdKgPHQM8vqt5ZG4JW2fX0D2SU+8sEJQit47XvuAPrKodhUXAPrkFciBp2znuJQ+YLoECvT9x8a7UJi/LbJncxMQuR+UOco3KLKKFh/adwVFbo9bo0C0X/K3T4K7HzuFwezmYElVznNxrzp36O+/YdDcqDdAB3ImNqw/gcdt7md4hAuZR1WFTqHcWvP51r0gu7tlEyq5MyWdoa1E9A7EjLqUMJwf58cMXsPuhteRBYymhTIm67uHyAq9h/eq9fPiNv2FV7Rg0gd7AsB+ASMisUzc3jG3eN9Po94Q/l8/ggpw2rIs7RpOjZy+pzDNUPkY1bhNFGVLPoZHBUMYRXWLL4bXsmJviiW6NzBtM5BkfbXLh+j1csvFBlo51+vEuBgoD4w7CXPVxO1vfjPHT8Y1P9PuBA6rLNWF05h7vv98pajckRc/EOsOoAiUO0+3vAejAeCPj6rU7ecO6XSwQ09WKcj1lbKxJtZEiEdAexNufqqZYCIcrhJn6o3Y0PXqiH9YAvw1beT4baQfZU0I9VxPOMtqilUMrhwqhvxkOPpIgxNoylPQYq7YZTrrE4hA3WHB24PnAazIhtCPcfC13w72vlh+v3zdz7jw3/i70AQAWylO8wo+kzSAPGvRFWliulUOLR4lH+4D4AUTol2mcGjQletCYKCgUWBlACPQ0tGLoGuuMu+lo7L6ZjabFyk8Xp2YAYMbuYql6Pq/U0ZFZz191UBuUsFwNAOQEhBsY9+oUhB1A5BpyNRgNdA0slvCdaC5L9VcOt+OvlFPTXvqN1smsPAkAsC1sR+n1XGnMwX94/miCWimotSIoERDpN8HKCrgnz8DA85PGNaETUSzU8rxnbm9l6kP3HmrcrnOVnnHrE0/Z4Z/1aHZ2dDU3mhEOeUamTPHOkaj3vnrcXlWLWyRRl5LO0LpARQ7KFkoOYgexx+rAojUc79btYjpy8yFbua6hfOvFD3wS2PwMW/rZAOb9Lm6xO9hUWp/eadk2pWSLQhZDUCMh6EYIyggK8YIUCsn1Sc+L1OTdNNqdO/laC3/9eNRsXnj/m4Ern83Uf3Y4/Xz9KqatkivLxcSyKH9BQ2fnVUx2eknn45HOS0ZcIcod89rvz41/II3d9p2V9qGJIg4btk3/23//D6fjH/HBsZv5SzqsXpd0ogmTq654f28WFT/91F1ePvIR4Ov/8d/+CfHfpDCA/XdnAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTExLTA5VDExOjM1OjI1KzAxOjAw560ORgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0xMS0wOVQxMTozNToyNSswMTowMJbwtvoAAABXelRYdFJhdyBwcm9maWxlIHR5cGUgaXB0YwAAeJzj8gwIcVYoKMpPy8xJ5VIAAyMLLmMLEyMTS5MUAxMgRIA0w2QDI7NUIMvY1MjEzMQcxAfLgEigSi4A6hcRdPJCNZUAAAAASUVORK5CYII=\">Help and Tutorials</A>\n        <DT><A HREF=\"https://support.mozilla.org/en-US/kb/customize-firefox-controls-buttons-and-toolbars?utm_source=firefox-browser&utm_medium=default-bookmarks&utm_campaign=customize\" ADD_DATE=\"1597805921\" LAST_MODIFIED=\"1597805921\" ICON_URI=\"fake-favicon-uri:https://support.mozilla.org/en-US/kb/customize-firefox-controls-buttons-and-toolbars?utm_source=firefox-browser&utm_medium=default-bookmarks&utm_campaign=customize\" ICON=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH4QsJCyMZzYMsXAAACVZJREFUWMOtl3mMX1UVxz/n3vve7/d+2yyd6bQdp6UtSwGrkgKW1FjFDdyDCAQTFTHGLRo33OMSExdwC0bREP8AFyLRGDVEa1gkYmuLWCmmFNvpQJm2Q6fTzm99y1384/dry6ZR40u+ue8l773zOffcc+65wv/pKvaCGV1CyLPLkVxE4tutbROt+Pffyf8LwB9S4P1yKZ/zK+jZYPdfIaIPuNRhVv4XAJ2xjU95rs5vIwDqrQcRZ7WvJhNUSmuolFZSMkOUAiS2RRQ/+tirz3zp1NCyzyGJwj58W/AH3s8NHOc0NJCr9z4TwDz5YW7ly+lASYs7H/HbnUgx9sJtrCiyWqP5xOZuZehyj1yEqOcgkqBEoT2YEIZqs73DxaRMqVhBFcy6KyQ02uGFe7bQtFo63GZ/JpgrwlMA1ImbfZOvJYhQYC6xor4QdBheOna3NI7PbRbvbiOE271EbxelzkpMWo20U2gg8mCCnFafrqypHkwgAgJQUajT3ibnnvVdGY8+FlazUtXCv56BAsVCUauWTf4eJ/birsTXbrLfz1vR0CdyauMi8KLKdt609LdUahlfzj7NPjkdlAcNk8ksddOCIAMAIOiIidVjRHpMju79gO91P+634tRFzwKQIgTxqx2cVxUnQ6XeZ79duU274VB6vD7KYqPC6ye3UNQV1y5+j32sAXPCo4AEj4QMQgHoAUToDyNTEKtrVHv6d5jk9/k9c8QveRpAhsMjK8ckHV5uFimXupVlSQ+qPS4cTmEkgyTjs8c+yR3dS6E6sOEFvDDbWU6z0CyJjoMsgxD6gv5YnhhFuC6099xvJkePwcKpNfDY8tegZ18lU9K7YJnuxCVVgPF9D430FfVfL3cgDin4AE6BVWBhb/N0/rqwDtx+8PkpAO8h+D6sGd0syZmXyej55H+uAaC3jV5FXVvK1f2bEl1cn5i0ZqICSSxULVSLvmoFiHBeb4ZNjft50dg2njM0y8PZOgoicl/GWsdrlv4aIx4YHsxAOAUTRBPMeFg88ktVWdL7wo1zqMRHzLZWRN6b9whMKDwigAqgnyQVAKHuu1wS3cm7h27i2tEfktgUMgOF4ZcHLuOWRy4j5Pug2A/egvPg3CkF2UDUuFjiOs1tz8P4oIl18VwX1CtEfL80SRiMT1PsQXuaeYN7Dr+E63vvZd6NQCTgDT0zzmd2fpHEpVy99ldo0wO9qr/UToTC+1hCeH2+0PxF0oid0eJIXXRuCDL8jCR9etqWHA+Vl3PdzEe5x2ymVxmHpBjEWoNVHJG1fPDP3yLppFx+1h0QdcCsBsrgXR/E+wtMyUyAP6jKCBLUkoCKQ5BB9sjJLCKAdwqXG7wTdri13N28kDwzkKbQy/tKC0gtZJZj6STfefAaFmdq0DoKnYchXwRrBypWyHxnQzjnAcwZkzvYOn3xmT4oPAqPEALIIL2azQqd4zW2ujVs0c9jPhqnmjbJVCDzHuvKhCKCyIFRoBUg7Oycze7OajYe3AUTbcimIR6Eo7B15tL3h5sn/mB+9Pe3lKZK85Pea7zXhKDAK3BClkYstsrUyhm7W1Pc2b2AUKlQSVpoAso5cpdT5GV8FBOMBqVACa1eiWm1jI1qFxwHKh0oDkM0DoVHLEvCUGxMBwlF0AetN7igcUETvCBO4dOIEXHUopxLxh/iT7PrmOlNISGADYTCI7lFRzk+Nngd4ZUmKEXodshyBSuA+UFxlEVwCVhDEJf7YefM+eX5/JiNdhc+pnARzht8UKhCUTIWKTuIPBsmpvniilv5wT8u5ZHuKmrVgjOnDlJp5OxcOIf759aTS6lvXBQqm2MiPjIoYEAGKAe+DT6Bsp/rRLZrFoqEInAgd7EtXGwK34fQtkB56ee/6deBDaP7uGHyJo6qOvXhLiNLWqhqoBWqfOmud/GTnZeCEnxQLKvs4ezRxyAHPFAMUtmmoCAY/+Bo5guTeYULsjd38ULmyksLF2O9IXIasa6fBdZQLI4gVKmOdKgPHQM8vqt5ZG4JW2fX0D2SU+8sEJQit47XvuAPrKodhUXAPrkFciBp2znuJQ+YLoECvT9x8a7UJi/LbJncxMQuR+UOco3KLKKFh/adwVFbo9bo0C0X/K3T4K7HzuFwezmYElVznNxrzp36O+/YdDcqDdAB3ImNqw/gcdt7md4hAuZR1WFTqHcWvP51r0gu7tlEyq5MyWdoa1E9A7EjLqUMJwf58cMXsPuhteRBYymhTIm67uHyAq9h/eq9fPiNv2FV7Rg0gd7AsB+ASMisUzc3jG3eN9Po94Q/l8/ggpw2rIs7RpOjZy+pzDNUPkY1bhNFGVLPoZHBUMYRXWLL4bXsmJviiW6NzBtM5BkfbXLh+j1csvFBlo51+vEuBgoD4w7CXPVxO1vfjPHT8Y1P9PuBA6rLNWF05h7vv98pajckRc/EOsOoAiUO0+3vAejAeCPj6rU7ecO6XSwQ09WKcj1lbKxJtZEiEdAexNufqqZYCIcrhJn6o3Y0PXqiH9YAvw1beT4baQfZU0I9VxPOMtqilUMrhwqhvxkOPpIgxNoylPQYq7YZTrrE4hA3WHB24PnAazIhtCPcfC13w72vlh+v3zdz7jw3/i70AQAWylO8wo+kzSAPGvRFWliulUOLR4lH+4D4AUTol2mcGjQletCYKCgUWBlACPQ0tGLoGuuMu+lo7L6ZjabFyk8Xp2YAYMbuYql6Pq/U0ZFZz191UBuUsFwNAOQEhBsY9+oUhB1A5BpyNRgNdA0slvCdaC5L9VcOt+OvlFPTXvqN1smsPAkAsC1sR+n1XGnMwX94/miCWimotSIoERDpN8HKCrgnz8DA85PGNaETUSzU8rxnbm9l6kP3HmrcrnOVnnHrE0/Z4Z/1aHZ2dDU3mhEOeUamTPHOkaj3vnrcXlWLWyRRl5LO0LpARQ7KFkoOYgexx+rAojUc79btYjpy8yFbua6hfOvFD3wS2PwMW/rZAOb9Lm6xO9hUWp/eadk2pWSLQhZDUCMh6EYIyggK8YIUCsn1Sc+L1OTdNNqdO/laC3/9eNRsXnj/m4Ern83Uf3Y4/Xz9KqatkivLxcSyKH9BQ2fnVUx2eknn45HOS0ZcIcod89rvz41/II3d9p2V9qGJIg4btk3/23//D6fjH/HBsZv5SzqsXpd0ogmTq654f28WFT/91F1ePvIR4Ov/8d/+CfHfpDCA/XdnAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTExLTA5VDExOjM1OjI1KzAxOjAw560ORgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0xMS0wOVQxMTozNToyNSswMTowMJbwtvoAAABXelRYdFJhdyBwcm9maWxlIHR5cGUgaXB0YwAAeJzj8gwIcVYoKMpPy8xJ5VIAAyMLLmMLEyMTS5MUAxMgRIA0w2QDI7NUIMvY1MjEzMQcxAfLgEigSi4A6hcRdPJCNZUAAAAASUVORK5CYII=\">Customize Firefox</A>\n        <DT><A HREF=\"https://www.mozilla.org/en-US/contribute/\" ADD_DATE=\"1597805921\" LAST_MODIFIED=\"1597805921\" ICON_URI=\"fake-favicon-uri:https://www.mozilla.org/en-US/contribute/\" ICON=\"data:image/png;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxNicgaGVpZ2h0PScxNic+IDxwYXRoIGQ9J00wIDBoMTZ2MTZIMHonLz4gPHBhdGggZD0nTTEzLjk5NCAxMC4zNTZIMTVWMTJoLTMuMTcxVjcuNzQxYzAtMS4zMDgtLjQzNS0xLjgxLTEuMjktMS44MS0xLjA0IDAtMS40Ni43MzctMS40NiAxLjh2Mi42M2gxLjAwNlYxMkg2LjkxOFY3Ljc0MWMwLTEuMzA4LS40MzUtMS44MS0xLjI5MS0xLjgxLTEuMDM5IDAtMS40NTkuNzM3LTEuNDU5IDEuOHYyLjYzaDEuNDQxVjEySDF2LTEuNjQ0aDEuMDA2VjYuMDc5SDFWNC40MzVoMy4xNjh2MS4xMzlhMi41MDcgMi41MDcgMCAwIDEgMi4zLTEuMjlBMi40NTIgMi40NTIgMCAwIDEgOC45MzEgNS45MSAyLjUzNSAyLjUzNSAwIDAgMSAxMS40IDQuMjg0IDIuNDQ4IDIuNDQ4IDAgMCAxIDE0IDYuOXYzLjQ1OHonIGZpbGw9JyNmZmYnLz4gPC9zdmc+\">Get Involved</A>\n        <DT><A HREF=\"https://www.mozilla.org/en-US/about/\" ADD_DATE=\"1597805921\" LAST_MODIFIED=\"1597805921\" ICON_URI=\"fake-favicon-uri:https://www.mozilla.org/en-US/about/\" ICON=\"data:image/png;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxNicgaGVpZ2h0PScxNic+IDxwYXRoIGQ9J00wIDBoMTZ2MTZIMHonLz4gPHBhdGggZD0nTTEzLjk5NCAxMC4zNTZIMTVWMTJoLTMuMTcxVjcuNzQxYzAtMS4zMDgtLjQzNS0xLjgxLTEuMjktMS44MS0xLjA0IDAtMS40Ni43MzctMS40NiAxLjh2Mi42M2gxLjAwNlYxMkg2LjkxOFY3Ljc0MWMwLTEuMzA4LS40MzUtMS44MS0xLjI5MS0xLjgxLTEuMDM5IDAtMS40NTkuNzM3LTEuNDU5IDEuOHYyLjYzaDEuNDQxVjEySDF2LTEuNjQ0aDEuMDA2VjYuMDc5SDFWNC40MzVoMy4xNjh2MS4xMzlhMi41MDcgMi41MDcgMCAwIDEgMi4zLTEuMjlBMi40NTIgMi40NTIgMCAwIDEgOC45MzEgNS45MSAyLjUzNSAyLjUzNSAwIDAgMSAxMS40IDQuMjg0IDIuNDQ4IDIuNDQ4IDAgMCAxIDE0IDYuOXYzLjQ1OHonIGZpbGw9JyNmZmYnLz4gPC9zdmc+\">About Us</A>\n    </DL><p>\n    <DT><H3 ADD_DATE=\"1597805921\" LAST_MODIFIED=\"1659320166\" PERSONAL_TOOLBAR_FOLDER=\"true\">Bookmarks Toolbar</H3>\n    <DL><p>\n        <DT><A HREF=\"https://www.mozilla.org/en-US/firefox/central/\" ADD_DATE=\"1597805921\" LAST_MODIFIED=\"1597805921\" ICON_URI=\"fake-favicon-uri:https://www.mozilla.org/en-US/firefox/central/\" ICON=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH4QsJCyMZzYMsXAAACVZJREFUWMOtl3mMX1UVxz/n3vve7/d+2yyd6bQdp6UtSwGrkgKW1FjFDdyDCAQTFTHGLRo33OMSExdwC0bREP8AFyLRGDVEa1gkYmuLWCmmFNvpQJm2Q6fTzm99y1384/dry6ZR40u+ue8l773zOffcc+65wv/pKvaCGV1CyLPLkVxE4tutbROt+Pffyf8LwB9S4P1yKZ/zK+jZYPdfIaIPuNRhVv4XAJ2xjU95rs5vIwDqrQcRZ7WvJhNUSmuolFZSMkOUAiS2RRQ/+tirz3zp1NCyzyGJwj58W/AH3s8NHOc0NJCr9z4TwDz5YW7ly+lASYs7H/HbnUgx9sJtrCiyWqP5xOZuZehyj1yEqOcgkqBEoT2YEIZqs73DxaRMqVhBFcy6KyQ02uGFe7bQtFo63GZ/JpgrwlMA1ImbfZOvJYhQYC6xor4QdBheOna3NI7PbRbvbiOE271EbxelzkpMWo20U2gg8mCCnFafrqypHkwgAgJQUajT3ibnnvVdGY8+FlazUtXCv56BAsVCUauWTf4eJ/birsTXbrLfz1vR0CdyauMi8KLKdt609LdUahlfzj7NPjkdlAcNk8ksddOCIAMAIOiIidVjRHpMju79gO91P+634tRFzwKQIgTxqx2cVxUnQ6XeZ79duU274VB6vD7KYqPC6ye3UNQV1y5+j32sAXPCo4AEj4QMQgHoAUToDyNTEKtrVHv6d5jk9/k9c8QveRpAhsMjK8ckHV5uFimXupVlSQ+qPS4cTmEkgyTjs8c+yR3dS6E6sOEFvDDbWU6z0CyJjoMsgxD6gv5YnhhFuC6099xvJkePwcKpNfDY8tegZ18lU9K7YJnuxCVVgPF9D430FfVfL3cgDin4AE6BVWBhb/N0/rqwDtx+8PkpAO8h+D6sGd0syZmXyej55H+uAaC3jV5FXVvK1f2bEl1cn5i0ZqICSSxULVSLvmoFiHBeb4ZNjft50dg2njM0y8PZOgoicl/GWsdrlv4aIx4YHsxAOAUTRBPMeFg88ktVWdL7wo1zqMRHzLZWRN6b9whMKDwigAqgnyQVAKHuu1wS3cm7h27i2tEfktgUMgOF4ZcHLuOWRy4j5Pug2A/egvPg3CkF2UDUuFjiOs1tz8P4oIl18VwX1CtEfL80SRiMT1PsQXuaeYN7Dr+E63vvZd6NQCTgDT0zzmd2fpHEpVy99ldo0wO9qr/UToTC+1hCeH2+0PxF0oid0eJIXXRuCDL8jCR9etqWHA+Vl3PdzEe5x2ymVxmHpBjEWoNVHJG1fPDP3yLppFx+1h0QdcCsBsrgXR/E+wtMyUyAP6jKCBLUkoCKQ5BB9sjJLCKAdwqXG7wTdri13N28kDwzkKbQy/tKC0gtZJZj6STfefAaFmdq0DoKnYchXwRrBypWyHxnQzjnAcwZkzvYOn3xmT4oPAqPEALIIL2azQqd4zW2ujVs0c9jPhqnmjbJVCDzHuvKhCKCyIFRoBUg7Oycze7OajYe3AUTbcimIR6Eo7B15tL3h5sn/mB+9Pe3lKZK85Pea7zXhKDAK3BClkYstsrUyhm7W1Pc2b2AUKlQSVpoAso5cpdT5GV8FBOMBqVACa1eiWm1jI1qFxwHKh0oDkM0DoVHLEvCUGxMBwlF0AetN7igcUETvCBO4dOIEXHUopxLxh/iT7PrmOlNISGADYTCI7lFRzk+Nngd4ZUmKEXodshyBSuA+UFxlEVwCVhDEJf7YefM+eX5/JiNdhc+pnARzht8UKhCUTIWKTuIPBsmpvniilv5wT8u5ZHuKmrVgjOnDlJp5OxcOIf759aTS6lvXBQqm2MiPjIoYEAGKAe+DT6Bsp/rRLZrFoqEInAgd7EtXGwK34fQtkB56ee/6deBDaP7uGHyJo6qOvXhLiNLWqhqoBWqfOmud/GTnZeCEnxQLKvs4ezRxyAHPFAMUtmmoCAY/+Bo5guTeYULsjd38ULmyksLF2O9IXIasa6fBdZQLI4gVKmOdKgPHQM8vqt5ZG4JW2fX0D2SU+8sEJQit47XvuAPrKodhUXAPrkFciBp2znuJQ+YLoECvT9x8a7UJi/LbJncxMQuR+UOco3KLKKFh/adwVFbo9bo0C0X/K3T4K7HzuFwezmYElVznNxrzp36O+/YdDcqDdAB3ImNqw/gcdt7md4hAuZR1WFTqHcWvP51r0gu7tlEyq5MyWdoa1E9A7EjLqUMJwf58cMXsPuhteRBYymhTIm67uHyAq9h/eq9fPiNv2FV7Rg0gd7AsB+ASMisUzc3jG3eN9Po94Q/l8/ggpw2rIs7RpOjZy+pzDNUPkY1bhNFGVLPoZHBUMYRXWLL4bXsmJviiW6NzBtM5BkfbXLh+j1csvFBlo51+vEuBgoD4w7CXPVxO1vfjPHT8Y1P9PuBA6rLNWF05h7vv98pajckRc/EOsOoAiUO0+3vAejAeCPj6rU7ecO6XSwQ09WKcj1lbKxJtZEiEdAexNufqqZYCIcrhJn6o3Y0PXqiH9YAvw1beT4baQfZU0I9VxPOMtqilUMrhwqhvxkOPpIgxNoylPQYq7YZTrrE4hA3WHB24PnAazIhtCPcfC13w72vlh+v3zdz7jw3/i70AQAWylO8wo+kzSAPGvRFWliulUOLR4lH+4D4AUTol2mcGjQletCYKCgUWBlACPQ0tGLoGuuMu+lo7L6ZjabFyk8Xp2YAYMbuYql6Pq/U0ZFZz191UBuUsFwNAOQEhBsY9+oUhB1A5BpyNRgNdA0slvCdaC5L9VcOt+OvlFPTXvqN1smsPAkAsC1sR+n1XGnMwX94/miCWimotSIoERDpN8HKCrgnz8DA85PGNaETUSzU8rxnbm9l6kP3HmrcrnOVnnHrE0/Z4Z/1aHZ2dDU3mhEOeUamTPHOkaj3vnrcXlWLWyRRl5LO0LpARQ7KFkoOYgexx+rAojUc79btYjpy8yFbua6hfOvFD3wS2PwMW/rZAOb9Lm6xO9hUWp/eadk2pWSLQhZDUCMh6EYIyggK8YIUCsn1Sc+L1OTdNNqdO/laC3/9eNRsXnj/m4Ern83Uf3Y4/Xz9KqatkivLxcSyKH9BQ2fnVUx2eknn45HOS0ZcIcod89rvz41/II3d9p2V9qGJIg4btk3/23//D6fjH/HBsZv5SzqsXpd0ogmTq654f28WFT/91F1ePvIR4Ov/8d/+CfHfpDCA/XdnAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTExLTA5VDExOjM1OjI1KzAxOjAw560ORgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0xMS0wOVQxMTozNToyNSswMTowMJbwtvoAAABXelRYdFJhdyBwcm9maWxlIHR5cGUgaXB0YwAAeJzj8gwIcVYoKMpPy8xJ5VIAAyMLLmMLEyMTS5MUAxMgRIA0w2QDI7NUIMvY1MjEzMQcxAfLgEigSi4A6hcRdPJCNZUAAAAASUVORK5CYII=\">Getting Started</A>\n        <DT><H3 ADD_DATE=\"1659320194\" LAST_MODIFIED=\"1659320276\">Example Folder Toolbar</H3>\n        <DL><p>\n            <DT><H3 ADD_DATE=\"1659320232\" LAST_MODIFIED=\"1659320276\">Example Nested Folder Toolbar</H3>\n            <DL><p>\n                <DT><A HREF=\"https://example.org/#toolbar\" ADD_DATE=\"1659320254\" LAST_MODIFIED=\"1659320276\" TAGS=\"tag2,tag6,tag7\">Example Org Toolbar</A>\n            </DL><p>\n            <DT><A HREF=\"https://example.net/#toolbar\" ADD_DATE=\"1659320211\" LAST_MODIFIED=\"1659320226\" TAGS=\"tag4,tag5,tag1\">Example Net Toolbar</A>\n        </DL><p>\n        <DT><A HREF=\"https://example.edu/#toolbar\" ADD_DATE=\"1659320286\" LAST_MODIFIED=\"1659320298\" TAGS=\"tag2,tag3\">Example Edu Toolbar</A>\n        <DT><A HREF=\"https://example.com/#toolbar\" ADD_DATE=\"1659320158\" LAST_MODIFIED=\"1659320166\" TAGS=\"tag2,tag1\">Example Com Toolbar</A>\n    </DL><p>\n    <DT><H3 ADD_DATE=\"1597805921\" LAST_MODIFIED=\"1659320551\" UNFILED_BOOKMARKS_FOLDER=\"true\">Other Bookmarks</H3>\n    <DL><p>\n        <DT><A HREF=\"https://example.com/#other\" ADD_DATE=\"1659320430\" LAST_MODIFIED=\"1659320564\" TAGS=\"tag1,tag2\">Example Com Other</A>\n        <DT><H3 ADD_DATE=\"1659320410\" LAST_MODIFIED=\"1659320570\">Example Folder Other</H3>\n        <DL><p>\n            <DT><H3 ADD_DATE=\"1659320410\" LAST_MODIFIED=\"1659320581\">Example Nested Folder Other</H3>\n            <DL><p>\n                <DT><A HREF=\"https://example.org/#other\" ADD_DATE=\"1659320410\" LAST_MODIFIED=\"1659320599\" TAGS=\"tag2,tag6,tag7\">Example Org Other</A>\n            </DL><p>\n            <DT><A HREF=\"https://example.net/#other\" ADD_DATE=\"1659320410\" LAST_MODIFIED=\"1659320588\" TAGS=\"tag1,tag4,tag5\">Example Net Other</A>\n        </DL><p>\n        <DT><A HREF=\"https://example.edu/#other\" ADD_DATE=\"1659320410\" LAST_MODIFIED=\"1659320576\" TAGS=\"tag2,tag3\">Example Edu Other</A>\n    </DL><p>\n</DL>\n"
  },
  {
    "path": "test/fixtures/example.asciidoc",
    "content": "= Example AsciiDoc Title\n\nExample AsciiDoc content.\n\n[[example-inline-anchor]]Example Inline Anchor\n\nSample subsequent AsciiDoc content containing [[wiki-style link]] inline.\n\n[[wiki-style link]] Demo content.\n\n- one\n- two\n- [[wiki-style link]]\n- four\n"
  },
  {
    "path": "test/fixtures/example.com-og.html",
    "content": "<!doctype html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\n    <meta data-rh=\"true\" property=\"og:title\" content=\"Example OG Title\" />\n    <meta data-rh=\"true\" property=\"og:description\" content=\"Example OG description.\" />\n\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 2em;\n        background-color: #fdfdff;\n        border-radius: 0.5em;\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        div {\n            margin: 0 auto;\n            width: auto;\n        }\n    }\n    </style>\n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "test/fixtures/example.com-titles-newlines.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n\n  <title example>\n    \n    Title One\n    \n  </title>\n\n  <title example>Title Two</title>\n  <meta name=\"description\" content=\"Example description.\" />\n\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n  <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 2em;\n        background-color: #fdfdff;\n        border-radius: 0.5em;\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        div {\n            margin: 0 auto;\n            width: auto;\n        }\n    }\n    </style>\n\n    <title abc></title><title example-example>sample</title><title abc></title>\n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "test/fixtures/example.com-titles.html",
    "content": "<!doctype html>\n<html>\n<head>\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" /><title> ‪  Title   One   </title><meta charset=\"utf-8\" /><title> ‪  Title   Two   </title> <title>   Title   Three   </title><meta name=\"description\" content=\"Example description.\" />\n\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 2em;\n        background-color: #fdfdff;\n        border-radius: 0.5em;\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        div {\n            margin: 0 auto;\n            width: auto;\n        }\n    }\n    </style>\n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "test/fixtures/example.com.html",
    "content": "<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"description\" content=\"Example description.\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 2em;\n        background-color: #fdfdff;\n        border-radius: 0.5em;\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        div {\n            margin: 0 auto;\n            width: auto;\n        }\n    }\n    </style>\n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "test/fixtures/example.com.md",
    "content": "# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\n"
  },
  {
    "path": "test/fixtures/example.edu.html",
    "content": "<!DOCTYPE html>\n<!-- saved from url=(0020)https://example.edu/ -->\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Example Domain</title>\n\n    \n    \n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 2em;\n        background-color: #fdfdff;\n        border-radius: 0.5em;\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        div {\n            margin: 0 auto;\n            width: auto;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n\n\n</body></html>"
  },
  {
    "path": "test/fixtures/example.md",
    "content": "# Example Title\n\nExample body with *formatting*.\n"
  },
  {
    "path": "test/fixtures/example.net.html",
    "content": "<!DOCTYPE html>\n<!-- saved from url=(0020)https://example.net/ -->\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Example Domain</title>\n\n    \n    \n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 2em;\n        background-color: #fdfdff;\n        border-radius: 0.5em;\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        div {\n            margin: 0 auto;\n            width: auto;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n\n\n</body></html>"
  },
  {
    "path": "test/fixtures/example.org",
    "content": "#+BEGIN_COMMENT\nExample Org mode file.\n\nResources:\n  https://writequit.org/denver-emacs/presentations/files/example.org.html\n  https://orgmode.org/guide/index.html\n#+END_COMMENT\n\n#+TITLE: Example .org Title\n\n- _underscores let you underline things_\n- *stars add emphasis*\n- /slashes are italics/\n- +pluses are strikethrough+\n- =equal signs are verbatim text=\n- ~tildes can also be used~\n\nSample text with link. [[home:1]]\n"
  },
  {
    "path": "test/fixtures/example.org.html",
    "content": "<!DOCTYPE html>\n<!-- saved from url=(0020)https://example.org/ -->\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Example Domain</title>\n\n    \n    \n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 2em;\n        background-color: #fdfdff;\n        border-radius: 0.5em;\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        div {\n            margin: 0 auto;\n            width: auto;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n\n\n</body></html>"
  },
  {
    "path": "test/folders-add-scoped.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'add <notebook>:<folder-name>/<folder-name>/<filename>' with existing file creates another with incremented filename.\"  {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                          \\\n      \"home:Example Folder/Sample Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[    -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\"    ]]\n    [[ !  -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File-1.md\"  ]]\n  }\n\n  run \"${_NB}\" add                                        \\\n      \"home:Example Folder/Sample Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates file:\n\n  [[    -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\"    ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File-1.md\"  ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"         ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"     ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                        ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"                ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                            ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File-1.md ]]\n}\n\n# notebook:folder/example.md ##################################################\n\n@test \"'add notebook:folder/example.md' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example-filename.md\"  ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" add \"home:Example Folder/example-filename.md\" --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ -e \"${NB_DIR}/home/Example Folder/example-filename.md\"     ]]\n  [[    \"${#_folder_files[@]}\" == 4                             ]]\n  [[    \"${_folder_files[2]}\"  == \".index\"                      ]]\n  [[    \"${_folder_files[3]}\"   == \"example-filename.md\"        ]]\n\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-filename.md ]]\n}\n\n# notebook:folder/ #####################################################################\n\n@test \"'add folder notebook:<folder>/' (trailing slash) creates new nested folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"                      ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/Sample Folder/.index\" ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" add folder \"home:Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  [[ -d \"${NB_DIR}/home/Example Folder/folder\"        ]]\n  [[ -f \"${NB_DIR}/home/Example Folder/folder/.index\" ]]\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home\"))\n\n  echo \"_files: ${_files[*]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"   ]]\n  [[ \"${#_files[@]}\"  == 5                ]]\n  [[ \"${_files[3]}\"   == \".index\"         ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\" ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  echo \"_folder_files: ${_folder_files[*]}\"\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n  [[ \"${#_folder_files[@]}\" == 4                        ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                 ]]\n  [[ \"${_folder_files[3]}\"  != \"Sample Folder\"          ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  cat \"${NB_DIR}/home/.index\"\n  cat \"${NB_DIR}/home/Example Folder/.index\"\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"    ]]\n\n  # Prints output:\n\n  [[    \"${output}\" =~ Added:                                     ]]\n  [[    \"${output}\" =~ 📂                                         ]]\n  [[    \"${output}\" =~ home:Example\\ Folder/1                     ]]\n  [[    \"${output}\" =~ home:Example\\ Folder/folder                ]]\n  [[ !  \"${output}\" =~ \\.                                         ]]\n}\n\n@test \"'add notebook:<folder>/ --filename' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"            ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"     ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" add home:Example\\ Folder/ --content \"# Example Title\" \\\n    --filename \"example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ example-filename.md          ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                        ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                        ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/example-filename.md      ]]\n}\n\n@test \"'add notebook:<folder>/' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"            ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"     ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" add home:Example\\ Folder/ --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ [0-9]+.md                    ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                          ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1          ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/[0-9]+.md  ]]\n}\n"
  },
  {
    "path": "test/folders-add.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# aliases #####################################################################\n\n@test \"'add folders' adds folder.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add folders Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[    -d \"${NB_DIR}/home/Example Folder\"        ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"                       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ Added:\\ .*[.*1.*].*\\ 📂\\ .*Example\\ Folder  ]]\n}\n\n@test \"'folders add' adds folder.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" folders add Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[    -d \"${NB_DIR}/home/Example Folder\"        ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"                       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ Added:\\ .*[.*1.*].*\\ 📂\\ .*Example\\ Folder  ]]\n}\n\n@test \"'folder add' adds folder.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" folder add Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[    -d \"${NB_DIR}/home/Example Folder\"        ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"                       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ Added:\\ .*[.*1.*].*\\ 📂\\ .*Example\\ Folder  ]]\n}\n\n# local #######################################################################\n\n@test \"'add <selector-with-folder-and-filename>' adds to local notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n  }\n\n  run \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n    --title         \"Title One\"                                                 \\\n    --content       \"Content one.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[ -f \"${_TMP_DIR}/Example Local/Example Folder/Sample Folder/Demo Folder/Example File.md\" ]]\n\n  cat \"${_TMP_DIR}/Example Local/Example Folder/Sample Folder/Demo Folder/Example File.md\"\n\n  diff                                                                                          \\\n    <(cat \"${_TMP_DIR}/Example Local/Example Folder/Sample Folder/Demo Folder/Example File.md\") \\\n    <(printf \"# Title One\\\\n\\\\nContent one.\\\\n\")\n\n  while [[ -n \"$(git -C \"${_TMP_DIR}/Example Local\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${_TMP_DIR}/Example Local\" log\n\n  git -C \"${_TMP_DIR}/Example Local\" log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ \\\n       \\ .*Example\\ Folder/Sample\\ Folder/Demo\\ Folder/Example\\ File.md ]]\n  [[ \"${output}\" =~ \\\n       Added:\\ .*[.*Example\\ Folder/Sample\\ Folder/Demo\\ Folder/1.*]    ]]\n}\n\n# arguments ##################################################################\n\n@test \"'add <selector-with-folder>/ --filename <relative-path> --folder <notebook> <folder> <content>' (slash) creates file at <selector-with-folder>/<relative-path> containing <notebook>, <folder>, and <content> as content.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Test Folder\" --type \"folder\"\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" add          \\\n    \"Example Folder/\"       \\\n    \"Example Notebook:\"     \\\n    \"Test Folder/\"          \\\n    \"Example content.\"      \\\n    --folder \"Demo Folder\"  \\\n    --filename \"Sample Folder/Sample File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[    -f \"${NB_DIR}/home/Example Folder/Demo Folder/Sample Folder/Sample File.md\" ]]\n\n  cat \"${NB_DIR}/home/Example Folder/Demo Folder/Sample Folder/Sample File.md\"\n\n  diff                                                                              \\\n    <(cat \"${NB_DIR}/home/Example Folder/Demo Folder/Sample Folder/Sample File.md\") \\\n    <(printf \"Example Notebook: Test Folder/ Example content.\\\\n\")\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ \\\n       \\ .*Example\\ Folder/Demo\\ Folder/Sample\\ Folder/Sample\\ File.md ]]\n  [[ \"${output}\" =~ \\\n       Added:\\ .*[.*Example\\ Folder/Demo\\ Folder/Sample\\ Folder/1.*]   ]]\n}\n\n# --filename ##################################################################\n\n@test \"'add --filename <relative-path>' option creates file at <relative-path>.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add    \\\n    \"Sample content.\" \\\n    --filename \"Sample Folder/Sample File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[    -f \"${NB_DIR}/home/Sample Folder/Sample File.md\" ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  grep -q \"Sample content.\" \"${NB_DIR}/home/Sample Folder/Sample File.md\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ \\\n       Added:\\ .*[.*Sample\\ Folder/1.*].*\\ .*Sample\\ Folder/Sample\\ File.md ]]\n}\n\n@test \"'add <selector-with-filename> --filename <relative-path>' option overrides selector with <relative-path>.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add                    \\\n    \"Example Folder/Example File.md\"  \\\n    --filename \"Sample Folder/Sample File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[ !  -e \"${NB_DIR}/home/Example Folder/Example File.md\"  ]]\n  [[    -f \"${NB_DIR}/home/Sample Folder/Sample File.md\"    ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  grep -q \"Example Folder/Example File.md\" \"${NB_DIR}/home/Sample Folder/Sample File.md\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ \\\n       Added:\\ .*[.*Sample\\ Folder/1.*].*\\ .*Sample\\ Folder/Sample\\ File.md ]]\n}\n\n@test \"'add <selector-with-folder>/ --filename <relative-path>' (slash) creates file at <selector-with-folder>/<relative-path>.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add    \\\n    \"Example Folder/\" \\\n    --filename \"Sample Folder/Sample File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[ !  -e \"${NB_DIR}/home/Example Folder/Sample File.md\"               ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/Sample Folder/Sample File.md\" ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  grep -q  \"mock_editor\"  \"${NB_DIR}/home/Example Folder/Sample Folder/Sample File.md\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ \\\n       \\ .*Example\\ Folder/Sample\\ Folder/Sample\\ File.md ]]\n  [[ \"${output}\" =~ \\\n       Added:\\ .*[.*Example\\ Folder/Sample\\ Folder/1.*]   ]]\n}\n\n@test \"'add <selector-with-folder>/ --filename <relative-path> --folder <folder>' (slash) creates file at <selector-with-folder>/<folder>/<relative-path>.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add          \\\n    \"Example Folder/\"       \\\n    --folder \"Demo Folder\"  \\\n    --filename \"Sample Folder/Sample File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[    -f \"${NB_DIR}/home/Example Folder/Demo Folder/Sample Folder/Sample File.md\" ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  grep -q  \"mock_editor\"  \"${NB_DIR}/home/Example Folder/Demo Folder/Sample Folder/Sample File.md\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ \\\n       \\ .*Example\\ Folder/Demo\\ Folder/Sample\\ Folder/Sample\\ File.md ]]\n  [[ \"${output}\" =~ \\\n       Added:\\ .*[.*Example\\ Folder/Demo\\ Folder/Sample\\ Folder/1.*]   ]]\n}\n\n@test \"'add <selector-with-folder> --filename <relative-path>' (no slash) creates file at relative-path> and <selector-with-folder>  as content.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add    \\\n    \"Example Folder\"  \\\n    --filename \"Sample Folder/Sample File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[ !  -e \"${NB_DIR}/home/Example Folder/Example File.md\"  ]]\n  [[    -f \"${NB_DIR}/home/Sample Folder/Sample File.md\"    ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  grep -q             \\\n    \"Example Folder\"  \\\n    \"${NB_DIR}/home/Sample Folder/Sample File.md\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\" =~ \\\n       Added:\\ .*[.*Sample\\ Folder/1.*].*\\ .*Sample\\ Folder/Sample\\ File.md ]]\n}\n\n# <folder>/ <filename> ########################################################\n\n@test \"'add <not-a-folder-name> <string>' (no slash) creates new file containing content <not-a-folder-name> and <string> separated by a space.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder\"                     ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder/.index\"              ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder/example-filename.md\" ]]\n  }\n\n  run \"${_NB}\" add Example\\ Not\\ A\\ Folder Sample\\ String\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates file:\n\n  _files=($(LC_ALL=C ls \"${NB_DIR}/home/\"))\n\n  [[   -n \"${_files[0]:-}\"                                            ]]\n\n  [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder\"                     ]]\n  [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder/.index\"              ]]\n  [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder/example-filename.md\" ]]\n  [[   -e \"${NB_DIR:-}/home/${_files[0]}\"                             ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[    -e \"${NB_DIR}/home/.index\"                      ]]\n  [[ !  -e \"${NB_DIR}/home/Example Not A Folder/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:          ]]\n  [[ \"${output}\" =~ ${_files[0]:-}  ]]\n\n  # File contains content:\n\n  printf \"cat: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_files[0]:-}\")\"\n\n  diff                                                \\\n    <(printf \"Example Not A Folder Sample String\\\\n\") \\\n    <(cat \"${NB_DIR}/home/${_files[0]:-}\")\n}\n\n@test \"'add <folder> <filename>' (no slash) creates new file with <filename> and the string in <folder> as content.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[   -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n    [[   -e \"${NB_DIR:-}/home/Example Folder/.index\"              ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/example-filename.md\" ]]\n  }\n\n  run \"${_NB}\" add Example\\ Folder \"example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates folder and files:\n\n  [[   -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n  [[   -e \"${NB_DIR:-}/home/Example Folder/.index\"              ]]\n  [[ ! -e \"${NB_DIR:-}/home/Example Folder/example-filename.md\" ]]\n  [[   -e \"${NB_DIR:-}/home/example-filename.md\"                ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: example-filename.md'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                 ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:              ]]\n  [[ \"${output}\" =~ example-filename.md ]]\n\n  # File contains content:\n\n  diff                            \\\n    <(printf \"Example Folder\\\\n\") \\\n    <(cat \"${NB_DIR}/home/example-filename.md\")\n}\n\n@test \"'add <not-a-folder-name> <filename>' (no slash) creates new file with <filename> containing content <not-a-folder-name>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder\"                     ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder/.index\"              ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder/example-filename.md\" ]]\n  }\n\n  run \"${_NB}\" add Example\\ Not\\ A\\ Folder \"example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates folder and files:\n\n  [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder\"                     ]]\n  [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder/.index\"              ]]\n  [[ ! -e \"${NB_DIR:-}/home/Example Not A Folder/example-filename.md\" ]]\n  [[   -e \"${NB_DIR:-}/home/example-filename.md\"                      ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: example-filename.md'\n\n  # Adds to index:\n\n  [[    -e \"${NB_DIR}/home/.index\"                      ]]\n  [[ !  -e \"${NB_DIR}/home/Example Not A Folder/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:              ]]\n  [[ \"${output}\" =~ example-filename.md ]]\n\n  # File contains content:\n\n  diff                                  \\\n    <(printf \"Example Not A Folder\\\\n\") \\\n    <(cat \"${NB_DIR}/home/example-filename.md\")\n}\n\n@test \"'add <folder>/ <filename>' (slash) creates new file with <filename> in new <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"              ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/example-filename.md\" ]]\n  }\n\n  run \"${_NB}\" add Example\\ Folder/ \"example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates folder and files:\n\n  [[   -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n  [[   -e \"${NB_DIR:-}/home/Example Folder/.index\"              ]]\n  [[   -e \"${NB_DIR:-}/home/Example Folder/example-filename.md\" ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example Folder/example-filename.md'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                 ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-filename.md ]]\n}\n\n@test \"'add <folder>/ <filename> --folder-prompt' (slash) with affirmative prompt response creates new file with <filename> in new <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"              ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/example-filename.md\" ]]\n  }\n\n  run \"${_NB}\" add Example\\ Folder/ \"example-filename.md\" --folder-prompt <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates folder and files:\n\n  [[   -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n  [[   -e \"${NB_DIR:-}/home/Example Folder/.index\"              ]]\n  [[   -e \"${NB_DIR:-}/home/Example Folder/example-filename.md\" ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example Folder/example-filename.md'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                 ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-filename.md ]]\n}\n\n@test \"'add <folder>/ <filename> --folder-prompt' (slash) with negative prompt response creates new file with <filename> in new <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"              ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/example-filename.md\" ]]\n  }\n\n  run \"${_NB}\" add Example\\ Folder/ \"example-filename.md\" --folder-prompt <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Does not create folder and files:\n\n  [[ ! -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n  [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"              ]]\n  [[ ! -e \"${NB_DIR:-}/home/Example Folder/example-filename.md\" ]]\n\n  # Does not commit to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Add: Example Folder/example-filename.md'\n\n  # Does not add to index:\n\n  [[    -e \"${NB_DIR}/home/.index\"                    ]]\n  [[ !  -e \"${NB_DIR}/home/Example Folder/.index\"     ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Creating\\ new\\ folder:\\ .*Example\\ Folder ]]\n  [[ \"${output}\" =~ Exiting\\.\\.\\.                             ]]\n}\n\n@test \"'add <name-1> <name-2> --type folder' (no slash) creates new folder with <name-1>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"         ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"  ]]\n    [[ ! -e \"${NB_DIR:-}/home/Sample Folder\"          ]]\n    [[ ! -e \"${NB_DIR:-}/home/Sample Folder/.index\"   ]]\n  }\n\n  run \"${_NB}\" add  \\\n    Example\\ Folder \\\n    Sample\\ Folder  \\\n    --type folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  [[    -d \"${NB_DIR}/home/Example Folder\"        ]]\n  [[    -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n  [[ !  -e \"${NB_DIR}/home/Sample Folder\"         ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example Folder'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:          ]]\n  [[ \"${output}\" =~ Example\\ Folder ]]\n}\n\n@test \"'add <folder>/ <folder-name> --type folder' (slash) creates new folder with <folder-name> in new <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/example-folder-name\" ]]\n  }\n\n  run \"${_NB}\" add        \\\n    Example\\ Folder/      \\\n    \"example-folder-name\" \\\n    --type folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path indexes:\n\n  [[ !  -e \"${NB_DIR}/home/example-folder-name\"                       ]]\n  [[    -d \"${NB_DIR}/home/Example Folder/example-folder-name\"        ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/.index\"                     ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/example-folder-name/.index\" ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example Folder/example-folder-name'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                 ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-folder-name ]]\n}\n\n# --folder option #############################################################\n\n@test \"'add --folder <folder> --filename <folder-name> --type folder' creates new folders without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"                     ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/example-folder-name\" ]]\n  }\n\n  run \"${_NB}\" add            \\\n    --folder Example\\ Folder  \\\n    --type folder             \\\n    --filename \"example-folder-name\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path indexes:\n\n  [[ !  -e \"${NB_DIR}/home/example-folder-name\"                       ]]\n  [[    -d \"${NB_DIR}/home/Example Folder/example-folder-name\"        ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/.index\"                     ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/example-folder-name/.index\" ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                 ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-folder-name ]]\n}\n\n@test \"'add --folder <folder> --type folder' creates new folders without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"            ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/folder\"     ]]\n  }\n\n  run \"${_NB}\" add            \\\n    --folder Example\\ Folder  \\\n    --type folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path and indexes:\n\n  [[ !  -e \"${NB_DIR}/home/folder\"                        ]]\n  [[    -d \"${NB_DIR}/home/Example Folder/folder\"         ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/.index\"         ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/folder/.index\"  ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                 ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                      ]]\n  [[ \"${output}\" =~ Example\\ Folder/folder      ]]\n}\n\n@test \"'add --folder <folder> --filename' (no slash) creates new file and folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"            ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"     ]]\n  }\n\n  run \"${_NB}\" add              \\\n    --folder Example\\ Folder    \\\n    --content \"# Example Title\" \\\n    --filename \"example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ example-filename.md          ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                 ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-filename.md ]]\n}\n\n@test \"'add --folder <folder>' (no slash) creates new file and folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"            ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"     ]]\n  }\n\n  run \"${_NB}\" add              \\\n    --folder Example\\ Folder    \\\n    --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ [0-9]+.md                    ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                 ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                      ]]\n  [[ \"${output}\" =~ Example\\ Folder/[0-9]+.md   ]]\n}\n\n@test \"'add --folder <folder>/ --filename' (slash) creates new file and folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"            ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"     ]]\n  }\n\n  run \"${_NB}\" add --folder Example\\ Folder/ --content \"# Example Title\" \\\n    --filename \"example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ example-filename.md          ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-filename.md ]]\n}\n\n@test \"'add --folder <folder>/' (slash) creates new file and folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"            ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"     ]]\n  }\n\n  run \"${_NB}\" add Example\\ Folder/ --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ [0-9]+.md                    ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                 ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/[0-9]+.md ]]\n}\n\n# <id>/ #####################################################################\n\n@test \"'add folder <id>/' (trailing slash) creates new nested folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[   -d \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[   -f \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add folder \"1/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  [[ -d \"${NB_DIR}/home/Example Folder/folder\"          ]]\n  [[ -f \"${NB_DIR}/home/Example Folder/folder/.index\"   ]]\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"_files: ${_files[*]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n  [[ \"${#_files[@]}\"  == 5                              ]]\n  [[ \"${_files[3]}\"   == \".index\"                       ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"               ]]\n\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  echo \"_folder_files: ${_folder_files[*]}\"\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n  [[ \"${#_folder_files[@]}\" == 4                        ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                 ]]\n  [[ \"${_folder_files[3]}\"  == \"folder\"                 ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  cat \"${NB_DIR}/home/.index\"\n  cat \"${NB_DIR}/home/Example Folder/.index\"\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"    ]]\n\n  # Prints output:\n\n  [[    \"${output}\" =~ Added:                 ]]\n  [[    \"${output}\" =~ 📂                     ]]\n  [[    \"${output}\" =~ Example\\ Folder/folder ]]\n  [[ !  \"${output}\" =~ \\.                     ]]\n}\n\n@test \"'add folder <id>/' (trailing slash) creates new nested folder with incremented name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/folder\" --type folder\n\n    [[   -d \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[   -f \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[   -d \"${NB_DIR}/home/Example Folder/folder\"               ]]\n    [[   -f \"${NB_DIR}/home/Example Folder/folder/.index\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/folder-1\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add folder \"1/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  [[ -d \"${NB_DIR}/home/Example Folder/folder-1\"        ]]\n  [[ -f \"${NB_DIR}/home/Example Folder/folder-1/.index\" ]]\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"_files:  ${_files[*]}\"\n  echo \"#_files: ${#_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"     ]]\n  [[ \"${#_files[@]}\"  == 5                  ]]\n  [[ \"${_files[3]}\"   == \".index\"           ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"   ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  echo \"_folder_files: ${_folder_files[*]}\"\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n  [[ \"${#_folder_files[@]}\" == 5                        ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                 ]]\n  [[ \"${_folder_files[3]}\"  == \"folder\"                 ]]\n  [[ \"${_folder_files[4]}\"  == \"folder-1\"               ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  cat \"${NB_DIR}/home/.index\"\n  cat \"${NB_DIR}/home/Example Folder/.index\"\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"    ]]\n\n  # Prints output:\n\n  [[    \"${output}\" =~ Added:                   ]]\n  [[    \"${output}\" =~ 📂                       ]]\n  [[    \"${output}\" =~ Example\\ Folder/folder-1 ]]\n  [[ !  \"${output}\" =~ \\.                       ]]\n}\n\n@test \"'add folder <id>/<folder>' creates new nested folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[   -d \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[   -f \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add folder \"1/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"_files: ${_files[*]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n  [[ \"${#_files[@]}\"  == 5                              ]]\n  [[ \"${_files[3]}\"   == \".index\"                       ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"               ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  echo \"_folder_files: ${_folder_files[*]}\"\n\n  [[   -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n  [[ \"${#_folder_files[@]}\" == 4                        ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                 ]]\n  [[ \"${_folder_files[3]}\"  == \"Sample Folder\"          ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  cat \"${NB_DIR}/home/.index\"\n  cat \"${NB_DIR}/home/Example Folder/.index\"\n\n  [[   -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"    ]]\n\n  # Prints output:\n\n  [[    \"${output}\" =~ Added:                         ]]\n  [[    \"${output}\" =~ 📂                             ]]\n  [[    \"${output}\" =~ Example\\ Folder/Sample\\ Folder ]]\n  [[ !  \"${output}\" =~ \\.                             ]]\n  [[ !  \"${output}\" =~ folder                         ]]\n}\n\n@test \"'add <id>/ --filename' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[   -d \"${NB_DIR:-}/home/Example Folder\"         ]]\n    [[   -f \"${NB_DIR:-}/home/Example Folder/.index\"  ]]\n  }\n\n  run \"${_NB}\" add 1/ --content \"# Example Title\" \\\n    --filename \"example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ example-filename.md          ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  printf \"ls  Example Folder:         '%s'\\\\n\"  \\\n    \"$(ls \"${NB_DIR}/home/Example Folder/\")\"\n  printf \"cat Example Folder/.index:  '%s'\\\\n\"  \\\n    \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-filename.md ]]\n}\n\n@test \"'add <id>/' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[   -d \"${NB_DIR}/home/Example Folder\"             ]]\n    [[   -f \"${NB_DIR:-}/home/Example Folder/.index\"    ]]\n  }\n\n  run \"${_NB}\" add 1/ --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ [0-9]+.md                    ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/[0-9]+.md ]]\n}\n\n# folder/ #####################################################################\n\n@test \"'add folder <folder>/' (trailing slash) creates new nested folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add folder \"Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"_files: ${_files[*]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n  [[ \"${#_files[@]}\"  == 5                              ]]\n  [[ \"${_files[3]}\"   == \".index\"                       ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"               ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  echo \"_folder_files: ${_folder_files[*]}\"\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n  [[ \"${#_folder_files[@]}\" == 4                        ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                 ]]\n  [[ \"${_folder_files[3]}\"  != \"Sample Folder\"          ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  cat \"${NB_DIR}/home/.index\"\n  cat \"${NB_DIR}/home/Example Folder/.index\"\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"    ]]\n\n  # Prints output:\n\n  [[    \"${output}\" =~ Added:                   ]]\n  [[    \"${output}\" =~ 📂                       ]]\n  [[    \"${output}\" =~ Example\\ Folder/folder   ]]\n  [[ !  \"${output}\" =~ \\.                       ]]\n}\n\n@test \"'add <folder>/ --filename' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"            ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"     ]]\n  }\n\n  run \"${_NB}\" add Example\\ Folder/ --content \"# Example Title\" \\\n    --filename \"example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ example-filename.md          ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-filename.md ]]\n}\n\n@test \"'add <folder>/' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder\"            ]]\n    [[ ! -e \"${NB_DIR:-}/home/Example Folder/.index\"     ]]\n  }\n\n  run \"${_NB}\" add Example\\ Folder/ --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[    \"${#_files[@]}\"  == 5                                   ]]\n  [[    \"${_files[3]}\"   == \".index\"                            ]]\n  [[    \"${_files[4]}\"   == \"Example Folder\"                    ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[    \"${#_folder_files[@]}\"  == 4                            ]]\n  [[    \"${_folder_files[2]}\"   == \".index\"                     ]]\n  [[    \"${_folder_files[3]}\"   =~ [0-9]+.md                    ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"     ]]\n\n  printf \"File:\\\\n\"\n  cat \"${NB_DIR}/home/Example Folder/${_folder_files[3]}\"\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                    ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"            ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/[0-9]+.md ]]\n}\n\n# uniqueness ##################################################################\n\n@test \"'add <folder>/<folder>/example.md' with existing file at target creates file with unique filename.\" {\n  {\n    \"${_NB}\" init\n\n    _folder_path=\"${NB_DIR}/home/Example Folder/Sample Folder\"\n    _existing_file_path=\"${_folder_path}/example-filename.md\"\n    _new_file_path=\"${_folder_path}/example-filename-1.md\"\n\n    mkdir -p \"${_folder_path}\"\n\n    printf \"# Example Title\" > \"${_existing_file_path}\"\n    cat \"${_existing_file_path}\"\n\n    \"${_NB}\" index reconcile \"${_folder_path}\" --ancestors\n\n    [[ \"${status}\" -eq 0            ]]\n    [[ -e \"${_existing_file_path}\"  ]]\n\n    _file_content=\"$(cat \"${_existing_file_path}\")\"\n    printf \"_file_content: '%s'\\\\n\" \"${_file_content:-}\"\n\n    [[   \"${_file_content}\" =~ Example\\ Title      ]]\n    [[ ! \"${_file_content}\" =~ Example\\ Title\\ Two ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder/Sample Folder/example-filename.md\" --content \"# Example Title Two\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[ -e \"${_existing_file_path}\"                                  ]]\n\n  [[   \"$(cat \"${_existing_file_path}\")\"  =~ Example\\ Title       ]]\n  [[ ! \"$(cat \"${_existing_file_path}\")\"  =~ Example\\ Title\\ Two  ]]\n\n  [[ -e \"${_new_file_path}\"                                       ]]\n  [[ \"$(cat \"${_new_file_path}\")\"         =~ Example\\ Title\\ Two  ]]\n\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  ls \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"                                 ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" =~  example-filename.md   ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" =~  example-filename-1.md ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                                ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example-filename-1.md  ]]\n}\n\n@test \"'add folder <folder>/<folder>/<folder>' with existing folder at target creates folder with unique filename.\" {\n  {\n    \"${_NB}\" init\n\n    _folder_path=\"${NB_DIR}/home/Example Folder/Sample Folder\"\n    _existing_folder_path=\"${_folder_path}/Demo Folder\"\n\n    mkdir -p \"${_existing_folder_path}\"\n    touch \"${_existing_folder_path}/.index\"\n\n    [[ -d \"${_existing_folder_path}\"        ]]\n    [[ -f \"${_existing_folder_path}/.index\" ]]\n\n    \"${_NB}\" index reconcile \"${_existing_folder_path}\" --ancestors\n\n    [[ \"${status}\" -eq 0              ]]\n    [[ -e \"${_existing_folder_path}\"  ]]\n  }\n\n  run \"${_NB}\" add folder \"Example Folder/Sample Folder/Demo Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[ -e \"${_existing_folder_path}\"    ]]\n  [[ -e \"${_existing_folder_path}-1\"  ]]\n\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  ls \"${NB_DIR}/home/Example Folder/Sample Folder\"\n  echo ---\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"              ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" =~  \\\n        Demo\\ Folder${_NEWLINE}Demo\\ Folder-1$                            ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Demo\\ Folder-1   ]]\n}\n\n# error handling ##############################################################\n\n@test \"'add <folder>/<folder>/example.md' with existing file in path exits with error and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    touch \"${NB_DIR}/home/Example Folder\"\n\n    [[   -f \"${NB_DIR}/home/Example Folder\"                                    ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example-filename.md\"  ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder/Sample Folder/example-filename.md\" --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # Does not create path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -f \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example-filename.md\" ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Add'\n\n  # Does not change index::\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Unable\\ to\\ create\\ folder:     ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder  ]]\n}\n\n@test \"'add <folder>/<folder> --type folder' with existing file in path exits with error and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    touch \"${NB_DIR}/home/Example Folder\"\n\n    [[   -f \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder/Sample Folder\" --type \"folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # Does not create path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -f \"${NB_DIR}/home/Example Folder\"                           ]]\n  [[ \"${#_files[@]}\"  == 5                                        ]]\n  [[ \"${_files[3]}\"   == \".index\"                                 ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                         ]]\n\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"           ]]\n\n  # Does not commit to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"     ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Add'\n\n  # Does not change:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Unable\\ to\\ create\\ folder:     ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder  ]]\n}\n\n# folder <folder> #############################################################\n\n@test \"'add folder <folder>' creates new folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add folder \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"       ]]\n  [[ \"${#_folder_files[@]}\" == 3                              ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                       ]]\n  [[ \"${_folder_files[3]}\"  != \"Sample Folder\"                ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"     ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                        ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" ]]\n\n  cat \"${NB_DIR}/home/.index\"\n  cat \"${NB_DIR}/home/Example Folder/.index\"\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"        ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:           ]]\n  [[ \"${output}\" =~ Example\\ Folder  ]]\n}\n\n@test \"'add folder <folder>/<folder>' creates new folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add folder \"Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ \"${#_folder_files[@]}\" == 4                              ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                       ]]\n  [[ \"${_folder_files[3]}\"  == \"Sample Folder\"                ]]\n\n  _folder_folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder\"))\n\n  printf \"_folder_folder_files: '%s'\" \"${_folder_folder_files[@]}\"\n\n  [[ \"${#_folder_folder_files[@]}\"  == 3                      ]]\n  [[ \"${_folder_folder_files[2]}\"   == \".index\"               ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"     ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                        ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" ]]\n\n  cat \"${NB_DIR}/home/.index\"\n  cat \"${NB_DIR}/home/Example Folder/.index\"\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n  ls -la \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"           ]]\n  [[ -z \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder  ]]\n}\n\n@test \"'add folder <folder>/<folder>/<folder>' creates new folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                                  ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                    ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add folder \"Example Folder/Sample Folder/Demo Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ \"${#_folder_files[@]}\" == 4                              ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                       ]]\n  [[ \"${_folder_files[3]}\"  == \"Sample Folder\"                ]]\n\n  _folder_folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder\"))\n\n  printf \"_folder_folder_files: '%s'\" \"${_folder_folder_files[@]}\"\n\n  [[ \"${#_folder_folder_files[@]}\"  == 4                      ]]\n  [[ \"${_folder_folder_files[2]}\"   == \".index\"               ]]\n  [[ \"${_folder_folder_files[3]}\"   == \"Demo Folder\"          ]]\n\n  _folder_folder_folder_files=($(\n    LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"\n  ))\n\n  printf \"_folder_folder_folder_files: '%s'\" \"${_folder_folder_folder_files[@]}\"\n\n  [[ \"${#_folder_folder_folder_files[@]}\"  == 3               ]]\n  [[ \"${_folder_folder_folder_files[2]}\"   == \".index\"        ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"     ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                        ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"                ]]\n\n  cat \"${NB_DIR}/home/.index\"\n  cat \"${NB_DIR}/home/Example Folder/.index\"\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n  ls -la \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"          ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"  ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\"           ]]\n  [[ -z \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\")\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                      ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Demo\\ Folder ]]\n}\n\n# --type folder ###############################################################\n\n@test \"'add <folder> --type folder' creates new folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder\" --type folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"       ]]\n  [[ \"${#_folder_files[@]}\" == 3                              ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                       ]]\n  [[ \"${_folder_files[3]}\"  != \"Sample Folder\"                ]]\n\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"     ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                        ]]\n  [[ -z \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"               ]]\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"        ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:          ]]\n  [[ \"${output}\" =~ Example\\ Folder ]]\n}\n\n@test \"'add <folder>/<folder> --type folder' creates new folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ \"${#_folder_files[@]}\" == 4                              ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                       ]]\n  [[ \"${_folder_files[3]}\"  == \"Sample Folder\"                ]]\n\n  _folder_folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder\"))\n\n  [[ \"${#_folder_folder_files[@]}\"  == 3                      ]]\n  [[ \"${_folder_folder_files[2]}\"   == \".index\"               ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"     ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                        ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"                ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"          ]]\n  [[ -z \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder  ]]\n}\n\n@test \"'add <folder>/<folder>/<folder> --type folder' creates new folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                                  ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                    ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"        ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\" --type \"folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ \"${#_folder_files[@]}\" == 4                              ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                       ]]\n  [[ \"${_folder_files[3]}\"  == \"Sample Folder\"                ]]\n\n  _folder_folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder\"))\n\n  printf \"_folder_folder_files: '%s'\" \"${_folder_folder_files[@]}\"\n\n  [[ \"${#_folder_folder_files[@]}\"  == 4                      ]]\n  [[ \"${_folder_folder_files[2]}\"   == \".index\"               ]]\n  [[ \"${_folder_folder_files[3]}\"   == \"Demo Folder\"          ]]\n\n  _folder_folder_folder_files=($(\n    LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"\n  ))\n\n  printf \"_folder_folder_folder_files: '%s'\" \"${_folder_folder_folder_files[@]}\"\n\n  [[ \"${#_folder_folder_folder_files[@]}\"  == 3               ]]\n  [[ \"${_folder_folder_folder_files[2]}\"   == \".index\"        ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"     ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                        ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"                ]]\n\n  cat \"${NB_DIR}/home/.index\"\n  cat \"${NB_DIR}/home/Example Folder/.index\"\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n  ls -la \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"          ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"  ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\"           ]]\n  [[ -z \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\")\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                      ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Demo\\ Folder ]]\n}\n\n# folder/example.md ###########################################################\n\n@test \"'add <folder>/example.md' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example-filename.md\"  ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder/example-filename.md\" --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[ \"${#_files[@]}\"  == 5                                      ]]\n  [[ \"${_files[3]}\"   == \".index\"                               ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                       ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ -e \"${NB_DIR}/home/Example Folder/example-filename.md\"     ]]\n  [[ \"${#_folder_files[@]}\" == 4                                ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                         ]]\n  [[ \"${_folder_files[3]}\"   == \"example-filename.md\"           ]]\n\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                     ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"   ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                      ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"              ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/example-filename.md ]]\n}\n\n@test \"'add <folder>/<folder>/example.md' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                                    ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example-filename.md\"  ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder/Sample Folder/example-filename.md\" --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ \"${#_folder_files[@]}\" == 4                              ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                       ]]\n  [[ \"${_folder_files[3]}\"  == \"Sample Folder\"                ]]\n\n  _folder_folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder\"))\n\n  [[ \"${#_folder_folder_files[@]}\"  == 4                      ]]\n  [[ \"${_folder_folder_files[2]}\"   == \".index\"               ]]\n  [[ \"${_folder_folder_files[3]}\"   == \"example-filename.md\"  ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/example-filename.md\" ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder/Sample Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                         ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"       ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                          ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"                  ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"            ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"    ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example-filename.md  ]]\n}\n\n@test \"'add <folder>/<folder>/example.md' with no created note deletes empty ancestor folders.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                                    ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example-filename.md\"  ]]\n  }\n\n  EDITOR=mock_editor_no_op \\\n    run \"${_NB}\" add \"Example Folder/Sample Folder/example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Does not create path:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[   \"${#_files[@]}\"  == 4                                    ]]\n  [[   \"${_files[3]}\"   == \".index\"                             ]]\n  [[ ! \"${_files[*]}\"   =~ \"Example Folder\"                     ]]\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example-filename.md\" ]]\n\n  # Does not commit to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Add'\n\n  # Does not add to .indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example             ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  # Does not print output:\n\n  [[ -z \"${output}\" ]]\n}\n\n@test \"'add <folder>/<folder>/example.md --encrypt' creates new encrypted note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                                    ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example-filename.md\"  ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder/Sample Folder/example-filename.md\" \\\n    --content \"# Example Title\"                                       \\\n    --encrypt --password=password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ \"${#_folder_files[@]}\" == 4                              ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                       ]]\n  [[ \"${_folder_files[3]}\"  == \"Sample Folder\"                ]]\n\n  _folder_folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder\"))\n\n  [[ \"${#_folder_folder_files[@]}\"  == 4                          ]]\n  [[ \"${_folder_folder_files[2]}\"   == \".index\"                   ]]\n  [[ \"${_folder_folder_files[3]}\"   == \"example-filename.md.enc\"  ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/example-filename.md.enc\" ]]\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                         ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"       ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                          ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"            ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"    ]]\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example-filename.md  ]]\n}\n\n@test \"'add <folder>/<folder>/example.md' with no created note deletes only empty ancestor folders.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\" --content \"# Example Title One\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/one.md\"                                         ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/.index\"                                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/example-filename.md\"  ]]\n  }\n\n  EDITOR=mock_editor_no_op \\\n    run \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/example-filename.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Removes only empty directories:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[   \"${#_files[@]}\"  == 5                        ]]\n  [[   \"${_files[3]}\"   == \".index\"                 ]]\n  [[   \"${_files[*]}\"   =~ \"Example Folder\"         ]]\n\n  [[   -d \"${NB_DIR}/home/Example Folder\"           ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/.index\"    ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/one.md\"    ]]\n\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                                 ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"                     ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/example-filename.md\" ]]\n\n  # Does not commit to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log -n 1 | grep -v -q '\\[nb\\] Add'\n\n  # Retains .index in populated directories:\n\n  [[   -e \"${NB_DIR}/home/.index\"                                          ]]\n  [[   \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example                         ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/.index\"                           ]]\n  [[   \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ one.md           ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample           ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"             ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\" ]]\n\n  # Does not print output:\n\n  [[ -z \"${output}\" ]]\n}\n\n@test \"'add <folder>/<folder>/<folder>/example.md' creates new note without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                                                ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"                                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                                  ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/example-filename.md\"  ]]\n  }\n\n  run \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/example-filename.md\" \\\n    --content \"# Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n  \"${_NB}\" git status\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # Creates path, target file, and indexes:\n\n  _files=($(LC_ALL=C ls -a \"${NB_DIR}/home/\"))\n\n  echo \"${_files[@]}\"\n\n  [[ -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ \"${#_files[@]}\"  == 5                                    ]]\n  [[ \"${_files[3]}\"   == \".index\"                             ]]\n  [[ \"${_files[4]}\"   == \"Example Folder\"                     ]]\n\n  _folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder\"))\n\n  [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ \"${#_folder_files[@]}\" == 4                              ]]\n  [[ \"${_folder_files[2]}\"  == \".index\"                       ]]\n  [[ \"${_folder_files[3]}\"  == \"Sample Folder\"                ]]\n\n  _folder_folder_files=($(LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder\"))\n\n  [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ \"${#_folder_files[@]}\" == 4                              ]]\n  [[ \"${_folder_folder_files[2]}\"  == \".index\"                ]]\n  [[ \"${_folder_folder_files[3]}\"  == \"Demo Folder\"           ]]\n\n  _folder_folder_folder_files=($(\n    LC_ALL=C ls -a \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"\n  ))\n\n  [[ \"${#_folder_folder_folder_files[@]}\"  == 4                      ]]\n  [[ \"${_folder_folder_folder_files[2]}\"   == \".index\"               ]]\n  [[ \"${_folder_folder_folder_files[3]}\"   == \"example-filename.md\"  ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/example-filename.md\" ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"/*\n\n  # Commits to git:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\"                                                     ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\"                   ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"                                      ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\"                              ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"                        ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"                ]]\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\"            ]]\n  [[ \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\")\" == \\\n       \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\")\"    ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Demo\\ Folder/example-filename.md ]]\n}\n"
  },
  {
    "path": "test/folders-bookmark.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# no argument #################################################################\n\n@test \"'bookmark <folder>/' with no argument exits with 0, prints message, and lists.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[   -d \"${NB_DIR}/home/Example Folder\"         ]]\n    [[   -f \"${NB_DIR}/home/Example Folder/.index\"  ]]\n  }\n\n  run \"${_NB}\" bookmark Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0          ]]\n\n  # Does not create note file:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  [[ \"${#_files[@]}\" -eq 1    ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Add'\n\n  # Prints help information:\n\n  [[ \"${lines[0]}\" =~ 0\\ bookmarks. ]]\n  [[ \"${lines[2]}\" =~ 1/\\ \\<url\\>   ]]\n}\n\n# `bookmark url` ##############################################################\n\n@test \"'bookmark url <folder>/<id>' with invalid <id> prints error.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n    \"${_NB}\" bookmark Example\\ Folder/ \"${_BOOKMARK_URL}\"\n\n    _files=($(ls \"${NB_DIR}/home/Example Folder\")) && _filename=\"${_files[0]}\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"               ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/${_filename}\"  ]]\n  }\n\n  run \"${_NB}\" bookmark url Example\\ Folder/99\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 1 ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Not\\ found ]]\n}\n\n@test \"'bookmark url' prints note url.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n    \"${_NB}\" bookmark Example\\ Folder/ \"${_BOOKMARK_URL}\"\n\n    _files=($(ls \"${NB_DIR}/home/Example Folder\")) && _filename=\"${_files[0]}\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"               ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/${_filename}\"  ]]\n  }\n\n  run \"${_NB}\" bookmark url Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Prints output\n  [[ \"${output}\" == \"${_BOOKMARK_URL}\" ]]\n}\n\n@test \"'bookmark url' with multiple URLs prints first url in <>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add Example\\ Folder/example.bookmark.md \\\n      --content \"\\\nhttps://example.com\n<${_BOOKMARK_URL}>\n<https://example.com>\"\n\n    _files=($(ls \"${NB_DIR}/home/Example Folder\")) && _filename=\"${_files[0]}\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"               ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/${_filename}\"  ]]\n  }\n\n  run \"${_NB}\" bookmark url Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0 ]]\n\n  # Prints output\n  [[ \"${output}\" == \"${_BOOKMARK_URL}\" ]]\n}\n\n# <url> #######################################################################\n\n@test \"'bookmark <notebook>:<folder>/<folder> <url>' (no slash) with valid <url> argument and affirmative prompt response creates new bookmark and folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    [[ ! -d \"${NB_DIR}/Example Notebook/Example Folder\"                       ]]\n    [[ ! -f \"${NB_DIR}/Example Notebook/Example Folder/.index\"                ]]\n    [[ ! -d \"${NB_DIR}/Example Notebook/Example Folder/Sample Folder\"         ]]\n    [[ ! -f \"${NB_DIR}/Example Notebook/Example Folder/Sample Folder/.index\"  ]]\n  }\n\n  run \"${_NB}\" bookmark                               \\\n    Example\\ Notebook:Example\\ Folder/Sample\\ Folder  \\\n    \"${_BOOKMARK_URL}\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Creates folder:\n\n  [[   -d \"${NB_DIR}/Example Notebook/Example Folder\"                       ]]\n  [[   -f \"${NB_DIR}/Example Notebook/Example Folder/.index\"                ]]\n  [[ ! -d \"${NB_DIR}/Example Notebook/Example Folder/Sample Folder\"         ]]\n  [[ ! -f \"${NB_DIR}/Example Notebook/Example Folder/Sample Folder/.index\"  ]]\n\n  # Creates new file with bookmark filename in first-level folder:\n\n  _files=($(ls \"${NB_DIR}/Example Notebook/Example Folder\")) && _filename=\"${_files[0]}\"\n\n  [[        \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md    ]]\n  [[    -f  \"${NB_DIR}/Example Notebook/Example Folder/${_filename}\"  ]]\n  [[ !  -f  \"${NB_DIR}/Example Notebook/${_filename}\"                 ]]\n\n  # Creates new file with content:\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/Example Notebook/Example Folder/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/${_filename}\") \\\n    <(printf \"%s\\\\n\" \"${_bookmark_content}\")\n\n  grep -q '# Example Domain' \"${NB_DIR}/Example Notebook/Example Folder\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/.index\"    ]]\n\n  diff                                                        \\\n    <(ls  \"${NB_DIR}/Example Notebook/Example Folder/\")       \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~ \\\nCreating\\ new\\ folder:\\ .*Example\\ Notebook:Example\\ Folder/.*  ]]\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*\\[.*Example\\ Notebook:Example\\ Folder/1.*\\].*\\ 🔖\\    ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder/[0-9]+.bookmark.md.*\\ \\\"Example\\ Domain\\\" ]]\n}\n\n@test \"'bookmark <folder>/<folder> <url>' (no slash) with valid <url> argument and affirmative prompt response creates new bookmark and folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -d \"${NB_DIR}/home/Example Folder\"                       ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/.index\"                ]]\n    [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"  ]]\n  }\n\n  run \"${_NB}\" bookmark Example\\ Folder/Sample\\ Folder \"${_BOOKMARK_URL}\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Creates folder:\n\n  [[   -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[   -f \"${NB_DIR}/home/Example Folder/.index\"                ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ ! -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"  ]]\n\n  # Creates new file with bookmark filename in first-level folder:\n\n  _files=($(ls \"${NB_DIR}/home/Example Folder\")) && _filename=\"${_files[0]}\"\n\n  [[        \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md    ]]\n  [[    -f  \"${NB_DIR}/home/Example Folder/${_filename}\"  ]]\n  [[ !  -f  \"${NB_DIR}/home/${_filename}\"                 ]]\n\n  # Creates new file with content:\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/Example Folder/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example Folder/${_filename}\") \\\n    <(printf \"%s\\\\n\" \"${_bookmark_content}\")\n\n  grep -q '# Example Domain' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"    ]]\n\n  diff                                            \\\n    <(ls  \"${NB_DIR}/home/Example Folder/\")       \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~ \\\nCreating\\ new\\ folder:\\ .*Example\\ Folder/.*      ]]\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*\\[.*Example\\ Folder/1.*\\].*\\ 🔖\\        ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*Example\\ Folder/[0-9]+.bookmark.md.*\\ \\\"Example\\ Domain\\\"   ]]\n}\n\n@test \"'bookmark <folder>/<folder> <url>' (no slash) with valid <url> argument and negative prompt response does not create new bookmark and folder.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -d \"${NB_DIR}/home/Example Folder\"                       ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/.index\"                ]]\n    [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"  ]]\n  }\n\n  run \"${_NB}\" bookmark Example\\ Folder/Sample\\ Folder \"${_BOOKMARK_URL}\" <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Does not create folder:\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"                       ]]\n  [[ ! -f \"${NB_DIR}/home/Example Folder/.index\"                ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n  [[ ! -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"  ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Add'\n\n  # Does not add to index:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"    ]]\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Creating\\ new\\ folder:\\ .*Example\\ Folder ]]\n  [[ \"${lines[1]}\" =~ Exiting...                                ]]\n}\n\n@test \"'bookmark <folder> <url>' (no slash) with valid <url> argument and matching folder name creates new bookmark in folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    [[  -d \"${NB_DIR}/home/Example Folder\"        ]]\n    [[  -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" bookmark Example\\ Folder \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Creates new file with bookmark filename:\n\n  _files=($(ls \"${NB_DIR}/home/Example Folder\")) && _filename=\"${_files[0]}\"\n\n  [[        \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md    ]]\n  [[    -f  \"${NB_DIR}/home/Example Folder/${_filename}\"  ]]\n\n  # Creates new file with content:\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/Example Folder/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example Folder/${_filename}\") \\\n    <(printf \"%s\\\\n\" \"${_bookmark_content}\")\n\n  grep -q '# Example Domain' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"  ]]\n\n  diff                                          \\\n    <(ls  \"${NB_DIR}/home/Example Folder/\")     \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                    ]]\n  [[ \"${output}\" =~ [0-9]+                                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/[A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark <folder> <url>' (no slash) with valid <url> argument and no matching folder name creates new bookmark at root level without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -d \"${NB_DIR}/home/Example Folder\"        ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" bookmark Example\\ Folder \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Does not create folder:\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"        ]]\n  [[ ! -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  # Creates new file with bookmark filename:\n\n  _files=($(ls \"${NB_DIR}/home\")) && _filename=\"${_files[0]}\"\n\n  [[        \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md    ]]\n  [[    -f  \"${NB_DIR}/home/${_filename}\"                 ]]\n\n  # Creates new file with content:\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/${_filename}\") \\\n    <(printf \"%s\\\\n\" \"${_bookmark_content}\")\n\n  grep -q '# Example Domain' \"${NB_DIR}/home\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                             \\\n    <(ls  \"${NB_DIR}/home/\")       \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark <folder>/ <url>' with valid <url> argument and affirmative prompt response creates new bookmark and folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -d \"${NB_DIR}/home/Example Folder\"        ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" bookmark Example\\ Folder/ \"${_BOOKMARK_URL}\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Creates folder:\n\n  [[   -d \"${NB_DIR}/home/Example Folder\"        ]]\n  [[   -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  # Creates new file with bookmark filename:\n\n  _files=($(ls \"${NB_DIR}/home/Example Folder\")) && _filename=\"${_files[0]}\"\n\n  [[        \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md    ]]\n  [[    -f  \"${NB_DIR}/home/Example Folder/${_filename}\"  ]]\n  [[ !  -f  \"${NB_DIR}/home/${_filename}\"                 ]]\n\n  # Creates new file with content:\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/Example Folder/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example Folder/${_filename}\") \\\n    <(printf \"%s\\\\n\" \"${_bookmark_content}\")\n\n  grep -q '# Example Domain' \"${NB_DIR}/home/Example Folder\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"    ]]\n\n  diff                                            \\\n    <(ls  \"${NB_DIR}/home/Example Folder/\")       \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                    ]]\n  [[ \"${output}\" =~ [0-9]+                                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/[A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'bookmark <folder>/ <url>' with valid <url> argument and negative prompt response does not create new bookmark and folder.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -d \"${NB_DIR}/home/Example Folder\"        ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" bookmark Example\\ Folder/ \"${_BOOKMARK_URL}\" <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Does not create folder:\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"        ]]\n  [[ ! -f \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Creating\\ new\\ folder:\\ .*Example\\ Folder ]]\n  [[ \"${lines[1]}\" =~ Exiting...                                ]]\n}\n\n@test \"'bookmark <folder>/<folder>/ <url>' with valid <url> argument and affirmative prompt response creates new bookmark and folder without errors.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -d \"${NB_DIR}/home/Example Folder\"                       ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/.index\"                ]]\n    [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"  ]]\n  }\n\n  run \"${_NB}\" bookmark Example\\ Folder/Sample\\ Folder/ \"${_BOOKMARK_URL}\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Creates folders:\n\n  [[   -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[   -f \"${NB_DIR}/home/Example Folder/.index\"                  ]]\n  [[   -d \"${NB_DIR}/home/Example Folder/Sample Folder\"           ]]\n  [[   -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"    ]]\n\n  # Creates new file with bookmark filename:\n\n  _files=($(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")) &&\n    _filename=\"${_files[0]}\"\n\n  [[        \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md                  ]]\n  [[    -f  \"${NB_DIR}/home/Example Folder/Sample Folder/${_filename}\"  ]]\n  [[ !  -f  \"${NB_DIR}/home/Example Folder/${_filename}\"                ]]\n  [[ !  -f  \"${NB_DIR}/home/${_filename}\"                               ]]\n\n  # Creates new file with content:\n\n  [[ \"${#_files[@]}\" -eq 1  ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/${_filename}\") \\\n    <(printf \"%s\\\\n\" \"${_bookmark_content}\")\n\n  grep -q '# Example Domain' \"${NB_DIR}/home/Example Folder/Sample Folder\"/*\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"    ]]\n\n  diff                                                          \\\n    <(ls  \"${NB_DIR}/home/Example Folder/Sample Folder/\")       \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Added:                                                  ]]\n  [[ \"${output}\" =~ [0-9]+                                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/[A-Za-z0-9]+.bookmark.md ]]\n}\n\n@test \"'bookmark <folder>/<folder>/ <url>' with valid <url> argument and negative prompt response does not create new bookmark and folder.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -d \"${NB_DIR}/home/Example Folder\"                       ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/.index\"                ]]\n    [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"         ]]\n    [[ ! -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"  ]]\n  }\n\n  run \"${_NB}\" bookmark Example\\ Folder/Sample\\ Folder/ \"${_BOOKMARK_URL}\" <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0        ]]\n\n  # Does not create folders:\n\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[ ! -f \"${NB_DIR}/home/Example Folder/.index\"                  ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder/Sample Folder\"           ]]\n  [[ ! -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"    ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Creating\\ new\\ folder:\\ .*Example\\ Folder/Sample\\ Folder  ]]\n  [[ \"${lines[1]}\" =~ Exiting...                                                ]]\n}\n\n# <list option...> arguments ##################################################\n\n# TODO\n# @test \"'bookmark <folder>/ <query>' exits with 0 and displays a list of bookmarks with titles.\" {\n#   {\n#     \"${_NB}\" init\n#     cat <<HEREDOC | \"${_NB}\" add \"Example Folder/first.md\"\n# # one\n# line two\n# line three\n# line four\n# HEREDOC\n#     \"${_NB}\" add \"Example Folder/second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n#     cat <<HEREDOC | \"${_NB}\" add \"Example Folder/third.md\"\n# line one\n# line two\n# line three\n# line four\n# line example\n# HEREDOC\n#     \"${_NB}\" add \"Example Folder/fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\" \\\n#       --title \"Example Bookmark Title\"\n#     cat <<HEREDOC | \"${_NB}\" add \"Example Folder/fifth.md\"\n# # three\n# line two\n# line three\n# line four\n# HEREDOC\n#     _files=($(ls \"${NB_DIR}/home/\"))\n#   }\n\n#   run \"${_NB}\" bookmark Example\\ Folder/ example\n\n#   printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n#   printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n#   printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n#   [[ ${status} -eq 0                            ]]\n#   [[ \"${lines[0]}\" =~ Example\\ Bookmark\\ Title  ]] && [[ \"${lines[0]}\" =~ 4 ]]\n#   [[ \"${#lines[@]}\" == \"1\"                      ]]\n# }\n"
  },
  {
    "path": "test/folders-count.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# default #####################################################################\n\n@test \"'count' with no argument exits with 0 and prints count in root folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 2 ]]\n}\n\n# notebooks ###################################################################\n\n@test \"'count notebook:' exits with 0 and prints count in notebook root folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" count home:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 2 ]]\n}\n\n@test \"'count notebook:<folder>' (no slash) exits with 0 and prints count in <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" count home:Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 3 ]]\n}\n\n@test \"'count notebook:<folder>/' (slash) exits with 0 and prints count in <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" count home:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 3 ]]\n}\n\n# error handling ##############################################################\n\n@test \"'count <not-valid>' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                       ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found:.*not-valid  ]]\n}\n\n@test \"'count <not-valid> --skip-unmatched-selector' exits with 0 and prints root-level count.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count not-valid --skip-unmatched-selector\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  =~  2 ]]\n}\n\n# file paths ##################################################################\n\n@test \"'count <file>' exits with 0 and prints count of <file> (1).\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count one.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 1 ]]\n}\n\n@test \"'count <folder>/<file>' exits with 0 and prints count of <folder>/<file> (1).\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count Example\\ Folder/two.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 1 ]]\n}\n\n# <folder> paths ##############################################################\n\n@test \"'count <folder>' (no slash) exits with 0 and prints count in <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 3 ]]\n}\n\n@test \"'count <folder>/' (slash) exits with 0 and prints count in <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 3 ]]\n}\n\n@test \"'count <folder>/<folder>' (no slash) exits with 0 and prints count in <folder>/<folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count Example\\ Folder/Sample\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 4 ]]\n}\n\n@test \"'count <folder>/<folder>/' (slash) exits with 0 and prints count in <folder>/<folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 4 ]]\n}\n\n# <id> paths ##################################################################\n\n@test \"'count <folder-id>' (no slash) exits with 0 and prints count in <folder-id>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 3 ]]\n}\n\n@test \"'count <folder-id>/' (slash) exits with 0 and prints count in <folder-id>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count 2/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 3 ]]\n}\n\n@test \"'count <folder>/<folder-id>' (no slash) exits with 0 and prints count in <folder>/<folder-id>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count Example\\ Folder/3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 4 ]]\n}\n\n@test \"'count <folder>/<folder-id>/' (slash) exits with 0 and prints count in <folder>/<folder-id>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"\n    \"${_NB}\" add \"Example Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.md\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\"\n  }\n\n  run \"${_NB}\" count Example\\ Folder/3/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[0]}\"  -eq 4 ]]\n}\n"
  },
  {
    "path": "test/folders-delete.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# error handling ##############################################################\n\n@test \"'delete <id>' with filename matching notebook name deletes properly.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add --filename \"one:\" --content \"Example content one.\"\n    \"${_NB}\" add --filename \"two:\" --content \"Example content two.\"\n\n    \"${_NB}\" notebooks add \"one\"\n\n    [[    -d \"${NB_DIR}/one\"       ]]\n    [[    -f \"${NB_DIR}/home/one:\" ]]\n    [[    -f \"${NB_DIR}/home/two:\" ]]\n  }\n\n  run \"${_NB}\" delete 1 --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[    -d \"${NB_DIR}/one\"       ]]\n  [[ !  -f \"${NB_DIR}/home/one:\" ]]\n  [[    -f \"${NB_DIR}/home/two:\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: one:'\n\n  # Prints output:\n\n  [[ \"${output}\"    =~  Deleted:.*one:  ]]\n  [[ \"${#lines[@]}\" -eq 1               ]]\n}\n\n@test \"'delete folder/<filename>' with invalid filename returns with error and message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n\n  }\n\n  run \"${_NB}\" delete \"Example Folder/not-valid\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1 ]]\n\n  # Does not delete file:\n\n  [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q -v '\\[nb\\] Delete: .*Example Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Not\\ found:               ]]\n  [[ \"${output}\" =~ Example\\ Folder/not-valid ]]\n  [[ \"${#lines[@]}\" -eq 1                     ]]\n}\n\n@test \"'delete notebook:folder/<filename>' with invalid filename returns with error and message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n\n  }\n\n  run \"${_NB}\" delete \"home:Example Folder/not-valid\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1 ]]\n\n  # Does not delete file:\n\n  [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q -v '\\[nb\\] Delete: .*Example Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Not\\ found:               ]]\n  [[ \"${output}\" =~ Example\\ Folder/not-valid ]]\n  [[ \"${#lines[@]}\" -eq 1                     ]]\n}\n\n# <filename> ##################################################################\n\n@test \"'delete folder/<filename>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n\n  }\n\n  run \"${_NB}\" delete \"Example Folder/Example File.bookmark.md\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                           ]]\n  [[ \"${output}\" =~ 🔖                                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md   ]]\n}\n\n@test \"'delete folder/folder/<filename>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  }\n\n  run \"${_NB}\" delete \"Example Folder/Sample Folder/Example File.bookmark.md\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Sample Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'delete notebook:folder/<filename>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"home:Example Folder/Example File.bookmark.md\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                        ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                              ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'delete notebook:folder/folder/<filename>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"home:Example Folder/Sample Folder/Example File.bookmark.md\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Sample Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                         ]]\n  [[ \"${output}\" =~ 🔖                                                            ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md ]]\n}\n\n# <id> ########################################################################\n\n@test \"'delete folder/<id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"Example Folder/1\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                           ]]\n  [[ \"${output}\" =~ 🔖                                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md   ]]\n}\n\n@test \"'delete folder/folder/<id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"Example Folder/Sample Folder/1\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Sample Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'delete notebook:folder/<id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" delete \"home:Example Folder/1\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                        ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                              ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'delete notebook:folder/folder/<id>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" delete \"home:Example Folder/Sample Folder/1\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Sample Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                         ]]\n  [[ \"${output}\" =~ 🔖                                                            ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md ]]\n}\n\n# <title> #####################################################################\n\n@test \"'delete folder/<title>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"Example Folder/Example Title\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes  file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                           ]]\n  [[ \"${output}\" =~ 🔖                                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md   ]]\n}\n\n@test \"'delete folder/folder/<title>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"Example Folder/Sample Folder/Example Title\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Sample Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'delete notebook:folder/<title>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"home:Example Folder/Example Title\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                        ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                              ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'delete notebook:folder/folder/<title>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"home:Example Folder/Sample Folder/Example Title\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Sample Folder/Example File.bookmark.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                         ]]\n  [[ \"${output}\" =~ 🔖                                                            ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md ]]\n}\n"
  },
  {
    "path": "test/folders-edit.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# <filename> ##################################################################\n\n@test \"'edit folder/<filename>' with encrypted file edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"                    \\\n      --encrypt                                             \\\n      --password password\n\n    declare _relative_path=\"Example Folder/Example File.bookmark.md.enc\"\n\n    declare _original_hash=\n    _original_hash=\"$(\n      _get_hash \"${NB_DIR}/home/${_relative_path}\"\n    )\"\n  }\n\n  run \"${_NB}\" edit \"${_relative_path}\" --password password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(_get_hash \"${NB_DIR}/home/${_relative_path}\")\" != \"${_original_hash}\" ]]\n\n\n  [[  \"$(\n        \"${_NB}\" show \"${_relative_path}\" \\\n          --print                         \\\n          --no-color                      \\\n          --password password\n      )\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                      ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                             ]]\n  [[ \"${output}\" =~ 🔖\\ 🔒                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md.enc ]]\n}\n\n# error handling ##############################################################\n\n\n@test \"'edit folder/<filename>' with invalid filename returns with error and message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" edit \"Example Folder/not-valid\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1 ]]\n\n  # Does not update file:\n\n  [[ ! \"$(cat \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Not\\ found:               ]]\n  [[ \"${output}\" =~ Example\\ Folder/not-valid ]]\n}\n\n# <filename> ##################################################################\n\n@test \"'edit folder/<filename>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" edit \"Example Folder/Example File.bookmark.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                           ]]\n  [[ \"${output}\" =~ 🔖                                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md   ]]\n}\n\n@test \"'edit folder/folder/<filename>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" edit \"Example Folder/Sample Folder/Example File.bookmark.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'edit notebook:folder/<filename>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" edit \"home:Example Folder/Example File.bookmark.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                        ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                              ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'edit notebook:folder/folder/<filename>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" edit \"home:Example Folder/Sample Folder/Example File.bookmark.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                         ]]\n  [[ \"${output}\" =~ 🔖                                                            ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md ]]\n}\n\n# <id> ########################################################################\n\n@test \"'edit folder/<id>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" edit \"Example Folder/1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                           ]]\n  [[ \"${output}\" =~ 🔖                                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md   ]]\n}\n\n@test \"'edit folder/folder/<id>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" edit \"Example Folder/Sample Folder/1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'edit notebook:folder/<id>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" edit \"home:Example Folder/1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                        ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                              ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'edit notebook:folder/folder/<id>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" edit \"home:Example Folder/Sample Folder/1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                         ]]\n  [[ \"${output}\" =~ 🔖                                                            ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md ]]\n}\n\n# <title> #####################################################################\n\n@test \"'edit folder/<title>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" edit \"Example Folder/Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                           ]]\n  [[ \"${output}\" =~ 🔖                                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md   ]]\n}\n\n@test \"'edit folder/folder/<title>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" edit \"Example Folder/Sample Folder/Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'edit notebook:folder/<title>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" edit \"home:Example Folder/Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                        ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                              ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n@test \"'edit notebook:folder/folder/<title>' edits properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" edit \"home:Example Folder/Sample Folder/Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Updates file:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\")\" =~ mock_editor ]]\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Edit'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Updated:                                                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                         ]]\n  [[ \"${output}\" =~ 🔖                                                            ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md ]]\n}\n"
  },
  {
    "path": "test/folders-export.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# error handling ##############################################################\n\n@test \"'export folder/<filename>' with invalid filename returns with error and message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://2.example.test>\"\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"  ]]\n  }\n\n  run \"${_NB}\" export \"Example Folder/not-valid\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1 ]]\n\n  # Does not export file:\n\n  [[ ! -e \"${_TMP_DIR}/example.md\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Not\\ found:               ]]\n  [[ \"${output}\" =~ Example\\ Folder/not-valid ]]\n}\n\n# <filename> ##################################################################\n\n@test \"'export folder/<filename>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://2.example.test>\"\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"  ]]\n  }\n\n  run \"${_NB}\" export \"Example Folder/Example File.bookmark.md\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" == \"<https://2.example.test>\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                         ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                                 ]]\n  [[ \"${output}\" =~ 🔖                                                ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md         ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                            ]]\n}\n\n@test \"'export folder/folder/<filename>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://2.example.test>\"\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"  ]]\n  }\n\n  run \"${_NB}\" export \"Example Folder/Sample Folder/Example File.bookmark.md\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" == \"<https://2.example.test>\"  ]]\n\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                                 ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                                    ]]\n}\n\n@test \"'export notebook:folder/<filename>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"            ]]\n  }\n\n  run \"${_NB}\" export \"home:Example Folder/Example File.bookmark.md\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" == \"<https://2.example.test>\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                       ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                              ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.bookmark.md  ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                          ]]\n}\n\n@test \"'export notebook:folder/folder/<filename>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"            ]]\n  }\n\n  run \"${_NB}\" export                                             \\\n    \"home:Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n    \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" == \"<https://2.example.test>\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                                     ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                         ]]\n  [[ \"${output}\" =~ 🔖                                                            ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                                        ]]\n}\n\n# <id> ########################################################################\n\n@test \"'export folder/<id>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://2.example.test>\"\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"  ]]\n\n  }\n\n  run \"${_NB}\" export \"Example Folder/1\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" == \"<https://2.example.test>\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                         ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                                 ]]\n  [[ \"${output}\" =~ 🔖                                                ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md         ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                            ]]\n}\n\n@test \"'export folder/folder/<id>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://2.example.test>\"\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"  ]]\n  }\n\n  run \"${_NB}\" export \"Example Folder/Sample Folder/1\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" == \"<https://2.example.test>\"  ]]\n\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                                 ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                                    ]]\n}\n\n@test \"'export notebook:folder/<id>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"            ]]\n  }\n\n  run \"${_NB}\" export \"home:Example Folder/1\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" == \"<https://2.example.test>\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                       ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                              ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.bookmark.md  ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                          ]]\n}\n\n@test \"'export notebook:folder/folder/<id>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"            ]]\n  }\n\n  run \"${_NB}\" export \"home:Example Folder/Sample Folder/1\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" == \"<https://2.example.test>\"  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                                     ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                         ]]\n  [[ \"${output}\" =~ 🔖                                                            ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                                        ]]\n}\n\n# <title> #####################################################################\n\n@test \"'export folder/<title>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://2.example.test>\"\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"  ]]\n  }\n\n  run \"${_NB}\" export \"Example Folder/Example Title\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" =~ Example\\ Title              ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" =~ \\<https://2.example.test\\>  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                         ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                                 ]]\n  [[ \"${output}\" =~ 🔖                                                ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.bookmark.md         ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                            ]]\n}\n\n@test \"'export folder/folder/<title>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"  ]]\n  }\n\n  run \"${_NB}\" export \"Example Folder/Sample Folder/Example Title\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" =~ Example\\ Title              ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" =~ \\<https://2.example.test\\>  ]]\n\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                                 ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                                        ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                                    ]]\n}\n\n@test \"'export notebook:folder/<title>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"            ]]\n  }\n\n  run \"${_NB}\" export \"home:Example Folder/Example Title\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" =~ Example\\ Title              ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" =~ \\<https://2.example.test\\>  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                       ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                          ]]\n  [[ \"${output}\" =~ 🔖                                              ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.bookmark.md  ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                          ]]\n}\n\n@test \"'export notebook:folder/folder/<title>' exports properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[ ! -e \"${_TMP_DIR}/example.md\"            ]]\n  }\n\n  run \"${_NB}\" export \"home:Example Folder/Sample Folder/Example Title\" \"${_TMP_DIR}/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Exports file:\n\n  [[ -e \"${_TMP_DIR}/example.md\"                                      ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" =~ Example\\ Title              ]]\n  [[ \"$(cat \"${_TMP_DIR}/example.md\")\" =~ \\<https://2.example.test\\>  ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Exported:                                                     ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                         ]]\n  [[ \"${output}\" =~ 🔖                                                            ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example.md                                        ]]\n}\n"
  },
  {
    "path": "test/folders-history.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'history <folder>/' (slash) exits with status 0 and prints folder history.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/one.md\" --title \"first nested\"\n    \"${_NB}\" add    \"Example Folder/two.md\" --title \"second nested\"\n    \"${_NB}\" edit   \"Example Folder/one.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"Example Folder/two.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/Sample Folder/one.md\" --title \"first deeply nested\"\n  }\n\n  run \"${_NB}\" history Example\\ Folder/ --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                    ]]\n\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md                                ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md                              ]]\n\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/Sample\\ Folder/one.md  ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/one.md                 ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/two.md                 ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Edit:\\ Example\\ Folder/one.md                ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Delete:\\ Example\\ Folder/two.md              ]]\n}\n\n@test \"'history <folder>' (no slash) exits with status 0 and prints folder history.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/one.md\" --title \"first nested\"\n    \"${_NB}\" add    \"Example Folder/two.md\" --title \"second nested\"\n    \"${_NB}\" edit   \"Example Folder/one.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"Example Folder/two.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/Sample Folder/one.md\" --title \"first deeply nested\"\n  }\n\n  run \"${_NB}\" history Example\\ Folder --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                    ]]\n\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md                                ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md                              ]]\n\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/Sample\\ Folder/one.md  ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/one.md                 ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/two.md                 ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Edit:\\ Example\\ Folder/one.md                ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Delete:\\ Example\\ Folder/two.md              ]]\n}\n\n@test \"'history <folder>/<filename>' exits with status 0 and prints file history.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/one.md\" --title \"first nested\"\n    \"${_NB}\" add    \"Example Folder/two.md\" --title \"second nested\"\n    \"${_NB}\" edit   \"Example Folder/one.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"Example Folder/two.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/Sample Folder/one.md\" --title \"first deeply nested\"\n  }\n\n  run \"${_NB}\" history Example\\ Folder/one.md --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                    ]]\n\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md                                ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md                              ]]\n\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/Sample\\ Folder/one.md  ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/one.md                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/two.md                 ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Edit:\\ Example\\ Folder/one.md                ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ Example\\ Folder/two.md              ]]\n}\n\n@test \"'history <folder>/<id>' exits with status 0 and prints file history.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/one.md\" --title \"first nested\"\n    \"${_NB}\" add    \"Example Folder/two.md\" --title \"second nested\"\n    \"${_NB}\" edit   \"Example Folder/one.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"Example Folder/two.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/Sample Folder/one.md\" --title \"first deeply nested\"\n  }\n\n  run \"${_NB}\" history Example\\ Folder/1 --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                    ]]\n\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md                                ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md                              ]]\n\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/Sample\\ Folder/one.md  ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/one.md                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/two.md                 ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Edit:\\ Example\\ Folder/one.md                ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ Example\\ Folder/two.md              ]]\n}\n\n@test \"'history <folder>/<title>' exits with status 0 and prints file history.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/one.md\" --title \"first nested\"\n    \"${_NB}\" add    \"Example Folder/two.md\" --title \"second nested\"\n    \"${_NB}\" edit   \"Example Folder/one.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"Example Folder/two.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/Sample Folder/one.md\" --title \"first deeply nested\"\n  }\n\n  run \"${_NB}\" history Example\\ Folder/first\\ nested --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                                    ]]\n\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md                                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md                                ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md                              ]]\n\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/Sample\\ Folder/one.md  ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/one.md                 ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ Example\\ Folder/two.md                 ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Edit:\\ Example\\ Folder/one.md                ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ Example\\ Folder/two.md              ]]\n}\n\n@test \"'history <folder>/<not-valid>' exits with status 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/one.md\" --title \"first nested\"\n    \"${_NB}\" add    \"Example Folder/two.md\" --title \"second nested\"\n    \"${_NB}\" edit   \"Example Folder/one.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"Example Folder/two.md\" --force\n\n    \"${_NB}\" add    \"Example Folder/Sample Folder/one.md\" --title \"first deeply nested\"\n  }\n\n  run \"${_NB}\" history Example\\ Folder/not-valid --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                                                 ]]\n  [[    \"${#lines[@]}\"  -eq 1                                                 ]]\n\n  [[    \"${lines[0]}\"   =~  Not\\ found:\\ .*Example\\ Folder/not-valid          ]]\n}\n"
  },
  {
    "path": "test/folders-import-download.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# import download | <url> <folder>/ ###########################################\n\n@test \"'import <url> <folder>' (no slash) with existing folder imports file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                 ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  }\n\n  run \"${_NB}\" import                                 \\\n    \"file://${NB_TEST_BASE_PATH}/fixtures/example.md\" \\\n    \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folder:\n\n  [[ ! -e \"${NB_DIR}/home/sample.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n  [[ \"${output}\" =~ Imported                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'import <url> <folder>/<folder>' (no slash) with existing folder imports file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n  }\n\n  run \"${_NB}\" import                                 \\\n    \"file://${NB_TEST_BASE_PATH}/fixtures/example.md\" \\\n    \"Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folders:\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/home/Example Folder/Sample Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example.md ]]\n}\n\n@test \"'import <url> <folder>/' (slash) imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                 ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  }\n\n  run \"${_NB}\" import                                 \\\n    \"file://${NB_TEST_BASE_PATH}/fixtures/example.md\" \\\n    \"Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folder:\n\n  [[ ! -e \"${NB_DIR}/home/sample.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'import <url> <folder>/<folder>/' (slash) imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n  }\n\n  run \"${_NB}\" import                                 \\\n    \"file://${NB_TEST_BASE_PATH}/fixtures/example.md\" \\\n    \"Example Folder/Sample Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folders:\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/home/Example Folder/Sample Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example.md ]]\n}\n\n# import <url> <folder>/<filename> ###########################################\n\n@test \"'import' with valid <url> and <filename> imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\" ]]\n  }\n\n  run \"${_NB}\" import                                 \\\n    \"file://${NB_TEST_BASE_PATH}/fixtures/example.md\" \\\n    \"sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file:\n\n  [[   -e \"${NB_DIR}/home/sample.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/sample.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/sample.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported  ]]\n  [[ \"${output}\" =~ sample.md ]]\n}\n\n@test \"'import' with valid <url> and <folder>/<filename> imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"                ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/sample.md\" ]]\n  }\n\n  run \"${_NB}\" import                                 \\\n    \"file://${NB_TEST_BASE_PATH}/fixtures/example.md\" \\\n    \"Example Folder/sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folder:\n\n  [[ ! -e \"${NB_DIR}/home/sample.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/sample.md\"   ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/sample.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/sample.md ]]\n}\n\n@test \"'import' with valid <url> and <folder>/<folder>/<filename> imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"                              ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/sample.md\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/sample.md\" ]]\n  }\n\n  run \"${_NB}\" import                                 \\\n    \"file://${NB_TEST_BASE_PATH}/fixtures/example.md\" \\\n    \"Example Folder/Sample Folder/sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folders:\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"                              ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/sample.md\"               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"           ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/sample.md\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/sample.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/home/Example Folder/Sample Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/sample.md  ]]\n}\n"
  },
  {
    "path": "test/folders-import-move.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# import move <path> <folder>/ ################################################\n\n@test \"'import move <path> <folder>' (no slash) with existing folder imports file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                 ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}/fixtures\"\n\n    [[   -f \"${_TMP_DIR}/fixtures/example.md\"           ]]\n  }\n\n  run \"${_NB}\" import move            \\\n    \"${_TMP_DIR}/fixtures/example.md\" \\\n    \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folder:\n\n  [[ ! -e \"${NB_DIR}/home/sample.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Moves from original location:\n\n  [[ ! -f \"${_TMP_DIR}/fixtures/example.md\"           ]]\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n  [[ \"${output}\" =~ Imported                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'import move <path> <folder>/<folder>' (no slash) with existing folder imports file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}/fixtures\"\n\n    [[   -f \"${_TMP_DIR}/fixtures/example.md\" ]]\n}\n\n  run \"${_NB}\" import move                      \\\n    \"${_TMP_DIR}/fixtures/example.md\"  \\\n    \"Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folders:\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\")\n\n  # Moves from original location:\n\n  [[ ! -f \"${_TMP_DIR}/fixtures/example.md\" ]]\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/home/Example Folder/Sample Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example.md ]]\n}\n\n@test \"'import move <path> <folder>/' (slash) imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                 ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}/fixtures\"\n\n    [[   -f \"${_TMP_DIR}/fixtures/example.md\"           ]]\n  }\n\n  run \"${_NB}\" import move            \\\n    \"${_TMP_DIR}/fixtures/example.md\" \\\n    \"Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folder:\n\n  [[ ! -e \"${NB_DIR}/home/sample.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Moves from original location:\n\n  [[ ! -f \"${_TMP_DIR}/fixtures/example.md\"           ]]\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'import move <path> <folder>/<folder>/' (slash) imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}/fixtures\"\n\n    [[   -f \"${_TMP_DIR}/fixtures/example.md\" ]]\n  }\n\n  run \"${_NB}\" import move            \\\n    \"${_TMP_DIR}/fixtures/example.md\" \\\n    \"Example Folder/Sample Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folders:\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\")\n\n  # Moves from original location:\n\n  [[ ! -f \"${_TMP_DIR}/fixtures/example.md\" ]]\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/home/Example Folder/Sample Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example.md ]]\n}\n\n# # import move <path> <folder>/<filename> ####################################\n\n@test \"'import move' with valid <path> and <filename> imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"        ]]\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}/fixtures\"\n\n    [[   -f \"${_TMP_DIR}/fixtures/example.md\" ]]\n  }\n\n  run \"${_NB}\" import move            \\\n    \"${_TMP_DIR}/fixtures/example.md\" \\\n    \"sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file:\n\n  [[   -e \"${NB_DIR}/home/sample.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/sample.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/sample.md\")\n\n  # Moves from original location:\n\n  [[ ! -f \"${_TMP_DIR}/fixtures/example.md\" ]]\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported  ]]\n  [[ \"${output}\" =~ sample.md ]]\n}\n\n@test \"'import move' with valid <path> and <folder>/<filename> imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"                ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/sample.md\" ]]\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}/fixtures\"\n\n    [[   -f \"${_TMP_DIR}/fixtures/example.md\"         ]]\n  }\n\n  run \"${_NB}\" import move            \\\n    \"${_TMP_DIR}/fixtures/example.md\" \\\n    \"Example Folder/sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folder:\n\n  [[ ! -e \"${NB_DIR}/home/sample.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/sample.md\"   ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/sample.md\")\n\n  # Moves from original location:\n\n  [[ ! -f \"${_TMP_DIR}/fixtures/example.md\"           ]]\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/sample.md ]]\n}\n\n@test \"'import move' with valid <path> and <folder>/<folder>/<filename> imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"                              ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/sample.md\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/sample.md\" ]]\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}/fixtures\"\n\n    [[   -f \"${_TMP_DIR}/fixtures/example.md\" ]]\n  }\n\n  run \"${_NB}\" import move            \\\n    \"${_TMP_DIR}/fixtures/example.md\" \\\n    \"Example Folder/Sample Folder/sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folders:\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"                              ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/sample.md\"               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"           ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/sample.md\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/sample.md\")\n\n  # Moves from original location:\n\n  [[ ! -f \"${_TMP_DIR}/fixtures/example.md\" ]]\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/home/Example Folder/Sample Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/sample.md  ]]\n}\n"
  },
  {
    "path": "test/folders-import.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# import <path> <folder>/ #####################################################\n\n@test \"'import <path> <folder>' (no slash) with existing folder imports file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                 ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  }\n\n  run \"${_NB}\" import                           \\\n    \"${NB_TEST_BASE_PATH}/fixtures/example.md\"  \\\n    \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folder:\n\n  [[ ! -e \"${NB_DIR}/home/sample.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n  [[ \"${output}\" =~ Imported                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'import <path> <folder>/<folder>' (no slash) with existing folder imports file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n  }\n\n  run \"${_NB}\" import                           \\\n    \"${NB_TEST_BASE_PATH}/fixtures/example.md\"  \\\n    \"Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folders:\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/home/Example Folder/Sample Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example.md ]]\n}\n\n@test \"'import <path> <folder>/' (slash) imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                 ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  }\n\n  run \"${_NB}\" import                           \\\n    \"${NB_TEST_BASE_PATH}/fixtures/example.md\"  \\\n    \"Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folder:\n\n  [[ ! -e \"${NB_DIR}/home/sample.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'import <path> <folder>/<folder>/' (slash) imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n  }\n\n  run \"${_NB}\" import                           \\\n    \"${NB_TEST_BASE_PATH}/fixtures/example.md\"  \\\n    \"Example Folder/Sample Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folders:\n\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"             ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/home/Example Folder/Sample Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example.md ]]\n}\n\n# import <path> <folder>/<filename> ###########################################\n\n@test \"'import' with valid <path> and <filename> imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\" ]]\n  }\n\n  run \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/example.md\" \"sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file:\n\n  [[   -e \"${NB_DIR}/home/sample.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/sample.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/sample.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported  ]]\n  [[ \"${output}\" =~ sample.md ]]\n}\n\n@test \"'import' with valid <path> and <folder>/<filename> imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"                ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/sample.md\" ]]\n  }\n\n  run \"${_NB}\" import                           \\\n    \"${NB_TEST_BASE_PATH}/fixtures/example.md\"  \\\n    \"Example Folder/sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folder:\n\n  [[ ! -e \"${NB_DIR}/home/sample.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder\"             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/sample.md\"   ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.pdf\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/sample.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/sample.md ]]\n}\n\n@test \"'import' with valid <path> and <folder>/<folder>/<filename> imports file.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"                              ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/sample.md\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"           ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/sample.md\" ]]\n  }\n\n  run \"${_NB}\" import                           \\\n    \"${NB_TEST_BASE_PATH}/fixtures/example.md\"  \\\n    \"Example Folder/Sample Folder/sample.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Creates file and folders:\n\n    [[ ! -e \"${NB_DIR}/home/sample.md\"                              ]]\n    [[   -e \"${NB_DIR}/home/Example Folder\"                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/sample.md\"               ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder\"           ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/sample.md\" ]]\n\n  diff                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/sample.md\")\n\n  # Adds to indexes:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  diff                                    \\\n    <(ls \"${NB_DIR}/home/Example Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/home/Example Folder/Sample Folder\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported                                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/sample.md  ]]\n}\n"
  },
  {
    "path": "test/folders-index-rebuild.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# rebuild #####################################################################\n\n@test \"'index rebuild' with folder path rebuilds a missing index in the current folder only.\" {\n  {\n    \"${_NB}\" init\n\n    # Add blank line to root-level .index to confirm blank lines are retained:\n\n    printf \"\\\\n\" > \"${NB_DIR}/home/.index\"\n\n    wc -l < \"${NB_DIR}/home/.index\" | tr -d ' '\n\n    diff <(wc -l < \"${NB_DIR}/home/.index\" | tr -d ' ') <(printf \"1\\\\n\")\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    printf \".index: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  # Run `index rebuild`:\n\n  run \"${_NB}\" index rebuild \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  cat \"${NB_DIR}/home/.index\"\n\n  # Verify existence of .index files:\n\n  [[   -e \"${NB_DIR}/home/.index\"                              ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  # Verify .index file contents:\n\n  printf \".index: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/.index\")\"\n  sed -n \"/^two.bookmark.md$/=\" \"${NB_DIR}/home/.index\"\n\n  [[ \"$(sed -n \"/^Example\\ Folder$/=\" \"${NB_DIR}/home/.index\")\" == \"\" ]]\n  [[ \"$(sed -n \"/^two.bookmark.md$/=\" \"${NB_DIR}/home/.index\")\" == \"\" ]]\n\n  diff <(cat \"${NB_DIR}/home/.index\") \\\n       <(printf \"\\\\n\")\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" != \"$(ls -t -r \"${NB_DIR}/home\")\" ]]\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" == \\\n       \"$(ls -t -r \"${NB_DIR}/home/Example Folder/Sample Folder\")\" ]]\n\n  # Verify the absence of a .index file in the notebook parent:\n\n  [[ ! -e \"${NB_DIR}/home/../.index\" ]]\n}\n\n@test \"'index rebuild --ancestors' with folder path rebuilds the index in all ancestors.\" {\n  {\n    \"${_NB}\" init\n\n    # Add blank line to root-level .index to confirm blank lines are retained:\n\n    printf \"\\\\n\" > \"${NB_DIR}/home/.index\"\n\n    wc -l < \"${NB_DIR}/home/.index\" | tr -d ' '\n\n    diff <(wc -l < \"${NB_DIR}/home/.index\" | tr -d ' ') <(printf \"1\\\\n\")\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    printf \".index: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  # Run `index rebuild`:\n\n  run \"${_NB}\" index rebuild \"${NB_DIR}/home/Example Folder/Sample Folder\" --ancestors\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  cat \"${NB_DIR}/home/.index\"\n\n  # Verify existence of .index files:\n\n  [[ -e \"${NB_DIR}/home/.index\"                              ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  # Verify .index file contents:\n\n  printf \".index: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/.index\")\"\n  sed -n \"/^two.bookmark.md$/=\" \"${NB_DIR}/home/.index\"\n\n  [[ \"$(sed -n \"/^two.bookmark.md$/=\" \"${NB_DIR}/home/.index\")\" == \"1\" ]]\n  [[ \"$(sed -n \"/^Example\\ Folder$/=\" \"${NB_DIR}/home/.index\")\" == \"2\" ]]\n\n  diff <(cat \"${NB_DIR}/home/.index\") \\\n       <(echo \"two.bookmark.md${_NEWLINE}Example Folder\")\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"$(ls -t -r \"${NB_DIR}/home\")\" ]]\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" == \\\n       \"$(ls -t -r \"${NB_DIR}/home/Example Folder\")\" ]]\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" == \\\n       \"$(ls -t -r \"${NB_DIR}/home/Example Folder/Sample Folder\")\" ]]\n\n  # Verify the absence of a .index file in the notebook parent:\n\n  [[ ! -e \"${NB_DIR}/home/../.index\" ]]\n}\n\n"
  },
  {
    "path": "test/folders-index-reconcile.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# reconcile ###################################################################\n\n@test \"'index reconcile' with folder path reconciles the index in the current folder only.\" {\n  {\n    \"${_NB}\" init\n\n    # Add blank line to root-level .index to confirm blank lines are retained:\n\n    printf \"\\\\n\" > \"${NB_DIR}/home/.index\"\n\n    wc -l < \"${NB_DIR}/home/.index\" | tr -d ' '\n\n    diff <(wc -l < \"${NB_DIR}/home/.index\" | tr -d ' ') <(printf \"1\\\\n\")\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    printf \".index: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  # Run `index reconcile`:\n\n  run \"${_NB}\" index reconcile \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  cat \"${NB_DIR}/home/.index\"\n\n  # Verify existence of .index files:\n\n  [[   -e \"${NB_DIR}/home/.index\"                              ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  # Verify .index file contents:\n\n  printf \".index: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/.index\")\"\n  sed -n \"/^two.bookmark.md$/=\" \"${NB_DIR}/home/.index\"\n\n  [[ \"$(sed -n \"/^Example\\ Folder$/=\" \"${NB_DIR}/home/.index\")\" == \"\" ]]\n  [[ \"$(sed -n \"/^two.bookmark.md$/=\" \"${NB_DIR}/home/.index\")\" == \"\" ]]\n\n  diff <(cat \"${NB_DIR}/home/.index\") \\\n       <(printf \"\\\\n\")\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" != \"$(ls -t -r \"${NB_DIR}/home\")\" ]]\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" == \\\n       \"$(ls -t -r \"${NB_DIR}/home/Example Folder/Sample Folder\")\" ]]\n\n  # Verify the absence of a .index file in the notebook parent:\n\n  [[ ! -e \"${NB_DIR}/home/../.index\" ]]\n}\n\n@test \"'index reconcile --ancestors' with folder path reconciles the index in all ancestors.\" {\n  {\n    \"${_NB}\" init\n\n    # Add blank line to root-level .index to confirm blank lines are retained:\n\n    printf \"\\\\n\" > \"${NB_DIR}/home/.index\"\n\n    wc -l < \"${NB_DIR}/home/.index\" | tr -d ' '\n\n    diff <(wc -l < \"${NB_DIR}/home/.index\" | tr -d ' ') <(printf \"1\\\\n\")\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    printf \".index: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  # Run `index reconcile`:\n\n  run \"${_NB}\" index reconcile \"${NB_DIR}/home/Example Folder/Sample Folder\" --ancestors\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  cat \"${NB_DIR}/home/.index\"\n\n  # Verify existence of .index files:\n\n  [[ -e \"${NB_DIR}/home/.index\"                              ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n\n  # Verify .index file contents:\n\n  printf \".index: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/.index\")\"\n  sed -n \"/^two.bookmark.md$/=\" \"${NB_DIR}/home/.index\"\n\n  [[ \"$(sed -n \"/^Example\\ Folder$/=\" \"${NB_DIR}/home/.index\")\" == \"2\" ]]\n  [[ \"$(sed -n \"/^two.bookmark.md$/=\" \"${NB_DIR}/home/.index\")\" == \"3\" ]]\n\n  diff <(cat \"${NB_DIR}/home/.index\") \\\n       <(echo \"${_NEWLINE}Example Folder${_NEWLINE}two.bookmark.md\")\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" != \"$(ls -t -r \"${NB_DIR}/home\")\" ]]\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" == \\\n       \"$(ls -t -r \"${NB_DIR}/home/Example Folder\")\" ]]\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" == \\\n       \"$(ls -t -r \"${NB_DIR}/home/Example Folder/Sample Folder\")\" ]]\n\n  # Verify the absence of a .index file in the notebook parent:\n\n  [[ ! -e \"${NB_DIR}/home/../.index\" ]]\n}\n"
  },
  {
    "path": "test/folders-index.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# #############################################################################\n\n@test \"'index' with folder path reconciles ancestors' indexes if .index doesn't exist.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    sleep 1\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n\n    sleep 1\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" index \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n\n  # .index is reconciled in notebook root:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n  # .index is generated in ancestor:\n\n  [[   -e \"${NB_DIR}/home/Example Folder/.index\"                       ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n  # .index is generated in folder:\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  diff                                                          \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\") \\\n    <(cat <<HEREDOC\none.bookmark.md\ntwo.bookmark.md\nthree.bookmark.md\nHEREDOC\n)\n\n  # Create git commit:\n\n  git -C \"${NB_DIR}/home\" log\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Reconcile Index'\n}\n\n# add #########################################################################\n\n@test \"'index add <filename>' with folder path adds an item to the folder index and does not reconcile ancestors.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Add existing files to the folder index:\n\n    {\n      printf \"one.bookmark.md\\\\n\"\n      printf \"two.bookmark.md\\\\n\"\n    } >> \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n    # Confirm the initial .index file configuration::\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"                               ]]\n    [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n    [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n  }\n\n  run \"${_NB}\" index add \"three.bookmark.md\" \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0  ]]\n  [[ -z \"${output}\"     ]]\n\n  # .index is not reconciled in notebook root:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n  # .index is not generated in ancestor:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  # item is added to the index:\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n}\n\n@test \"'index add <filename>' with non-existent filename and folder path returns error and does not reconcile .index or ancestors.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Add existing files to the folder index:\n\n    {\n      printf \"one.bookmark.md\\\\n\"\n      printf \"two.bookmark.md\\\\n\"\n    } >> \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n    # Confirm the initial .index file configuration::\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"                               ]]\n    [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n    [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ new.bookmark.md    ]]\n  }\n\n  run \"${_NB}\" index add \"new.bookmark.md\" \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 1                ]]\n  [[ \"${output}\" =~ File\\ not\\ found: ]]\n\n  # .index is not reconciled in notebook root:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[   -e \"${NB_DIR}/home/.index\"                          ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n  # .index is not generated in ancestor:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/.index\" ]]\n\n  # .index is not reconciled in folder:\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ new.bookmark.md    ]]\n}\n\n# get_basename ################################################################\n\n@test \"'index get_basename' with folder path prints the filename for an id.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    sleep 1\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n\n    sleep 1\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    [[   -e \"${NB_DIR}/home/.index\"                          ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" index get_basename 2 \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  [[ ${status} -eq 0                    ]]\n  [[ \"${lines[0]}\" =~ two.bookmark.md$  ]]\n\n  # .index is reconciled in notebook root:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n  # .index is generated in ancestor:\n\n  [[   -e \"${NB_DIR}/home/Example Folder/.index\"                       ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n  # .index is generated in folder:\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md   ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md   ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md ]]\n}\n\n# get_id #########################################################################\n\n@test \"'index get_id <filename>' with folder path prints the filename for an id.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n    sleep 1\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    sleep 1\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" index get_id two.bookmark.md \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  [[ ${status} -eq 0      ]]\n  [[ \"${lines[0]}\" == \"2\" ]]\n\n  # .index is reconciled in notebook root:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n  # .index is generated in ancestor:\n\n  [[   -e \"${NB_DIR}/home/Example Folder/.index\"                       ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n  # .index is generated in folder:\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n}\n\n# get_max_id ##################################################################\n\n@test \"'index get_max_id' with folder path prints the filename for an id.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" index get_max_id \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  [[ ${status} -eq 0      ]]\n  [[ \"${lines[0]}\" == \"3\" ]]\n\n  # .index is reconciled in notebook root:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n  # .index is generated in ancestor:\n\n  [[   -e \"${NB_DIR}/home/Example Folder/.index\"                       ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n  # .index is generated in folder:\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n}\n\n# delete ######################################################################\n\n@test \"'index delete <filename>' with folder path deletes <filename> from the index.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" index delete \"two.bookmark.md\" \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n\n  [[ ${status} -eq 0  ]]\n  [[ -z \"${output}\"   ]]\n\n  # .index is reconciled in notebook root:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n  # .index is generated in ancestor:\n\n  [[   -e \"${NB_DIR}/home/Example Folder/.index\"                       ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n  # .index is generated in folder and two.bookmark.md is deleted:\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n  ls \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" =~ two.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n}\n\n# show ########################################################################\n\n@test \"'index show' with folder path prints the index.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" index show \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  # .index is reconciled in notebook root:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n  # .index is generated in ancestor:\n\n  [[   -e \"${NB_DIR}/home/Example Folder/.index\"                       ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n  # .index is generated in folder:\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n\n  # output is the same as the content of .index\n\n  [[ ${status} -eq 0                                                                ]]\n  [[ \"${output}\"  == \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"  ]]\n}\n\n# update ######################################################################\n\n@test \"'index update <old> <new>' with folder updates the index.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                                 ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/one.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/two.bookmark.md\"    ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/three.bookmark.md\"  ]]\n\n    # Confirm the initial .index file configuration::\n\n    [[   -e \"${NB_DIR}/home/.index\"                              ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder     ]]\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md     ]]\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" index update \\\n    two.bookmark.md         \\\n    new-name.md             \\\n    \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  [[ ${status} -eq 0  ]]\n  [[ -z \"${output}\"   ]]\n\n  # .index is reconciled in notebook root:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n  # .index is generated in ancestor:\n\n  [[   -e \"${NB_DIR}/home/Example Folder/.index\"                       ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n  # .index is updated in folder:\n\n  cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n  [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ one.bookmark.md    ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ two.bookmark.md    ]]\n  [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ new-name.md        ]]\n  [[   \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   =~ three.bookmark.md  ]]\n}\n\n# verify ######################################################################\n\n@test \"'index verify' with folder verifies a valid index.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/1.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n    sleep 1\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/2.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    sleep 1\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/3.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                             ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/1.bookmark.md\"  ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/2.bookmark.md\"  ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/3.bookmark.md\"  ]]\n\n    # Reconcile all .indexes in the path:\n\n    run \"${_NB}\" index reconcile                        \\\n      \"${NB_DIR}/home/Example Folder/Sample Folder\"  \\\n      --ancestors > /dev/null\n\n    # .index is reconciled in notebook root:\n\n    cat \"${NB_DIR}/home/.index\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n    # .index is generated in ancestor:\n\n    [[   -e \"${NB_DIR}/home/Example Folder/.index\"                       ]]\n    [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n    # .index is generated in folder:\n\n    cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n    ls \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" == \\\n         \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\" ]]\n  }\n\n  run \"${_NB}\" index verify \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  [[ ${status} -eq 0  ]]\n  [[ -z \"${output}\"   ]]\n\n  # .index still reflects folder contents:\n\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" == \\\n       \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\" ]]\n}\n\n@test \"'index verify' with folder returns 1 with invalid index.\" {\n  {\n    \"${_NB}\" init\n\n    # Create directories:\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"  ]]\n\n    # Add files:\n\n    cat <<HEREDOC > \"${NB_DIR}/home/two.bookmark.md\"\n# Root-Level Example Title Two\n\n<https://root-2.example.test>\nHEREDOC\n\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/1.bookmark.md\"\n# Example Title One\n\n<https://1.example.test>\nHEREDOC\n    sleep 1\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/2.bookmark.md\"\n# Example Title Two\n\n<https://2.example.test>\nHEREDOC\n    sleep 1\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Folder/Sample Folder/3.bookmark.md\"\n# Example Title Three\n\n<https://3.example.test>\nHEREDOC\n\n    [[ -f \"${NB_DIR}/home/two.bookmark.md\"                             ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/1.bookmark.md\"  ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/2.bookmark.md\"  ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/3.bookmark.md\"  ]]\n\n    # Reconcile all .indexes in the path:\n\n    run \"${_NB}\" index reconcile                    \\\n      \"${NB_DIR}/home/Example Folder/Sample Folder\" \\\n      --ancestors > /dev/null\n\n\n    # .index is reconciled in notebook root:\n\n    cat \"${NB_DIR}/home/.index\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ Example\\ Folder ]]\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ two.bookmark.md ]]\n\n    # .index is generated in ancestor:\n\n    [[   -e \"${NB_DIR}/home/Example Folder/.index\"                       ]]\n    [[ \"$(cat \"${NB_DIR}/home/Example Folder/.index\")\" =~ Sample\\ Folder ]]\n\n    # .index is generated in folder:\n\n    cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n    ls \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" == \\\n         \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\" ]]\n\n    # Overwrite entries in folder index:\n\n    printf \"\" > \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n    [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" != \\\n         \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\" ]]\n  }\n\n  run \"${_NB}\" index verify \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" git log --stat\n\n  [[ ${status} -eq 1                  ]]\n  [[ \"${output}\"  =~ Index\\ corrupted ]]\n\n  # .index is not updated:\n\n  [[ -z \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\"   ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")\" != \\\n       \"$(ls \"${NB_DIR}/home/Example Folder/Sample Folder\")\"            ]]\n}\n\n"
  },
  {
    "path": "test/folders-list-pinned.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --pinned ####################################################################\n\n@test \"'NB_PINNED_PATTERN list --pinned --type' filters by type.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"     \\\n      --title     \"Title One\"       \\\n      --content   \"Content one.\"\n\n    \"${_NB}\" add  \"File Two.md\"     \\\n      --title     \"Title Two\"       \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder\" --type \"folder\"\n\n    \"${_NB}\" add  \"File Three.md\"   \\\n      --title     \"Title Three\"     \\\n      --content   \"Content Three.\"\n\n    \"${_NB}\" add  \"Sample Folder\" --type \"folder\"\n\n    \"${_NB}\" add  \"File Four.md\"    \\\n      --title     \"Title Four\"      \\\n      --content   \"Content Four.\"\n\n    \"${_NB}\" add  \"Demo Folder\" --type \"folder\"\n\n\n    \"${_NB}\" pin 2\n    \"${_NB}\" pin 3\n    \"${_NB}\" pin 5\n    \"${_NB}\" pin 6\n  }\n\n  run \"${_NB}\" list --pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 4                                 ]]\n\n  [[    \"${lines[0]}\"   =~  [.*2*].*\\ 📌\\ Title\\ Two          ]]\n  [[    \"${lines[1]}\"   =~  [.*3*].*\\ 📌\\ 📂\\ Example\\ Folder ]]\n  [[    \"${lines[2]}\"   =~  [.*5*].*\\ 📌\\ 📂\\ Sample\\ Folder  ]]\n  [[    \"${lines[3]}\"   =~  [.*6*].*\\ 📌\\ Title\\ Four         ]]\n\n  run \"${_NB}\" list --pinned --type folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 2                                 ]]\n\n  [[    \"${lines[0]}\"   =~  [.*3*].*\\ 📌\\ 📂\\ Example\\ Folder ]]\n  [[    \"${lines[1]}\"   =~  [.*5*].*\\ 📌\\ 📂\\ Sample\\ Folder  ]]\n\n  run \"${_NB}\" list --pinned --type md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 2                                 ]]\n\n  [[    \"${lines[0]}\"   =~  [.*2*].*\\ 📌\\ Title\\ Two          ]]\n  [[    \"${lines[1]}\"   =~  [.*6*].*\\ 📌\\ Title\\ Four         ]]\n\n  run \"${_NB}\" list --pinned --type example-type\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 5                                 ]]\n\n  [[    \"${lines[0]}\"   =~  0\\ pinned\\ example-type\\ items.   ]]\n  [[    \"${lines[1]}\"   =~  Pin\\ an\\ item:                    ]]\n  [[    \"${lines[2]}\"   =~  nb\\ pin\\ \\<id\\>                   ]]\n  [[    \"${lines[3]}\"   =~  Help\\ information:                ]]\n  [[    \"${lines[4]}\"   =~  nb\\ help                          ]]\n}\n\n@test \"'NB_PINNED_PATTERN list --pinned' only shows pins.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root three\"  \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\"   \\\n      --title     \"nested one\"              \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\"   \\\n      --title     \"nested two\"              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/three.md\" \\\n      --title     \"nested three\"            \\\n      --content   \"Content three.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\"   \\\n      --title     \"deep one\"                              \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\"   \\\n      --title     \"deep two\"                              \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/three.md\" \\\n      --title     \"deep three\"                            \\\n      --content   \"Content three.\"\n  }\n\n  run \"${_NB}\" list --pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 2                             ]]\n\n  [[    \"${lines[0]}\"   =~  [.*3*].*\\ 📌\\ root\\ three     ]]\n  [[    \"${lines[1]}\"   =~  [.*2*].*\\ 📌\\ root\\ two       ]]\n\n  run \"${_NB}\" list Example\\ Folder/ --pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 5                             ]]\n\n  [[    \"${lines[0]}\"   =~  0\\ pinned\\ items.             ]]\n  [[    \"${lines[1]}\"   =~  Pin\\ an\\ item:                ]]\n  [[    \"${lines[2]}\"   =~  nb\\ pin\\ 4/\\<id\\>             ]]\n  [[    \"${lines[3]}\"   =~  Help\\ information:            ]]\n  [[    \"${lines[4]}\"   =~  nb\\ help                      ]]\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/ --pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 2                             ]]\n\n  [[    \"${lines[0]}\"   =~  [.*Example\\ Folder/Sample\\ Folder/1.*].*\\ 📌\\ deep\\ one ]]\n  [[    \"${lines[1]}\"   =~  [.*Example\\ Folder/Sample\\ Folder/2.*].*\\ 📌\\ deep\\ two ]]\n}\n\n# --with-pinned ###############################################################\n\n@test \"'NB_PINNED_PATTERN list --with-pinned' only shows pins when type is blank.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root three\"  \\\n      --content   \"Content three. #pinned\"\n\n    sleep 1\n\n    \"${_NB}\" add  \"Example Folder/one.md\"   \\\n      --title     \"nested one\"              \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/two.md\"   \\\n      --title     \"nested two\"              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/three.md\" \\\n      --title     \"nested three\"            \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\"   \\\n      --title     \"deep one\"                              \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\"   \\\n      --title     \"deep two\"                              \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/three.md\" \\\n      --title     \"deep three\"                            \\\n      --content   \"Content three.\"\n  }\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 4                             ]]\n\n  [[    \"${lines[0]}\"   =~  [.*3*].*\\ 📌\\ root\\ three     ]]\n  [[    \"${lines[1]}\"   =~  [.*2*].*\\ 📌\\ root\\ two       ]]\n  [[    \"${lines[2]}\"   =~  [.*4*].*\\ 📂\\ Example\\ Folder ]]\n  [[    \"${lines[3]}\"   =~  [.*1*].*\\ root\\ one           ]]\n\n  run \"${_NB}\" list --with-pinned --type folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 1                             ]]\n\n  [[    \"${lines[0]}\"   =~  [.*4*].*\\ 📂\\ Example\\ Folder ]]\n}\n\n@test \"'NB_PINNED_PATTERN list --with-pinned' doesn't show pins when single selector match is present.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root three\"  \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\"   \\\n      --title     \"nested one\"              \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/two.md\"   \\\n      --title     \"nested two\"              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/three.md\" \\\n      --title     \"nested three\"            \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\"   \\\n      --title     \"deep one\"                              \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\"   \\\n      --title     \"deep two\"                              \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/three.md\" \\\n      --title     \"deep three\"                            \\\n      --content   \"Content three.\"\n  }\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 4                             ]]\n\n  [[    \"${lines[0]}\"   =~  [.*3*].*\\ 📌\\ root\\ three     ]]\n  [[    \"${lines[1]}\"   =~  [.*2*].*\\ 📌\\ root\\ two       ]]\n  [[    \"${lines[2]}\"   =~  [.*4*].*\\ 📂\\ Example\\ Folder ]]\n  [[    \"${lines[3]}\"   =~  [.*1*].*\\ root\\ one           ]]\n\n  run \"${_NB}\" list \"4\" --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 1                             ]]\n\n  [[    \"${lines[0]}\"   =~  [.*4*].*\\ 📂\\ Example\\ Folder ]]\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 4                             ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/1.*].*\\ 📌\\ nested\\ one    ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*Example\\ Folder/3.*].*\\ 📌\\ nested\\ three  ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*Example\\ Folder/4*].*\\ 📂\\ Sample\\ Folder  ]]\n  [[    \"${lines[3]}\"   =~  \\\n          [.*Example\\ Folder/2.*].*\\ nested\\ two        ]]\n\n  run \"${_NB}\" list Example\\ Folder/4 --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 1                           ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/4*].*\\ 📂\\ Sample\\ Folder  ]]\n\n  # switch notebooks\n\n  \"${_NB}\" notebooks add \"Example Notebook\"\n  \"${_NB}\" use \"Example Notebook\"\n\n  run \"${_NB}\" list home: --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 4                                   ]]\n\n  [[    \"${lines[0]}\"   =~  [.*home:3*].*\\ 📌\\ root\\ three      ]]\n  [[    \"${lines[1]}\"   =~  [.*home:2*].*\\ 📌\\ root\\ two        ]]\n  [[    \"${lines[2]}\"   =~  [.*home:4*].*\\ 📂\\ Example\\ Folder  ]]\n  [[    \"${lines[3]}\"   =~  [.*home:1*].*\\ root\\ one            ]]\n\n  run \"${_NB}\" list home:4 --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 1                                   ]]\n\n  [[    \"${lines[0]}\"   =~  [.*home:4*].*\\ 📂\\ Example\\ Folder  ]]\n\n  run \"${_NB}\" list home:Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 4                                 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*home:Example\\ Folder/1.*].*\\ 📌\\ nested\\ one     ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*home:Example\\ Folder/3.*].*\\ 📌\\ nested\\ three   ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*home:Example\\ Folder/4*].*\\ 📂\\ Sample\\ Folder   ]]\n  [[    \"${lines[3]}\"   =~  \\\n          [.*home:Example\\ Folder/2.*].*\\ nested\\ two         ]]\n\n  run \"${_NB}\" list home:Example\\ Folder/4 --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 1                                 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*home:Example\\ Folder/4*].*\\ 📂\\ Sample\\ Folder   ]]\n}\n\n@test \"'NB_PINNED_PATTERN list --with-pinned' filters pinned and unpinned items by filter pattern.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root three\"  \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\"   \\\n      --title     \"nested one\"              \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/two.md\"   \\\n      --title     \"nested two\"              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/three.md\" \\\n      --title     \"nested three\"            \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\"   \\\n      --title     \"deep one\"                              \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\"   \\\n      --title     \"deep two\"                              \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/three.md\" \\\n      --title     \"deep three\"                            \\\n      --content   \"Content three.\"\n  }\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 4                             ]]\n\n  [[    \"${lines[0]}\"   =~  [.*3*].*\\ 📌\\ root\\ three     ]]\n  [[    \"${lines[1]}\"   =~  [.*2*].*\\ 📌\\ root\\ two       ]]\n  [[    \"${lines[2]}\"   =~  [.*4*].*\\ 📂\\ Example\\ Folder ]]\n  [[    \"${lines[3]}\"   =~  [.*1*].*\\ root\\ one           ]]\n\n  run \"${_NB}\" list \"root\" --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n  [[    \"${#lines[@]}\"  -eq 3                             ]]\n\n  [[    \"${lines[0]}\"   =~  [.*3*].*\\ 📌\\ root\\ three     ]]\n  [[    \"${lines[1]}\"   =~  [.*2*].*\\ 📌\\ root\\ two       ]]\n  [[    \"${lines[2]}\"   =~  [.*1*].*\\ root\\ one           ]]\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 4                           ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/1.*].*\\ 📌\\ nested\\ one    ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*Example\\ Folder/3.*].*\\ 📌\\ nested\\ three  ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*Example\\ Folder/4*].*\\ 📂\\ Sample\\ Folder  ]]\n  [[    \"${lines[3]}\"   =~  \\\n          [.*Example\\ Folder/2.*].*\\ nested\\ two        ]]\n\n  run \"${_NB}\" list Example\\ Folder/ \"nested\" --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 3                           ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/1.*].*\\ 📌\\ nested\\ one    ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*Example\\ Folder/3.*].*\\ 📌\\ nested\\ three  ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*Example\\ Folder/2.*].*\\ nested\\ two        ]]\n\n  # switch notebooks\n\n  \"${_NB}\" notebooks add \"Example Notebook\"\n  \"${_NB}\" use \"Example Notebook\"\n\n  run \"${_NB}\" list home: --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 4                                   ]]\n\n  [[    \"${lines[0]}\"   =~  [.*home:3*].*\\ 📌\\ root\\ three      ]]\n  [[    \"${lines[1]}\"   =~  [.*home:2*].*\\ 📌\\ root\\ two        ]]\n  [[    \"${lines[2]}\"   =~  [.*home:4*].*\\ 📂\\ Example\\ Folder  ]]\n  [[    \"${lines[3]}\"   =~  [.*home:1*].*\\ root\\ one            ]]\n\n  run \"${_NB}\" list home: \"root\" --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 3                                   ]]\n\n  [[    \"${lines[0]}\"   =~  [.*home:3*].*\\ 📌\\ root\\ three      ]]\n  [[    \"${lines[1]}\"   =~  [.*home:2*].*\\ 📌\\ root\\ two        ]]\n  [[    \"${lines[2]}\"   =~  [.*home:1*].*\\ root\\ one            ]]\n\n  run \"${_NB}\" list home:Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 4                                 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*home:Example\\ Folder/1.*].*\\ 📌\\ nested\\ one     ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*home:Example\\ Folder/3.*].*\\ 📌\\ nested\\ three   ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*home:Example\\ Folder/4*].*\\ 📂\\ Sample\\ Folder   ]]\n  [[    \"${lines[3]}\"   =~  \\\n          [.*home:Example\\ Folder/2.*].*\\ nested\\ two         ]]\n\n  run \"${_NB}\" list home:Example\\ Folder/ \"nested\" --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 3                                 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*home:Example\\ Folder/1.*].*\\ 📌\\ nested\\ one     ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*home:Example\\ Folder/3.*].*\\ 📌\\ nested\\ three   ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*home:Example\\ Folder/2.*].*\\ nested\\ two         ]]\n}\n\n@test \"'NB_PINNED_PATTERN list [<folder>/] --with-pinned --limit' (slash) respects limit.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root three\"  \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\"   \\\n      --title     \"nested one\"              \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/two.md\"   \\\n      --title     \"nested two\"              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/three.md\" \\\n      --title     \"nested three\"            \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\"   \\\n      --title     \"deep one\"                              \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\"   \\\n      --title     \"deep two\"                              \\\n      --content   \"Content two. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/three.md\" \\\n      --title     \"deep three\"                            \\\n      --content   \"Content three.\"\n  }\n\n  run \"${_NB}\" list --with-pinned --limit 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 2                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*3*].*\\ 📌\\ root\\ three                               ]]\n  [[    \"${lines[1]}\"   =~  3\\ omitted.\\ 4\\ total.                ]]\n\n  run \"${_NB}\" list --with-pinned --limit 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*3*].*\\ 📌\\ root\\ three                               ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*2*].*\\ 📌\\ root\\ two                                 ]]\n  [[    \"${lines[2]}\"   =~  2\\ omitted.\\ 4\\ total.                ]]\n\n  run \"${_NB}\" list --with-pinned --limit 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 4                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*3*].*\\ 📌\\ root\\ three                               ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*2*].*\\ 📌\\ root\\ two                                 ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*4*].*\\ 📂\\ Example\\ Folder                           ]]\n  [[    \"${lines[3]}\"   =~  1\\ omitted.\\ 4\\ total.                ]]\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned --limit 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 2                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/1.*].*\\ 📌\\ nested\\ one              ]]\n  [[    \"${lines[1]}\"   =~  3\\ omitted.\\ 4\\ total.                ]]\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned --limit 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/1.*].*\\ 📌\\ nested\\ one              ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*Example\\ Folder/3.*].*\\ 📌\\ nested\\ three            ]]\n  [[    \"${lines[2]}\"   =~  2\\ omitted.\\ 4\\ total.                ]]\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned --limit 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 4                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/1.*].*\\ 📌\\ nested\\ one              ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*Example\\ Folder/3.*].*\\ 📌\\ nested\\ three            ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*4*].*\\ 📂\\ Sample\\ Folder                            ]]\n  [[    \"${lines[3]}\"   =~  1\\ omitted.\\ 4\\ total.                ]]\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/ --with-pinned --limit 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 2                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/1.*].*\\ 📌\\ deep\\ one ]]\n  [[    \"${lines[1]}\"   =~  2\\ omitted.\\ 3\\ total.                ]]\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/ --with-pinned --limit 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/1.*].*\\ 📌\\ deep\\ one ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/2.*].*\\ 📌\\ deep\\ two ]]\n  [[    \"${lines[2]}\"   =~  1\\ omitted.\\ 3\\ total.                ]]\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/ --with-pinned --limit 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 4                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/1.*].*\\ 📌\\ deep\\ one ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/2.*].*\\ 📌\\ deep\\ two ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/3.*].*\\ deep\\ three   ]]\n}\n\n@test \"'NB_PINNED_PATTERN list [<folder>/] --with-pinned' (slash) prints items tagged with #pinned in the current folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root three\"  \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\" \\\n      --title     \"nested one\"            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\" \\\n      --title     \"nested two\"            \\\n      --content   \"Content two. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\" \\\n      --title     \"deep one\"                            \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\" \\\n      --title     \"deep two\"                            \\\n      --content   \"Content two.\"\n  }\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 4                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*3*].*\\ 📌\\ root\\ three                               ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*4*].*\\ 📂\\ Example\\ Folder                           ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*2*].*\\ root\\ two                                     ]]\n  [[    \"${lines[3]}\"   =~  \\\n          [.*1*].*\\ root\\ one                                     ]]\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/2.*].*\\ 📌\\ nested\\ two              ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*Example\\ Folder/3*].*\\ 📂\\ Sample\\ Folder            ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*Example\\ Folder/1*].*\\ nested\\ one                   ]]\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 2                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/1.*].*\\ 📌\\ deep\\ one ]]\n  [[    \"${lines[1]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/2.*].*\\ deep\\ two     ]]\n}\n"
  },
  {
    "path": "test/folders-list.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# empty #######################################################################\n\n@test \"'list --type folder' with no folders displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" list --type folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  0\\ folders\\.                          ]]\n}\n\n@test \"'list --type folders' with no folders displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" list --type folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  0\\ folders\\.                          ]]\n}\n\n@test \"'list <folder>/ --type' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n  }\n\n  run \"${_NB}\" list Example\\ Folder/ --type audio\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  0\\ audio\\ items\\.                     ]]\n  [[   \"${lines[2]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n}\n\n@test \"'list <id>/ --type' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n  }\n\n  run \"${_NB}\" list 1/ --type audio\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  0\\ audio\\ items\\.                     ]]\n  [[   \"${lines[2]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n}\n\n@test \"'list <folder>/' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Example Folder\"\n  }\n\n  run \"${_NB}\" list Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  0\\ items\\.                            ]]\n  [[   \"${lines[2]}\"  =~  add\\ 1/                               ]]\n  [[   \"${lines[3]}\"  =~  bookmark                              ]]\n  [[   \"${lines[4]}\"  =~  1/\\ \\<url\\>                           ]]\n  [[   \"${lines[6]}\"  =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n  [[   \"${lines[8]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n}\n\n@test \"'list <id>/' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n  }\n\n  run \"${_NB}\" list 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  0\\ items\\.                            ]]\n  [[   \"${lines[2]}\"  =~  add\\ 1/                               ]]\n  [[   \"${lines[3]}\"  =~  bookmark                              ]]\n  [[   \"${lines[4]}\"  =~  1/\\ \\<url\\>                           ]]\n  [[   \"${lines[6]}\"  =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n  [[   \"${lines[8]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n}\n\n@test \"'list <folder>/<folder>/' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n  }\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                       ]]\n  [[   \"${lines[0]}\"  =~  0\\ items\\.                              ]]\n  [[   \"${lines[2]}\"  =~  add\\ 1/1/                               ]]\n  [[   \"${lines[3]}\"  =~  bookmark                                ]]\n  [[   \"${lines[4]}\"  =~  1/1/\\ \\<url\\>                           ]]\n  [[   \"${lines[6]}\"  =~  todo\\ add\\ 1/1/\\ \\<title\\>              ]]\n  [[   \"${lines[8]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/1/ ]]\n}\n\n@test \"'list <id>/<id>/' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n  }\n\n  run \"${_NB}\" list 1/1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                       ]]\n  [[   \"${lines[0]}\"  =~  0\\ items\\.                              ]]\n  [[   \"${lines[2]}\"  =~  add\\ 1/1/                               ]]\n  [[   \"${lines[3]}\"  =~  bookmark                                ]]\n  [[   \"${lines[4]}\"  =~  1/1/\\ \\<url\\>                           ]]\n  [[   \"${lines[6]}\"  =~  todo\\ add\\ 1/1/\\ \\<title\\>              ]]\n  [[   \"${lines[8]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/1/ ]]\n}\n\n@test \"'list <notebook>:<id>/' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" list home:1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                           ]]\n  [[   \"${lines[0]}\"  =~  0\\ items\\.                                  ]]\n  [[   \"${lines[2]}\"  =~  add\\ home:1/                                ]]\n  [[   \"${lines[3]}\"  =~  bookmark                                    ]]\n  [[   \"${lines[4]}\"  =~  home:1/\\ \\<url\\>                            ]]\n  [[   \"${lines[6]}\"  =~  todo\\ add\\ home:1/\\ \\<title\\>               ]]\n  [[   \"${lines[8]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ home:1/  ]]\n}\n\n# full path ###################################################################\n\n@test \"'list /full/path/to/notebook' (no slash) exits with 0 and lists files in notebook in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"                  \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"two.bookmark.md\"         \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"three.bookmark.md\"       \\\n      --content   \"<https://example.test>\"  \\\n      --encrypt   --password=password\n  }\n\n  # full path (no slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/home\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${#lines[@]}\" -eq 3                                     ]]\n\n  [[   \"${lines[0]}\"  =~  [.*3.*].*\\ 🔖\\ 🔒\\ three.bookmark.md  ]]\n  [[   \"${lines[1]}\"  =~  [.*2.*].*\\ 🔖\\ two.bookmark.md        ]]\n  [[   \"${lines[2]}\"  =~  [.*1.*].*\\ Title\\ One                 ]]\n}\n\n@test \"'list /full/path/to/notebook/' (slash) exits with 0 and lists files in notebook in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"                  \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"two.bookmark.md\"         \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"three.bookmark.md\"       \\\n      --content   \"<https://example.test>\"  \\\n      --encrypt   --password=password\n  }\n\n  # full path (slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/home/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${#lines[@]}\" -eq 3                                     ]]\n\n  [[   \"${lines[0]}\"  =~  [.*3.*].*\\ 🔖\\ 🔒\\ three.bookmark.md  ]]\n  [[   \"${lines[1]}\"  =~  [.*2.*].*\\ 🔖\\ two.bookmark.md        ]]\n  [[   \"${lines[2]}\"  =~  [.*1.*].*\\ Title\\ One                 ]]\n}\n\n@test \"'list /full/path/to/folder/' (slash) with conflicting notebook name exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/one.md\"             \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"Example Folder/two.bookmark.md\"    \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"Example Folder/three.bookmark.md\"  \\\n      --content   \"<https://example.test>\"            \\\n      --encrypt   --password=password\n\n    \"${_NB}\" notebooks add \"Example Folder\"\n    \"${_NB}\" notebooks use \"Example Folder\"\n\n    \"${_NB}\" add  \"Example Notebook File.md\"          \\\n      --content   \"Example notebook file content.\"\n\n    \"${_NB}\" notebooks use \"home\"\n\n    [[   -f \"${NB_DIR}/home/Example Folder/one.md\"              ]]\n    [[   -f \"${NB_DIR}/Example Folder/Example Notebook File.md\" ]]\n  }\n\n  # relative path\n\n  run \"${_NB}\" list \"Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n  [[   \"${#lines[@]}\" -eq 3     ]]\n\n  [[   \"${lines[0]}\"  =~  [.*Example\\ Folder/3.*].*\\ 🔖\\ 🔒\\ three.bookmark.md  ]]\n  [[   \"${lines[1]}\"  =~  [.*Example\\ Folder/2.*].*\\ 🔖\\ two.bookmark.md        ]]\n  [[   \"${lines[2]}\"  =~  [.*Example\\ Folder/1.*].*\\ Title\\ One                 ]]\n\n  # full path (slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/home/Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n  [[   \"${#lines[@]}\" -eq 3     ]]\n\n  [[   \"${lines[0]}\"  =~  \\\n          [.*Example\\ Folder/3.*].*\\ 🔖\\ 🔒\\ three.bookmark.md  ]]\n  [[   \"${lines[1]}\"  =~  \\\n          [.*Example\\ Folder/2.*].*\\ 🔖\\ two.bookmark.md        ]]\n  [[   \"${lines[2]}\"  =~  \\\n          [.*Example\\ Folder/1.*].*\\ Title\\ One                 ]]\n}\n\n@test \"'list /not/valid/full/path/to/folder/' (slash) with existing notebook exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/one.md\"             \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"Example Folder/two.bookmark.md\"    \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"Example Folder/three.bookmark.md\"  \\\n      --content   \"<https://example.test>\"            \\\n      --encrypt   --password=password\n  }\n\n  # full path (slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/home/not-valid/does-not-match/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1     ]]\n  [[   \"${#lines[@]}\" -eq 1     ]]\n\n  [[   \"${lines[0]}\"  =~  Not\\ found:\\ .*${NB_DIR}/home/not-valid/does-not-match  ]]\n}\n\n@test \"'list /not/valid/full/path/to/folder' (no slash) with existing notebook exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/one.md\"             \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"Example Folder/two.bookmark.md\"    \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"Example Folder/three.bookmark.md\"  \\\n      --content   \"<https://example.test>\"            \\\n      --encrypt   --password=password\n  }\n\n  # full path (slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/home/not-valid/does-not-match\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1     ]]\n  [[   \"${#lines[@]}\" -eq 1     ]]\n\n  [[   \"${lines[0]}\"  =~  Not\\ found:\\ .*${NB_DIR}/home/not-valid/does-not-match  ]]\n}\n\n@test \"'list /not/valid/full/path/to/folder/' (slash) without existing notebook treats exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/one.md\"             \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"Example Folder/two.bookmark.md\"    \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"Example Folder/three.bookmark.md\"  \\\n      --content   \"<https://example.test>\"            \\\n      --encrypt   --password=password\n  }\n\n  # full path (slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/example/not-valid/does-not-match/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1     ]]\n  [[   \"${#lines[@]}\" -eq 1     ]]\n\n  [[   \"${lines[0]}\"  =~  Not\\ found:\\ .*${NB_DIR}/example/not-valid/does-not-match  ]]\n}\n\n@test \"'list /not/valid/full/path/to/folder' (no slash) without existing notebook treats exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/one.md\"             \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"Example Folder/two.bookmark.md\"    \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"Example Folder/three.bookmark.md\"  \\\n      --content   \"<https://example.test>\"            \\\n      --encrypt   --password=password\n  }\n\n  # full path (slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/example/not-valid/does-not-match\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1     ]]\n  [[   \"${#lines[@]}\" -eq 1     ]]\n\n  [[   \"${lines[0]}\"  =~  Not\\ found:\\ .*${NB_DIR}/example/not-valid/does-not-match  ]]\n}\n\n@test \"'list /full/path/to/folder/' (slash) exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/one.md\"             \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"Example Folder/two.bookmark.md\"    \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"Example Folder/three.bookmark.md\"  \\\n      --content   \"<https://example.test>\"            \\\n      --encrypt   --password=password\n  }\n\n  # relative path\n\n  run \"${_NB}\" list \"Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n  [[   \"${#lines[@]}\" -eq 3     ]]\n\n  [[   \"${lines[0]}\"  =~  [.*Example\\ Folder/3.*].*\\ 🔖\\ 🔒\\ three.bookmark.md  ]]\n  [[   \"${lines[1]}\"  =~  [.*Example\\ Folder/2.*].*\\ 🔖\\ two.bookmark.md        ]]\n  [[   \"${lines[2]}\"  =~  [.*Example\\ Folder/1.*].*\\ Title\\ One                 ]]\n\n  # full path (slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/home/Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n  [[   \"${#lines[@]}\" -eq 3     ]]\n\n  [[   \"${lines[0]}\"  =~  \\\n          [.*Example\\ Folder/3.*].*\\ 🔖\\ 🔒\\ three.bookmark.md  ]]\n  [[   \"${lines[1]}\"  =~  \\\n          [.*Example\\ Folder/2.*].*\\ 🔖\\ two.bookmark.md        ]]\n  [[   \"${lines[2]}\"  =~  \\\n          [.*Example\\ Folder/1.*].*\\ Title\\ One                 ]]\n}\n\n@test \"'list /full/path/to/folder' (no slash) exits with 0 and lists folder item only.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/one.md\"             \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"Example Folder/two.bookmark.md\"    \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"Example Folder/three.bookmark.md\"  \\\n      --content   \"<https://example.test>\"            \\\n      --encrypt   --password=password\n  }\n\n  # relative path\n\n  run \"${_NB}\" list \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n  [[   \"${#lines[@]}\" -eq 1                               ]]\n\n  [[   \"${lines[0]}\"  =~  [.*1.*].*\\ 📂\\ Example\\ Folder  ]]\n\n  # full path (no slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/home/Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n  [[   \"${#lines[@]}\" -eq 1                               ]]\n\n  [[   \"${lines[0]}\"  =~  [.*1.*].*\\ 📂\\ Example\\ Folder  ]]\n}\n\n@test \"'list /full/path/to/folder/' (slash) in different notebook exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/one.md\"            \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"Example Notebook:Example Folder/two.bookmark.md\"   \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"Example Notebook:Example Folder/three.bookmark.md\" \\\n      --content   \"<https://example.test>\"                            \\\n      --encrypt   --password=password\n  }\n\n  # relative path\n\n  run \"${_NB}\" list \"Example Notebook:Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n  [[   \"${#lines[@]}\" -eq 3     ]]\n\n  [[   \"${lines[0]}\"  =~  [.*Example\\ Folder/3.*].*\\ 🔖\\ 🔒\\ three.bookmark.md  ]]\n  [[   \"${lines[1]}\"  =~  [.*Example\\ Folder/2.*].*\\ 🔖\\ two.bookmark.md        ]]\n  [[   \"${lines[2]}\"  =~  [.*Example\\ Folder/1.*].*\\ Title\\ One                 ]]\n\n  # full path (slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/Example Notebook/Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n  [[   \"${#lines[@]}\" -eq 3     ]]\n\n  [[   \"${lines[0]}\"  =~  \\\n          [.*Example\\ Notebook:Example\\ Folder/3.*].*\\ 🔖\\ 🔒\\ three.bookmark.md  ]]\n  [[   \"${lines[1]}\"  =~  \\\n          [.*Example\\ Notebook:Example\\ Folder/2.*].*\\ 🔖\\ two.bookmark.md        ]]\n  [[   \"${lines[2]}\"  =~  \\\n          [.*Example\\ Notebook:Example\\ Folder/1.*].*\\ Title\\ One                 ]]\n}\n\n@test \"'list /full/path/to/folder' (no slash) in different notebook exits with 0 and lists folder item only.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/one.md\"            \\\n      --title     \"Title One\"\n    \"${_NB}\" add  \"Example Notebook:Example Folder/two.bookmark.md\"   \\\n      --content   \"<https://example.test>\"\n    \"${_NB}\" add  \"Example Notebook:Example Folder/three.bookmark.md\" \\\n      --content   \"<https://example.test>\"                            \\\n      --encrypt   --password=password\n  }\n\n  # relative path\n\n  run \"${_NB}\" list \"Example Notebook:Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                                 ]]\n  [[   \"${#lines[@]}\" -eq 1                                                 ]]\n\n  [[   \"${lines[0]}\"  =~  [.*Example\\ Notebook:1.*].*\\ 📂\\ Example\\ Folder  ]]\n\n  # full path (no slash)\n\n  run \"${_NB}\" list \"${NB_DIR}/Example Notebook/Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                                 ]]\n  [[   \"${#lines[@]}\" -eq 1                                                 ]]\n\n  [[   \"${lines[0]}\"  =~  [.*Example\\ Notebook:1.*].*\\ 📂\\ Example\\ Folder  ]]\n}\n\n# index #######################################################################\n\n@test \"'list <folder>/<folder>/' reconciles ancestor indexes.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n\n    [[    -d \"${NB_DIR}/home/Example Folder/Sample Folder\"        ]]\n    [[ !  -e \"${NB_DIR}/home/Example Folder/.index\"               ]]\n    [[ !  -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n  [[    \"${lines[0]}\" =~  0\\ items\\.                              ]]\n\n  [[    -e \"${NB_DIR}/home/Example Folder/.index\"                 ]]\n  [[    -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"   ]]\n\n  diff                                                            \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")                 \\\n    <(printf \"Sample Folder\\\\n\")\n\n  diff                                                            \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")   \\\n    <(printf \"\")\n}\n\n@test \"'list <folder>/<folder>/<filename>' reconciles ancestor indexes.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${NB_DIR}/home/Example Folder/Sample Folder\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"\n\n    [[    -d \"${NB_DIR}/home/Example Folder/Sample Folder\"            ]]\n    [[ !  -e \"${NB_DIR}/home/Example Folder/.index\"                   ]]\n    [[ !  -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"     ]]\n    [[    -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\" ]]\n  }\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/example.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                           ]]\n  [[    \"${lines[0]}\" =~  example.md                                  ]]\n\n  [[    -e \"${NB_DIR}/home/Example Folder/.index\"                     ]]\n  [[    -e \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"       ]]\n  [[    -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"   ]]\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")                     \\\n    <(printf \"Sample Folder\\\\n\")\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/home/Example Folder/Sample Folder/.index\")       \\\n    <(printf \"example.md\\\\n\")\n}\n\n# excerpt #####################################################################\n\n@test \"'list <folder>/<folder>/<id> -e' includes excerpt line.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\" \\\n      --title     \"one\"                                 \\\n      --content   \"Content one.\"\n  }\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/one --excerpt\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  echo \"${#lines[1]}\"\n\n  [[    \"${status}\"     -eq 0                                             ]]\n  [[    \"${#lines[@]}\"  -eq 4                                             ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/Sample\\ Folder/1.*one         ]]\n  [[    \"${lines[1]}\"   =~  [^-]------------------------------------[^-]  ]]\n  [[    \"${#lines[1]}\"  =~  47                                            ]]\n}\n\n# filtering ###################################################################\n\n@test \"'list <folder>/ <pattern>...' (slash) exits with 0 and prints filtered list.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"    \\\n      --title     \"root one\"  \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"    \\\n      --title     \"root two\"  \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\" \\\n      --title     \"nested one\"            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\" \\\n      --title     \"nested two\"            \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\" \\\n      --title     \"deep one\"                            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\" \\\n      --title     \"deep two\"                            \\\n      --content   \"Content two.\"\n  }\n\n  run \"${_NB}\" list one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 1                               ]]\n\n  [[    \"${lines[0]}\"   =~  1.*root\\ one                    ]]\n\n  run \"${_NB}\" list Example\\ Folder/ one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 1                               ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/1.*nested\\ one  ]]\n\n  run \"${_NB}\" list Example\\ Folder/ nested\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 2                               ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/2.*nested\\ two  ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/1.*nested\\ one  ]]\n\n  run \"${_NB}\" list Example\\ Folder/ one two\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 2                               ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/2.*nested\\ two  ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/1.*nested\\ one  ]]\n}\n\n@test \"'list <folder> <pattern>...' (no slash) exits with 0 and treats folder as selector and filter pattern.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"    \\\n      --title     \"root one\"  \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"    \\\n      --title     \"root two\"  \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\" \\\n      --title     \"nested one\"            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\" \\\n      --title     \"nested two\"            \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\" \\\n      --title     \"deep one\"                            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\" \\\n      --title     \"deep two\"                            \\\n      --content   \"Content two.\"\n  }\n\n  run \"${_NB}\" list one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n  [[    \"${#lines[@]}\"  -eq 1                       ]]\n\n  [[    \"${lines[0]}\"   =~  1.*root\\ one            ]]\n  [[    \"${output}\"     =~  1.*root\\ one            ]]\n\n  run \"${_NB}\" list Example\\ Folder one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n  [[    \"${#lines[@]}\"  -eq 2                       ]]\n\n  [[    \"${lines[0]}\"   =~  3.*📂\\ Example\\ Folder  ]]\n  [[    \"${lines[1]}\"   =~  1.*root\\ one            ]]\n\n  run \"${_NB}\" list Example\\ Folder nested\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n  [[    \"${#lines[@]}\"  -eq 1                       ]]\n\n  [[    \"${lines[0]}\"   =~  3.*📂\\ Example\\ Folder  ]]\n\n  run \"${_NB}\" list Example\\ Folder one two\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n  [[    \"${#lines[@]}\"  -eq 3                       ]]\n\n  [[    \"${lines[2]}\"   =~  1.*root\\ one            ]]\n  [[    \"${lines[1]}\"   =~  2.*root\\ two            ]]\n  [[    \"${lines[0]}\"   =~  3.*📂\\ Example\\ Folder  ]]\n}\n\n# error handling ##############################################################\n\n@test \"'list filename/<id>' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"     --title \"one\"     --content \"Content one.\"\n    \"${_NB}\" add \"example.md\" --title \"example\" --content \"Content example.\"\n  }\n\n  run \"${_NB}\" list one.md/example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1             ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:    ]]\n  [[   \"${lines[0]}\"  =~ one.md/example ]]\n  [[   \"${#lines[@]}\" == 1              ]]\n}\n\n@test \"'list <not-valid-id>/' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list 10/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1           ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:  ]]\n  [[   \"${lines[0]}\"  =~ 10           ]]\n\n  [[ ! \"${output}\"  =~ three          ]]\n  [[ ! \"${output}\"  =~ 🔖\\ 🔒         ]]\n  [[ ! \"${output}\"  =~ two            ]]\n  [[ ! \"${output}\"  =~ 🔖             ]]\n  [[ ! \"${output}\"  =~ one            ]]\n}\n\n@test \"'list not-valid/' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list not-valid/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1           ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:  ]]\n  [[   \"${lines[0]}\"  =~ not-valid    ]]\n\n  [[ ! \"${output}\"  =~ three          ]]\n  [[ ! \"${output}\"  =~ 🔖\\ 🔒         ]]\n  [[ ! \"${output}\"  =~ two            ]]\n  [[ ! \"${output}\"  =~ 🔖             ]]\n  [[ ! \"${output}\"  =~ one            ]]\n}\n\n@test \"'list valid/<not-valid-id>/' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n    \"${_NB}\" add \"Example Folder/Sample 2 Folder 2\" --type folder\n  }\n\n  run \"${_NB}\" list Example\\ Folder/10/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1                         ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:                ]]\n  [[   \"${lines[0]}\"  =~ Example\\ Folder/10         ]]\n\n  [[ ! \"${output}\"  =~ three                        ]]\n  [[ ! \"${output}\"  =~ 🔖\\ 🔒                       ]]\n  [[ ! \"${output}\"  =~ two                          ]]\n  [[ ! \"${output}\"  =~ 🔖                           ]]\n  [[ ! \"${output}\"  =~ one                          ]]\n}\n\n@test \"'list valid/not-valid/' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list Example\\ Folder/not-valid/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1                                         ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:.*Example\\ Folder/not-valid/    ]]\n\n  [[ ! \"${output}\"  =~ three                                        ]]\n  [[ ! \"${output}\"  =~ 🔖\\ 🔒                                       ]]\n  [[ ! \"${output}\"  =~ two                                          ]]\n  [[ ! \"${output}\"  =~ 🔖                                           ]]\n  [[ ! \"${output}\"  =~ one                                          ]]\n}\n\n@test \"'list not-valid/not-valid/' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list not-valid/not-valid/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1                   ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:          ]]\n  [[   \"${lines[0]}\"  =~ not-valid/not-valid  ]]\n\n  [[ ! \"${output}\"  =~ three                  ]]\n  [[ ! \"${output}\"  =~ 🔖\\ 🔒                 ]]\n  [[ ! \"${output}\"  =~ two                    ]]\n  [[ ! \"${output}\"  =~ 🔖                     ]]\n  [[ ! \"${output}\"  =~ one                    ]]\n}\n\n@test \"'list not-valid' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1           ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:  ]]\n  [[   \"${lines[0]}\"  =~ not-valid    ]]\n}\n\n@test \"'list valid/not-valid' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list Example\\ Folder/not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1                                           ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:.*Example\\ Folder/.*\\ .*not-valid ]]\n}\n\n@test \"'list not-valid/not-valid' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list not-valid/not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1                   ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:          ]]\n  [[   \"${lines[0]}\"  =~ not-valid/not-valid  ]]\n}\n\n# list folder files ###########################################################\n\n@test \"'list folder/folder/<id>/' (slash) with file lists file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                                      \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/1/3/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                            ]]\n\n  [[   \"${lines[0]}\"  =~ Example\\ Folder/Sample\\ Folder/Demo\\ Folder/3 ]]\n  [[   \"${lines[0]}\"  =~ 🔖\\ 🔒                                        ]]\n  [[   \"${lines[0]}\"  =~ three.bookmark.md.enc                         ]]\n}\n\n# list notebook:<id> ##########################################################\n\n@test \"'list notebook:<id>/<folder>' exits with 0 and prints the folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"          \\\n      --title \"Two\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n}\n\n  run \"${_NB}\" list home:1/Sample\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n\n  [[   \"${lines[0]}\"  =~  [^/]home:Example\\ Folder/3      ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  📂                              ]]\n\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder                  ]]\n}\n\n@test \"'list <id>/<folder>' exits with 0 and prints the folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"          \\\n      --title \"Two\"\n}\n\n  run \"${_NB}\" list 1/Sample\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n\n  [[   \"${lines[0]}\"  =~  Example\\ Folder/3               ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  📂                              ]]\n\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder                  ]]\n}\n\n# list <id>/ ##################################################################\n\n@test \"'list folder/folder/<id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                                      \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n\n  [[   \"${lines[0]}\"  =~ three  ]]\n  [[   \"${lines[0]}\"  =~ 🔖\\ 🔒 ]]\n  [[   \"${lines[1]}\"  =~ two    ]]\n  [[   \"${lines[1]}\"  =~ 🔖     ]]\n  [[   \"${lines[2]}\"  =~ one    ]]\n  [[ ! \"${lines[2]}\"  =~ 🔖     ]]\n  [[ ! \"${lines[2]}\"  =~ 🔒     ]]\n}\n\n@test \"'list folder/<id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list Example\\ Folder/1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n\n  [[   \"${status}\"    -eq 0     ]]\n\n  [[   \"${lines[0]}\"  =~ three  ]]\n  [[   \"${lines[0]}\"  =~ 🔖\\ 🔒 ]]\n  [[   \"${lines[1]}\"  =~ two    ]]\n  [[   \"${lines[1]}\"  =~ 🔖     ]]\n  [[   \"${lines[2]}\"  =~ one    ]]\n  [[ ! \"${lines[2]}\"  =~ 🔖     ]]\n  [[ ! \"${lines[2]}\"  =~ 🔒     ]]\n}\n\n@test \"'list <id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n\n  [[   \"${lines[0]}\"  =~ three  ]]\n  [[   \"${lines[0]}\"  =~ 🔖\\ 🔒 ]]\n  [[   \"${lines[1]}\"  =~ two    ]]\n  [[   \"${lines[1]}\"  =~ 🔖     ]]\n  [[   \"${lines[2]}\"  =~ one    ]]\n  [[ ! \"${lines[2]}\"  =~ 🔖     ]]\n  [[ ! \"${lines[2]}\"  =~ 🔒     ]]\n}\n\n# list folder ################################################################\n\n@test \"'list folder/folder/folder' exits with 0 and prints the folder/folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"                   \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\"     \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"              \\\n      --title \"Two\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.txt\" \\\n      --content \"Content one.\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.txt\" \\\n      --content \"Content two.\"\n  }\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/Demo\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                           ]]\n\n  [[   \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder/3            ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder/Demo\\ Folder ]]\n  [[   \"${lines[0]}\"  =~  📂                                          ]]\n\n  [[ ! \"${lines[0]}\"  =~  Sample\\ Folder/Demo\\ Folder                 ]]\n  [[   \"${lines[0]}\"  =~  Demo\\ Folder                                ]]\n  [[   \"${#lines[@]}\" -eq 1                                           ]]\n}\n\n@test \"'list folder/folder' exits with 0 and prints the folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"          \\\n      --title \"Two\"\n  }\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                   ]]\n\n  [[   \"${lines[0]}\"  =~  Example\\ Folder/3                   ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder      ]]\n  [[   \"${lines[0]}\"  =~  📂                                  ]]\n\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder      ]]\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder                      ]]\n  [[   \"${#lines[@]}\" -eq 1                                   ]]\n}\n\n@test \"'list folder' exits with 0 and prints the folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/1.md\"          \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/2.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/3.bookmark.md\" \\\n      --content \"<https://example.test>\"        \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                 ]]\n\n  [[ ! \"${lines[0]}\"  =~  3\\.bookmark\\.md   ]]\n  [[ ! \"${lines[0]}\"  =~  🔖\\ 🔒            ]]\n  [[ ! \"${lines[1]}\"  =~  2\\.bookmark\\.md   ]]\n  [[ ! \"${lines[1]}\"  =~  🔖                ]]\n  [[ ! \"${lines[2]}\"  =~  one               ]]\n  [[ ! \"${lines[2]}\"  =~  🔖                ]]\n  [[ ! \"${lines[2]}\"  =~  🔒                ]]\n\n  [[   \"${lines[0]}\"  =~  3                 ]]\n  [[   \"${lines[0]}\"  =~  📂                ]]\n  [[   \"${lines[0]}\"  =~  Example\\ Folder   ]]\n  [[   \"${#lines[@]}\" -eq 1                 ]]\n}\n\n# list folder/ ################################################################\n\n@test \"'list folder/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n\n  [[   \"${lines[0]}\"  =~ three  ]]\n  [[   \"${lines[0]}\"  =~ 🔖\\ 🔒 ]]\n  [[   \"${lines[1]}\"  =~ two    ]]\n  [[   \"${lines[1]}\"  =~ 🔖     ]]\n  [[   \"${lines[2]}\"  =~ one    ]]\n  [[ ! \"${lines[2]}\"  =~ 🔖     ]]\n  [[ ! \"${lines[2]}\"  =~ 🔒     ]]\n}\n\n@test \"'list folder/folder/' exits with 0 and lists files in folder/folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/file 1.md\"  --content \"Example content one.\"\n    \"${_NB}\" add \"Example Folder/file 2.md\"  --content \"Example content two.\"\n    \"${_NB}\" add \"Example Folder/file 3.md\"  --content \"Example content three.\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" list Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0               ]]\n\n  [[ ! \"${lines[0]}\"  =~ three            ]]\n  [[ ! \"${lines[0]}\"  =~ 🔖\\ 🔒           ]]\n  [[ ! \"${lines[1]}\"  =~ two              ]]\n  [[ ! \"${lines[1]}\"  =~ 🔖               ]]\n  [[ ! \"${lines[2]}\"  =~ one              ]]\n  [[ ! \"${lines[2]}\"  =~ 🔖               ]]\n  [[ ! \"${lines[2]}\"  =~ 🔒               ]]\n\n  [[   \"${lines[0]}\"  =~ Sample\\ Folder   ]]\n  [[   \"${lines[1]}\"  =~ file\\ 3          ]]\n  [[   \"${lines[2]}\"  =~ file\\ 2          ]]\n  [[   \"${lines[3]}\"  =~ file\\ 1          ]]\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0     ]]\n\n  [[   \"${lines[0]}\"  =~ three  ]]\n  [[   \"${lines[0]}\"  =~ 🔖\\ 🔒 ]]\n  [[   \"${lines[1]}\"  =~ two    ]]\n  [[   \"${lines[1]}\"  =~ 🔖     ]]\n  [[   \"${lines[2]}\"  =~ one    ]]\n  [[ ! \"${lines[2]}\"  =~ 🔖     ]]\n  [[ ! \"${lines[2]}\"  =~ 🔒     ]]\n}\n\n@test \"'list folder/folder/folder/' exits with 0 and lists files in folder/folder/folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/file 1.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"Example Folder/file 2.md\" --content \"Example content two.\"\n    \"${_NB}\" add \"Example Folder/file 3.md\" --content \"Example content three.\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\"             \\\n      --content \"<https://example.test>\"                                      \\\n      --encrypt --password=password\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Document One.md\"   \\\n      --content \"Example content one.\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Document Two.md\"   \\\n      --content \"Example content two.\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Document Three.md\" \\\n      --content \"Example content three.\"\n  }\n\n  run \"${_NB}\" list Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0               ]]\n\n  [[ ! \"${lines[0]}\"  =~  three           ]]\n  [[ ! \"${lines[0]}\"  =~  🔖\\ 🔒          ]]\n  [[ ! \"${lines[1]}\"  =~  two             ]]\n  [[ ! \"${lines[1]}\"  =~  🔖              ]]\n  [[ ! \"${lines[2]}\"  =~  one             ]]\n  [[ ! \"${lines[2]}\"  =~  🔖              ]]\n  [[ ! \"${lines[2]}\"  =~  🔒              ]]\n\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder  ]]\n  [[   \"${lines[1]}\"  =~  file\\ 3         ]]\n  [[   \"${lines[2]}\"  =~  file\\ 2         ]]\n  [[   \"${lines[3]}\"  =~  file\\ 1         ]]\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0             ]]\n\n  [[   \"${lines[0]}\"  =~  Demo\\ Folder  ]]\n  [[   \"${lines[1]}\"  =~  three         ]]\n  [[   \"${lines[1]}\"  =~  🔖\\ 🔒        ]]\n  [[   \"${lines[2]}\"  =~  two           ]]\n  [[   \"${lines[2]}\"  =~  🔖            ]]\n  [[   \"${lines[3]}\"  =~  one           ]]\n  [[ ! \"${lines[3]}\"  =~  🔖            ]]\n  [[ ! \"${lines[3]}\"  =~  🔒            ]]\n\n  run \"${_NB}\" list Example\\ Folder/Sample\\ Folder/Demo\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                   ]]\n\n  [[   \"${lines[0]}\"  =~  Document\\ Three.md  ]]\n  [[   \"${lines[1]}\"  =~  Document\\ Two.md    ]]\n  [[   \"${lines[2]}\"  =~  Document\\ One.md    ]]\n}\n"
  },
  {
    "path": "test/folders-ls-pinned.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# search-based pinning ########################################################\n\n@test \"'NB_PINNED_PATTERN ls [<folder>/]' (slash) prints items tagged with #pinned in the current folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root three\"  \\\n      --content   \"Content three. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\" \\\n      --title     \"nested one\"            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\" \\\n      --title     \"nested two\"            \\\n      --content   \"Content two. #pinned\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\" \\\n      --title     \"deep one\"                            \\\n      --content   \"Content one. #pinned\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\" \\\n      --title     \"deep two\"                            \\\n      --content   \"Content two.\"\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n\n  [[    \"${lines[0]}\"   =~  home                                  ]]\n  [[    \"${lines[1]}\"   =~  ----                                  ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*3*].*\\ 📌\\ root\\ three                               ]]\n  [[    \"${lines[3]}\"   =~  \\\n          [.*4*].*\\ 📂\\ Example\\ Folder                           ]]\n  [[    \"${lines[4]}\"   =~  \\\n          [.*2*].*\\ root\\ two                                     ]]\n  [[    \"${lines[5]}\"   =~  \\\n          [.*1*].*\\ root\\ one                                     ]]\n  [[    \"${lines[6]}\"   =~  ----                                  ]]\n  [[    \"${lines[7]}\"   =~  nb\\ add                               ]]\n\n  run \"${_NB}\" ls Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n\n  [[    \"${lines[0]}\"   =~  home                                  ]]\n  [[    \"${lines[1]}\"   =~  ----                                  ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*Example\\ Folder/2.*].*\\ 📌\\ nested\\ two              ]]\n  [[    \"${lines[3]}\"   =~  \\\n          [.*Example\\ Folder/3*].*\\ 📂\\ Sample\\ Folder            ]]\n  [[    \"${lines[4]}\"   =~  \\\n          [.*Example\\ Folder/1*].*\\ nested\\ one                   ]]\n  [[    \"${lines[5]}\"   =~  ----                                  ]]\n  [[    \"${lines[6]}\"   =~  nb\\ add\\ 4/                           ]]\n\n\n  run \"${_NB}\" ls Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n\n  [[    \"${lines[0]}\"   =~  home                                  ]]\n  [[    \"${lines[1]}\"   =~  ----                                  ]]\n  [[    \"${lines[2]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/1.*].*\\ 📌\\ deep\\ one ]]\n  [[    \"${lines[3]}\"   =~  \\\n          [.*Example\\ Folder/Sample\\ Folder/2.*].*\\ deep\\ two     ]]\n  [[    \"${lines[4]}\"   =~  ----                                  ]]\n  [[    \"${lines[5]}\"   =~  nb\\ add\\ 4/3/                         ]]\n}\n"
  },
  {
    "path": "test/folders-ls.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# $_FOLDER_HEADER_ENABLED\n#\n# See also: $NB_FOLDER_HEADER in _ls().\n_FOLDER_HEADER_ENABLED=0\n\n# _FOLDER_HEADER_ON_EMPTY_ENABLED\n#\n# See also: $NB_FOLDER_HEADER in _ls().\n_FOLDER_HEADER_ON_EMPTY_ENABLED=1\n\n# empty #######################################################################\n\n@test \"'ls <folder>/ --type' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/ --type audio\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED)) || ((_FOLDER_HEADER_ON_EMPTY_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  ^Example\\ Folder                      ]]\n    [[ ! \"${lines[2]}\"  =~  ^📂\\ Example\\ Folder                  ]]\n    [[   \"${lines[4]}\"  =~  0\\ audio\\ items\\.                     ]]\n    [[   \"${lines[6]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  else\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  0\\ audio\\ items\\.                     ]]\n    [[   \"${lines[4]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  fi\n}\n\n@test \"'ls <id>/ --type' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n  }\n\n  run \"${_NB}\" ls 1/ --type audio\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED)) || ((_FOLDER_HEADER_ON_EMPTY_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  ^Example\\ Folder                      ]]\n    [[ ! \"${lines[2]}\"  =~  ^📂\\ Example\\ Folder                  ]]\n    [[   \"${lines[4]}\"  =~  0\\ audio\\ items\\.                     ]]\n    [[   \"${lines[6]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  else\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  0\\ audio\\ items\\.                     ]]\n    [[   \"${lines[4]}\"  =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n\n  fi\n}\n\n@test \"'ls <folder>/' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED)) || ((_FOLDER_HEADER_ON_EMPTY_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  ^Example\\ Folder                      ]]\n    [[ ! \"${lines[2]}\"  =~  ^📂\\ Example\\ Folder                  ]]\n    [[   \"${lines[4]}\"  =~  0\\ items\\.                            ]]\n    [[   \"${lines[10]}\" =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n    [[   \"${lines[12]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  else\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  0\\ items\\.                            ]]\n    [[   \"${lines[8]}\"  =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n    [[   \"${lines[10]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  fi\n}\n\n@test \"'ls <id>/' with conflicting id / folder name and empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n    \"${_NB}\" add \"Sample Folder/File One.md\" --content \"Example content.\"\n\n    \"${_NB}\" move \"Sample Folder\" \"1\" --force\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n    [[ -f \"${NB_DIR}/home/1/File One.md\"  ]]\n  }\n\n  run \"${_NB}\" ls 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED)) || ((_FOLDER_HEADER_ON_EMPTY_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  ^Example\\ Folder                      ]]\n    [[ ! \"${lines[2]}\"  =~  ^1                                    ]]\n    [[ ! \"${lines[2]}\"  =~  ^📂\\ Example\\ Folder                  ]]\n    [[   \"${lines[4]}\"  =~  0\\ items\\.                            ]]\n    [[   \"${lines[10]}\" =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n    [[   \"${lines[12]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  else\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  0\\ items\\.                            ]]\n    [[   \"${lines[8]}\"  =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n    [[   \"${lines[10]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  fi\n}\n\n@test \"'ls <id>/' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n  }\n\n  run \"${_NB}\" ls 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED)) || ((_FOLDER_HEADER_ON_EMPTY_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  ^Example\\ Folder                      ]]\n    [[ ! \"${lines[2]}\"  =~  ^📂\\ Example\\ Folder                  ]]\n    [[   \"${lines[4]}\"  =~  0\\ items\\.                            ]]\n    [[   \"${lines[10]}\" =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n    [[   \"${lines[12]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  else\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  0\\ items\\.                            ]]\n    [[   \"${lines[8]}\"  =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n    [[   \"${lines[10]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  fi\n}\n\n@test \"'ls <folder>/<folder>/' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED)) || ((_FOLDER_HEADER_ON_EMPTY_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                       ]]\n    [[   \"${lines[2]}\"  =~  ^Example\\ Folder                        ]]\n    [[ ! \"${lines[2]}\"  =~  ^📂\\ Example\\ Folder                    ]]\n    [[   \"${lines[2]}\"  =~  Sample\\ Folder                          ]]\n    [[   \"${lines[4]}\"  =~  0\\ items\\.                              ]]\n    [[   \"${lines[10]}\" =~  todo\\ add\\ 1/1/\\ \\<title\\>              ]]\n    [[   \"${lines[12]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/1/ ]]\n  else\n    [[   \"${status}\"    -eq 0                                       ]]\n    [[   \"${lines[2]}\"  =~  0\\ items\\.                              ]]\n    [[   \"${lines[8]}\"  =~  todo\\ add\\ 1/1/\\ \\<title\\>              ]]\n    [[   \"${lines[10]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/1/ ]]\n  fi\n}\n\n@test \"'ls <id>/<id>/' with empty folder displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n  }\n\n  run \"${_NB}\" ls 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED)) || ((_FOLDER_HEADER_ON_EMPTY_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  ^Example\\ Folder                      ]]\n    [[ ! \"${lines[2]}\"  =~  ^📂\\ Example\\ Folder                  ]]\n    [[   \"${lines[4]}\"  =~  0\\ items\\.                            ]]\n    [[   \"${lines[10]}\" =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n    [[   \"${lines[12]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  else\n    [[   \"${status}\"    -eq 0                                     ]]\n    [[   \"${lines[2]}\"  =~  0\\ items\\.                            ]]\n    [[   \"${lines[8]}\"  =~  todo\\ add\\ 1/\\ \\<title\\>              ]]\n    [[   \"${lines[10]}\" =~  import\\ \\(\\<path\\>\\ \\|\\ \\<url\\>\\)\\ 1/ ]]\n  fi\n}\n\n# limit ###################################################################\n\n@test \"'ls <folder>/' exits with 0 and respects limit.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"three.md\"    \\\n      --title     \"root three\"  \\\n      --content   \"Content Three.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\"   \\\n      --title     \"nested one\"              \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\"   \\\n      --title     \"nested two\"              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/thee.md\"  \\\n      --title     \"nested three\"            \\\n      --content   \"Content three.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\"   \\\n      --title     \"deep one\"                              \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\"   \\\n      --title     \"deep two\"                              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/three.md\" \\\n      --title     \"deep three\"                            \\\n      --content   \"Content three.\"\n\n    \"${_NB}\" set limit 2\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                         ]]\n  [[    \"${#lines[@]}\"  -ge 8                         ]]\n\n  [[    \"${lines[0]}\"   =~  home                      ]]\n  [[    \"${lines[1]}\"   =~  ------------              ]]\n  [[    \"${lines[2]}\"   =~  4.*📂\\ Example\\ Folder    ]]\n  [[    \"${lines[3]}\"   =~  3.*root\\ three            ]]\n  [[    \"${lines[4]}\"   =~  2\\ omitted\\.\\ 4\\ total\\.  ]]\n  [[    \"${lines[5]}\"   =~  ------------              ]]\n  [[    \"${lines[6]}\"   =~  nb\\ add                   ]]\n\n  run \"${_NB}\" ls Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -ge 8                                     ]]\n\n  [[    \"${lines[0]}\"   =~  home                                  ]]\n  [[    \"${lines[1]}\"   =~  ------------                          ]]\n  [[    \"${lines[2]}\"   =~  Example\\ Folder/4.*📂\\ Sample\\ Folder ]]\n  [[    \"${lines[3]}\"   =~  Example\\ Folder/3.*nested\\ three      ]]\n  [[    \"${lines[4]}\"   =~  2\\ omitted\\.\\ 4\\ total\\.              ]]\n  [[    \"${lines[5]}\"   =~  ------------                          ]]\n  [[    \"${lines[6]}\"   =~  nb\\ add\\ 4/                           ]]\n}\n\n@test \"'ls <folder>/ -s' exits with 0, respects limit, and hides header and footer.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"three.md\"    \\\n      --title     \"root three\"  \\\n      --content   \"Content Three.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\"   \\\n      --title     \"nested one\"              \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\"   \\\n      --title     \"nested two\"              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/thee.md\"  \\\n      --title     \"nested three\"            \\\n      --content   \"Content three.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\"   \\\n      --title     \"deep one\"                              \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\"   \\\n      --title     \"deep two\"                              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/three.md\" \\\n      --title     \"deep three\"                            \\\n      --content   \"Content three.\"\n\n    \"${_NB}\" set limit 2\n  }\n\n  run \"${_NB}\" ls -s\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                         ]]\n  [[    \"${#lines[@]}\"  -ge 3                         ]]\n\n  [[    \"${lines[0]}\"   =~  1.*root\\ one              ]]\n  [[    \"${lines[1]}\"   =~  2.*root\\ two              ]]\n  [[    \"${lines[2]}\"   =~  2\\ omitted\\.\\ 4\\ total\\.  ]]\n\n  run \"${_NB}\" ls Example\\ Folder/ -s\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -ge 3                               ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/1.*nested\\ one  ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/2.*nested\\ two  ]]\n  [[    \"${lines[2]}\"   =~  2\\ omitted\\.\\ 4\\ total\\.        ]]\n}\n\n@test \"'ls <folder>/ <pattern>...' (space) exits with 0 and ignores limit.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"three.md\"    \\\n      --title     \"root three\"  \\\n      --content   \"Content Three.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\"   \\\n      --title     \"nested one\"              \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\"   \\\n      --title     \"nested two\"              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/thee.md\"  \\\n      --title     \"nested three\"            \\\n      --content   \"Content three.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\"   \\\n      --title     \"deep one\"                              \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\"   \\\n      --title     \"deep two\"                              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/three.md\" \\\n      --title     \"deep three\"                            \\\n      --content   \"Content three.\"\n\n    \"${_NB}\" set limit 2\n  }\n\n  run \"${_NB}\" ls root\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 3                                 ]]\n\n  [[    \"${lines[0]}\"   =~  3.*root\\ three                    ]]\n  [[    \"${lines[1]}\"   =~  2.*root\\ two                      ]]\n  [[    \"${lines[2]}\"   =~  1.*root\\ one                      ]]\n\n  run \"${_NB}\" ls Example\\ Folder/ one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 1                                 ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/1.*nested\\ one    ]]\n\n  run \"${_NB}\" ls Example\\ Folder/ nested\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 3                                 ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/3.*nested\\ three  ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/2.*nested\\ two    ]]\n  [[    \"${lines[2]}\"   =~  Example\\ Folder/1.*nested\\ one    ]]\n  [[ !  \"${output}\"     =~  omitted                           ]]\n\n  run \"${_NB}\" list Example\\ Folder/ one two\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 2                                 ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/2.*nested\\ two    ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/1.*nested\\ one    ]]\n}\n\n@test \"'ls <folder>/<pattern>...' (no space) exits with 0 and ignores limit.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"      \\\n      --title     \"root one\"    \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"      \\\n      --title     \"root two\"    \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"three.md\"    \\\n      --title     \"root three\"  \\\n      --content   \"Content Three.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\"   \\\n      --title     \"nested one\"              \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\"   \\\n      --title     \"nested two\"              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/thee.md\"  \\\n      --title     \"nested three\"            \\\n      --content   \"Content three.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\"   \\\n      --title     \"deep one\"                              \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\"   \\\n      --title     \"deep two\"                              \\\n      --content   \"Content two.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/three.md\" \\\n      --title     \"deep three\"                            \\\n      --content   \"Content three.\"\n\n    \"${_NB}\" set limit 2\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 1                                 ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/1.*nested\\ one    ]]\n\n  run \"${_NB}\" ls Example\\ Folder/nested\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 3                                 ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/3.*nested\\ three  ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/2.*nested\\ two    ]]\n  [[    \"${lines[2]}\"   =~  Example\\ Folder/1.*nested\\ one    ]]\n  [[ !  \"${output}\"     =~  omitted                           ]]\n\n  run \"${_NB}\" list Example\\ Folder/one two\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 2                                 ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/2.*nested\\ two    ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/1.*nested\\ one    ]]\n\n  run \"${_NB}\" list Example\\ Folder/one two three\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 3                                 ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/3.*nested\\ three  ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/2.*nested\\ two    ]]\n  [[    \"${lines[2]}\"   =~  Example\\ Folder/1.*nested\\ one    ]]\n  [[ !  \"${output}\"     =~  omitted                           ]]\n}\n\n# error handling ##############################################################\n\n@test \"'ls <not-valid>/' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" ls not-valid/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1             ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:    ]]\n  [[   \"${lines[0]}\"  =~ not-valid/     ]]\n  [[   \"${#lines[@]}\" == 1              ]]\n}\n\n@test \"'ls <folder>/ <no-match>' (slash, space) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/ no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                              ]]\n  [[    \"${#lines[@]}\" -eq 1                                              ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*Example\\ Folder/.*\\ .*no-match  ]]\n}\n\n@test \"'ls <folder>/<no-match>' (slash, no space) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                              ]]\n  [[    \"${#lines[@]}\" -eq 1                                              ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*Example\\ Folder/.*\\ .*no-match  ]]\n}\n\n@test \"'ls <folder> <no-match>' (no slash, space) exits with 0 and lists folder match.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" ls Example\\ Folder no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                          ]]\n  [[    \"${#lines[@]}\" -eq 1                          ]]\n  [[    \"${lines[0]}\"  =~  1.*\\ 📂\\ .*Example\\ Folder ]]\n}\n\n@test \"'ls <notebook>:<folder>/ <no-match>' (slash, space) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:Example\\ Folder/ no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                                    ]]\n  [[    \"${#lines[@]}\" -eq 1                                                    ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*home:.*Example\\ Folder/.*\\ .*no-match ]]\n}\n\n@test \"'ls <notebook>:<folder>/<no-match>' (slash, no space) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:Example\\ Folder/no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                                    ]]\n  [[    \"${#lines[@]}\" -eq 1                                                    ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*home:.*Example\\ Folder/.*\\ .*no-match ]]\n}\n\n@test \"'ls <notebook>:<folder> <no-match>' (no slash, space) exits with 0 and lists folder match.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:Example\\ Folder no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                ]]\n  [[    \"${#lines[@]}\" -eq 1                                ]]\n  [[    \"${lines[0]}\"  =~  home:1.*\\ 📂\\ .*Example\\ Folder  ]]\n}\n\n# filtering ###################################################################\n\n@test \"'ls <folder>/ <pattern>...' (slash) exits with 0 and prints filtered list.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"    \\\n      --title     \"root one\"  \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"    \\\n      --title     \"root two\"  \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\" \\\n      --title     \"nested one\"            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\" \\\n      --title     \"nested two\"            \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\" \\\n      --title     \"deep one\"                            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\" \\\n      --title     \"deep two\"                            \\\n      --content   \"Content two.\"\n  }\n\n  run \"${_NB}\" ls one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 1                               ]]\n\n  [[    \"${lines[0]}\"   =~  1.*root\\ one                    ]]\n\n  run \"${_NB}\" ls Example\\ Folder/ one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 1                               ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/1.*nested\\ one  ]]\n\n  run \"${_NB}\" ls Example\\ Folder/ nested\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 2                               ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/2.*nested\\ two  ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/1.*nested\\ one  ]]\n\n  run \"${_NB}\" list Example\\ Folder/ one two\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 2                               ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/2.*nested\\ two  ]]\n  [[    \"${lines[1]}\"   =~  Example\\ Folder/1.*nested\\ one  ]]\n}\n\n@test \"'ls <notebook>:<folder>/ <pattern>...' (slash) exits with 0 and prints filtered list.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"    \\\n      --title     \"root one\"  \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"    \\\n      --title     \"root two\"  \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\" \\\n      --title     \"nested one\"            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\" \\\n      --title     \"nested two\"            \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\" \\\n      --title     \"deep one\"                            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\" \\\n      --title     \"deep two\"                            \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" notebooks add \"example-notebook\"\n    \"${_NB}\" use \"example-notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"example-notebook\"    ]]\n  }\n\n  run \"${_NB}\" ls home: one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 1                                   ]]\n\n  [[    \"${lines[0]}\"   =~  home:1.*root\\ one                   ]]\n\n  run \"${_NB}\" ls home:Example\\ Folder/ one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 1                                   ]]\n\n  [[    \"${lines[0]}\"   =~  home:Example\\ Folder/1.*nested\\ one ]]\n\n  run \"${_NB}\" ls home:Example\\ Folder/ nested\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 2                                   ]]\n\n  [[    \"${lines[0]}\"   =~  home:Example\\ Folder/2.*nested\\ two ]]\n  [[    \"${lines[1]}\"   =~  home:Example\\ Folder/1.*nested\\ one ]]\n\n  run \"${_NB}\" list home:Example\\ Folder/ one two\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 2                                   ]]\n\n  [[    \"${lines[0]}\"   =~  home:Example\\ Folder/2.*nested\\ two ]]\n  [[    \"${lines[1]}\"   =~  home:Example\\ Folder/1.*nested\\ one ]]\n}\n\n@test \"'ls <folder> <pattern>...' (no slash) exits with 0 and treats folder as selector and filter pattern.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"    \\\n      --title     \"root one\"  \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"    \\\n      --title     \"root two\"  \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\" \\\n      --title     \"nested one\"            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\" \\\n      --title     \"nested two\"            \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\" \\\n      --title     \"deep one\"                            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\" \\\n      --title     \"deep two\"                            \\\n      --content   \"Content two.\"\n  }\n\n  run \"${_NB}\" list one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n  [[    \"${#lines[@]}\"  -eq 1                       ]]\n\n  [[    \"${lines[0]}\"   =~  1.*root\\ one            ]]\n  [[    \"${output}\"     =~  1.*root\\ one            ]]\n\n  run \"${_NB}\" list Example\\ Folder one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n  [[    \"${#lines[@]}\"  -eq 2                       ]]\n\n  [[    \"${lines[0]}\"   =~  3.*📂\\ Example\\ Folder  ]]\n  [[    \"${lines[1]}\"   =~  1.*root\\ one            ]]\n\n  run \"${_NB}\" list Example\\ Folder nested\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n  [[    \"${#lines[@]}\"  -eq 1                       ]]\n\n  [[    \"${lines[0]}\"   =~  3.*📂\\ Example\\ Folder  ]]\n\n  run \"${_NB}\" list Example\\ Folder one two\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n  [[    \"${#lines[@]}\"  -eq 3                       ]]\n\n  [[    \"${lines[2]}\"   =~  1.*root\\ one            ]]\n  [[    \"${lines[1]}\"   =~  2.*root\\ two            ]]\n  [[    \"${lines[0]}\"   =~  3.*📂\\ Example\\ Folder  ]]\n}\n\n@test \"'ls <notebook>:<folder> <pattern>...' (no slash) exits with 0 and treats folder as selector and filter pattern.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"one.md\"    \\\n      --title     \"root one\"  \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"two.md\"    \\\n      --title     \"root two\"  \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/one.md\" \\\n      --title     \"nested one\"            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/two.md\" \\\n      --title     \"nested two\"            \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/one.md\" \\\n      --title     \"deep one\"                            \\\n      --content   \"Content one.\"\n    \"${_NB}\" add  \"Example Folder/Sample Folder/two.md\" \\\n      --title     \"deep two\"                            \\\n      --content   \"Content two.\"\n\n    \"${_NB}\" notebooks add \"example-notebook\"\n    \"${_NB}\" use \"example-notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"example-notebook\" ]]\n  }\n\n  run \"${_NB}\" list home: one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 1                           ]]\n\n  [[    \"${lines[0]}\"   =~  home:1.*root\\ one           ]]\n  [[    \"${output}\"     =~  home:1.*root\\ one           ]]\n\n  run \"${_NB}\" list home:Example\\ Folder one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 2                           ]]\n\n  [[    \"${lines[0]}\"   =~  home:3.*📂\\ Example\\ Folder ]]\n  [[    \"${lines[1]}\"   =~  home:1.*root\\ one           ]]\n\n  run \"${_NB}\" list home:Example\\ Folder nested\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 1                           ]]\n\n  [[    \"${lines[0]}\"   =~  home:3.*📂\\ Example\\ Folder ]]\n\n  run \"${_NB}\" list home:Example\\ Folder one two\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 3                           ]]\n\n  [[    \"${lines[2]}\"   =~  home:1.*root\\ one           ]]\n  [[    \"${lines[1]}\"   =~  home:2.*root\\ two           ]]\n  [[    \"${lines[0]}\"   =~  home:3.*📂\\ Example\\ Folder ]]\n}\n\n# footer ######################################################################\n\n@test \"'<id>/' prints footer with commands scoped to folder id.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                         \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"           \\\n      --title \"Two\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\" ]]\n  }\n\n  run \"${_NB}\" 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"\\${lines[6]}: '%s'\\\\n\" \"${lines[6]}\"\n  printf \"\\${lines[8]}: '%s'\\\\n\" \"${lines[8]}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0       ]]\n    [[   \"${lines[8]}\"  =~ add\\ 1/  ]]\n  else\n    [[   \"${status}\"    -eq 0       ]]\n    [[   \"${lines[6]}\"  =~ add\\ 1/  ]]\n  fi\n}\n\n@test \"'<folder>/' prints footer with commands scoped to folder id.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                         \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"           \\\n      --title \"Two\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\" ]]\n  }\n\n  run \"${_NB}\" Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"\\${lines[6]}: '%s'\\\\n\" \"${lines[6]}\"\n  printf \"\\${lines[8]}: '%s'\\\\n\" \"${lines[8]}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0       ]]\n    [[   \"${lines[8]}\"  =~ add\\ 1/  ]]\n  else\n    [[   \"${status}\"    -eq 0       ]]\n    [[   \"${lines[6]}\"  =~ add\\ 1/  ]]\n  fi\n}\n\n@test \"'notebook:<id>/' prints footer with commands scoped to notebook and folder id.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Notebook One\"\n\n    \"${_NB}\" add \"Notebook One:Example Folder/one.md\"                         \\\n      --title \"one\"\n    \"${_NB}\" add \"Notebook One:Example Folder/two.bookmark.md\"                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Notebook One:Example Folder/Sample Folder/one.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Notebook One:Example Folder/Sample Folder/two.md\"           \\\n      --title \"Two\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\" ]]\n  }\n\n  run \"${_NB}\" Notebook\\ One:1/\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n\n  printf \"\\${lines[6]}: '%s'\\\\n\" \"${lines[6]}\"\n  printf \"\\${lines[8]}: '%s'\\\\n\" \"${lines[8]}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                       ]]\n    [[   \"${lines[8]}\"  =~ add\\ Notebook\\\\\\ One:1/  ]]\n  else\n    [[   \"${status}\"    -eq 0                       ]]\n    [[   \"${lines[6]}\"  =~ add\\ Notebook\\\\\\ One:1/  ]]\n  fi\n}\n\n@test \"'notebook:<folder>/' prints footer with commands scoped to notebook and folder id.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Notebook One\"\n\n    \"${_NB}\" add \"Notebook One:Example Folder/one.md\"                         \\\n      --title \"one\"\n    \"${_NB}\" add \"Notebook One:Example Folder/two.bookmark.md\"                \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Notebook One:Example Folder/Sample Folder/one.bookmark.md\"  \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Notebook One:Example Folder/Sample Folder/two.md\"           \\\n      --title \"Two\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\" ]]\n  }\n\n  run \"${_NB}\" Notebook\\ One:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"\\${lines[6]}: '%s'\\\\n\" \"${lines[6]}\"\n  printf \"\\${lines[8]}: '%s'\\\\n\" \"${lines[8]}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                       ]]\n    [[   \"${lines[8]}\"  =~ add\\ Notebook\\\\\\ One:1/  ]]\n  else\n    [[   \"${status}\"    -eq 0                       ]]\n    [[   \"${lines[6]}\"  =~ add\\ Notebook\\\\\\ One:1/  ]]\n  fi\n}\n\n# notebook:<id> ###############################################################\n\n@test \"'notebook:<id>/<folder>' exits with 0 and prints the folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"          \\\n      --title \"Two\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n}\n\n  run \"${_NB}\" home:1/Sample\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n\n  [[   \"${#lines[@]}\" -eq 1                               ]]\n\n  [[   \"${lines[0]}\"  =~  [^/]home:Example\\ Folder/3      ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  📂                              ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder                  ]]\n}\n\n@test \"'notebook:folder/folder/<id>' exits with 0 and prints the folder/folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"                   \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\"     \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"              \\\n      --title \"Two\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.txt\" \\\n      --content \"Content one.\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.txt\" \\\n      --content \"Content two.\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" home:Example\\ Folder/Sample\\ Folder/3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                           ]]\n\n  [[   \"${#lines[@]}\" -eq 1                                           ]]\n\n  [[   \"${lines[0]}\"  =~  [^/]home:Example\\ Folder/Sample\\ Folder/3   ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder/Demo\\ Folder ]]\n  [[   \"${lines[0]}\"  =~  📂                                          ]]\n  [[ ! \"${lines[0]}\"  =~  Sample\\ Folder/Demo\\ Folder                 ]]\n  [[   \"${lines[0]}\"  =~  Demo\\ Folder                                ]]\n}\n\n@test \"'notebook:folder/<id>' exits with 0 and prints the folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"          \\\n      --title \"Two\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n}\n\n  run \"${_NB}\" home:Example\\ Folder/3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n\n  [[   \"${#lines[@]}\" -eq 1                               ]]\n\n  [[   \"${lines[0]}\"  =~  [^/]home:Example\\ Folder/3      ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  📂                              ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder                  ]]\n}\n\n@test \"'notebook:<id>' exits with 0 and prints the folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/1.md\"          \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/2.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/3.bookmark.md\" \\\n      --content \"<https://example.test>\"        \\\n      --encrypt --password=password\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" home:1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                         ]]\n\n  [[ ! \"${lines[0]}\"  =~  3\\.bookmark\\.md           ]]\n  [[ ! \"${lines[0]}\"  =~  🔖\\ 🔒                    ]]\n  [[ ! \"${lines[1]}\"  =~  2\\.bookmark\\.md           ]]\n  [[ ! \"${lines[1]}\"  =~  🔖                        ]]\n  [[ ! \"${lines[2]}\"  =~  one                       ]]\n  [[ ! \"${lines[2]}\"  =~  🔖                        ]]\n  [[ ! \"${lines[2]}\"  =~  🔒                        ]]\n\n  [[ ! \"${lines[0]}\"  =~  [^/]home:Example\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  3                         ]]\n  [[   \"${lines[0]}\"  =~  📂                        ]]\n  [[   \"${lines[0]}\"  =~  Example\\ Folder           ]]\n  [[   \"${#lines[@]}\" -eq 1                         ]]\n}\n\n# ls notebook:<id> ############################################################\n\n@test \"'ls notebook:<id>/<folder>' exits with 0 and prints the folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"          \\\n      --title \"Two\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n}\n\n  run \"${_NB}\" ls home:1/Sample\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n\n  [[   \"${#lines[@]}\" -eq 1                               ]]\n\n  [[   \"${lines[0]}\"  =~  home:Example\\ Folder/3          ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  📂                              ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder                  ]]\n}\n\n@test \"'ls notebook:folder/folder/<id>' exits with 0 and prints the folder/folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"                   \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\"     \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"              \\\n      --title \"Two\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.txt\" \\\n      --content \"Content one.\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.txt\" \\\n      --content \"Content two.\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:Example\\ Folder/Sample\\ Folder/3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                           ]]\n\n  [[   \"${#lines[@]}\" -eq 1                                           ]]\n\n  [[   \"${lines[0]}\"  =~  home:Example\\ Folder/Sample\\ Folder/3       ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder/Demo\\ Folder ]]\n  [[   \"${lines[0]}\"  =~  📂                                          ]]\n  [[ ! \"${lines[0]}\"  =~  Sample\\ Folder/Demo\\ Folder                 ]]\n  [[   \"${lines[0]}\"  =~  Demo\\ Folder                                ]]\n}\n\n@test \"'ls notebook:folder/<id>' exits with 0 and prints the folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"          \\\n      --title \"Two\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n}\n\n  run \"${_NB}\" ls home:Example\\ Folder/3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n\n  [[   \"${#lines[@]}\" -eq 1                               ]]\n\n  [[   \"${lines[0]}\"  =~  home:Example\\ Folder/3          ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  📂                              ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder                  ]]\n}\n\n@test \"'ls notebook:<id>' exits with 0 and prints the folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/1.md\"          \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/2.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/3.bookmark.md\" \\\n      --content \"<https://example.test>\"        \\\n      --encrypt --password=password\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                     ]]\n\n  [[ ! \"${lines[0]}\"  =~  3\\.bookmark\\.md       ]]\n  [[ ! \"${lines[0]}\"  =~  🔖\\ 🔒                ]]\n  [[ ! \"${lines[1]}\"  =~  2\\.bookmark\\.md       ]]\n  [[ ! \"${lines[1]}\"  =~  🔖                    ]]\n  [[ ! \"${lines[2]}\"  =~  one                   ]]\n  [[ ! \"${lines[2]}\"  =~  🔖                    ]]\n  [[ ! \"${lines[2]}\"  =~  🔒                    ]]\n\n  [[ ! \"${lines[0]}\"  =~  home:Example\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  3                     ]]\n  [[   \"${lines[0]}\"  =~  📂                    ]]\n  [[   \"${lines[0]}\"  =~  Example\\ Folder       ]]\n  [[   \"${#lines[@]}\" -eq 1                     ]]\n}\n\n# ls notebook:folder ###################################################################\n\n@test \"'ls notebook:folder/folder/folder' exits with 0 and prints the folder/folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"                   \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\"     \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"              \\\n      --title \"Two\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.txt\" \\\n      --content \"Content one.\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.txt\" \\\n      --content \"Content two.\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:Example\\ Folder/Sample\\ Folder/Demo\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                           ]]\n\n  [[   \"${#lines[@]}\" -eq 1                                           ]]\n\n  [[   \"${lines[0]}\"  =~  home:Example\\ Folder/Sample\\ Folder/3       ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder/Demo\\ Folder ]]\n  [[   \"${lines[0]}\"  =~  📂                                          ]]\n  [[ ! \"${lines[0]}\"  =~  Sample\\ Folder/Demo\\ Folder                 ]]\n  [[   \"${lines[0]}\"  =~  Demo\\ Folder                                ]]\n}\n\n@test \"'ls notebook:folder/folder' exits with 0 and prints the folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"          \\\n      --title \"Two\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n}\n\n  run \"${_NB}\" ls home:Example\\ Folder/Sample\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n\n  [[   \"${#lines[@]}\" -eq 1                               ]]\n\n  [[   \"${lines[0]}\"  =~  home:Example\\ Folder/3          ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  📂                              ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder                  ]]\n}\n\n@test \"'ls notebook:folder' exits with 0 and prints the folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/1.md\"          \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/2.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/3.bookmark.md\" \\\n      --content \"<https://example.test>\"        \\\n      --encrypt --password=password\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                     ]]\n\n  [[ ! \"${lines[0]}\"  =~  3\\.bookmark\\.md       ]]\n  [[ ! \"${lines[0]}\"  =~  🔖\\ 🔒                ]]\n  [[ ! \"${lines[1]}\"  =~  2\\.bookmark\\.md       ]]\n  [[ ! \"${lines[1]}\"  =~  🔖                    ]]\n  [[ ! \"${lines[2]}\"  =~  one                   ]]\n  [[ ! \"${lines[2]}\"  =~  🔖                    ]]\n  [[ ! \"${lines[2]}\"  =~  🔒                    ]]\n\n  [[ ! \"${lines[0]}\"  =~  home:Example\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  3                     ]]\n  [[   \"${lines[0]}\"  =~  📂                    ]]\n  [[   \"${lines[0]}\"  =~  Example\\ Folder       ]]\n  [[   \"${#lines[@]}\" -eq 1                     ]]\n}\n\n# ls notebook:<id>/ ###########################################################\n\n@test \"'ls notebook:folder/folder/<id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                                      \\\n      --encrypt --password=password\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:Example\\ Folder/Sample\\ Folder/1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ ----                                 ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[   \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ ----                                 ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n@test \"'ls notebook:folder/<id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n}\n\n  run \"${_NB}\" ls home:Example\\ Folder/1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[   \"${lines[7]}\"  =~ Demo                                 ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[8]}\"  =~ ----                                 ]]\n    [[   \"${lines[9]}\"  =~ add ]] || [[   \"${lines[10]}\" =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[   \"${lines[5]}\"  =~ Demo                                 ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[6]}\"  =~ ----                                 ]]\n    [[   \"${lines[7]}\"  =~ add ]] || [[   \"${lines[8]}\"  =~ add ]]\n  fi\n}\n\n@test \"'ls notebook:<id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[ ! \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n@test \"'notebook:<id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"example-1.md\"\n    \"${_NB}\" add \"example-2.md\"\n    \"${_NB}\" add \"example-3.md\"\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" home:4/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[ ! \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n# ls notebook:folder/ ###########################################################\n\n@test \"'ls notebook:folder/folder/folder/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                                      \\\n      --encrypt --password=password\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:Example\\ Folder/Sample\\ Folder/Demo\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ ----                                 ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[   \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ ----                                 ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n@test \"'ls notebook:folder/folder/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n}\n\n  run \"${_NB}\" ls home:Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[   \"${lines[7]}\"  =~ Demo                                 ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[8]}\"  =~ ----                                 ]]\n    [[   \"${lines[9]}\"  =~ add ]] || [[   \"${lines[10]}\" =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[   \"${lines[5]}\"  =~ Demo                                 ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[6]}\"  =~ ----                                 ]]\n    [[   \"${lines[7]}\"  =~ add ]] || [[   \"${lines[8]}\"  =~ add ]]\n  fi\n}\n\n@test \"'ls notebook:folder/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" ls home:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[ ! \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n@test \"'folder/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"example-1.md\"\n    \"${_NB}\" add \"example-2.md\"\n    \"${_NB}\" add \"example-3.md\"\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" home:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[ ! \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n# ls <id>/ ####################################################################\n\n@test \"'ls folder/folder/<id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                                      \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/Sample\\ Folder/1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ ----                                 ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[   \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ ----                                 ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n@test \"'ls folder/<id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[   \"${lines[7]}\"  =~ Demo                                 ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[8]}\"  =~ ----                                 ]]\n    [[   \"${lines[9]}\"  =~ add ]] || [[   \"${lines[10]}\" =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[   \"${lines[5]}\"  =~ Demo                                 ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[6]}\"  =~ ----                                 ]]\n    [[   \"${lines[7]}\"  =~ add ]] || [[   \"${lines[8]}\"  =~ add ]]\n  fi\n}\n\n@test \"'ls <id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" ls 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[ ! \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n@test \"'<id>/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"example-1.md\"\n    \"${_NB}\" add \"example-2.md\"\n    \"${_NB}\" add \"example-3.md\"\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" 4/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[ ! \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n# ls folder ###################################################################\n\n@test \"'ls folder/folder/folder' exits with 0 and prints the folder/folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"                   \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\"     \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"              \\\n      --title \"Two\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/one.txt\" \\\n      --content \"Content one.\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/two.txt\" \\\n      --content \"Content two.\"\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/Sample\\ Folder/Demo\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                           ]]\n\n  [[   \"${#lines[@]}\" -eq 1                                           ]]\n\n  [[   \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder/3            ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder/Demo\\ Folder ]]\n  [[   \"${lines[0]}\"  =~  📂                                          ]]\n  [[ ! \"${lines[0]}\"  =~  Sample\\ Folder/Demo\\ Folder                 ]]\n  [[   \"${lines[0]}\"  =~  Demo\\ Folder                                ]]\n}\n\n@test \"'ls folder/folder' exits with 0 and prints the folder/folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.md\"          \\\n      --title \"Two\"\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/Sample\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                               ]]\n\n  [[   \"${#lines[@]}\" -eq 1                               ]]\n\n  [[   \"${lines[0]}\"  =~  Example\\ Folder/3               ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  📂                              ]]\n  [[ ! \"${lines[0]}\"  =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[   \"${lines[0]}\"  =~  Sample\\ Folder                  ]]\n}\n\n@test \"'ls folder' exits with 0 and prints the folder list item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/1.md\"          \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/2.bookmark.md\" \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/3.bookmark.md\" \\\n      --content \"<https://example.test>\"        \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" ls Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                 ]]\n\n  [[ ! \"${lines[0]}\"  =~  3\\.bookmark\\.md   ]]\n  [[ ! \"${lines[0]}\"  =~  🔖\\ 🔒            ]]\n  [[ ! \"${lines[1]}\"  =~  2\\.bookmark\\.md   ]]\n  [[ ! \"${lines[1]}\"  =~  🔖                ]]\n  [[ ! \"${lines[2]}\"  =~  one               ]]\n  [[ ! \"${lines[2]}\"  =~  🔖                ]]\n  [[ ! \"${lines[2]}\"  =~  🔒                ]]\n\n  [[   \"${lines[0]}\"  =~  3                 ]]\n  [[   \"${lines[0]}\"  =~  📂                ]]\n  [[   \"${lines[0]}\"  =~  Example\\ Folder   ]]\n  [[   \"${#lines[@]}\" -eq 1                 ]]\n}\n\n# ls folder/ ##################################################################\n\n@test \"'ls folder/' exits with 0 and lists files in folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"            \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[ ! \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n@test \"'ls folder/folder/' exits with 0 and lists files in folder/folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/file 1.md\"  --content \"Example content one.\"\n    \"${_NB}\" add \"Example Folder/file 2.md\"  --content \"Example content two.\"\n    \"${_NB}\" add \"Example Folder/file 3.md\"  --content \"Example content three.\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"            \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"   \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\" \\\n      --content \"<https://example.test>\"                          \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[ ! \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[ ! \"${lines[4]}\"  =~ three                                ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[ ! \"${lines[5]}\"  =~ two                                  ]]\n    [[ ! \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[4]}\"  =~ Sample\\ Folder                       ]]\n    [[   \"${lines[5]}\"  =~ file\\ 3                              ]]\n    [[   \"${lines[6]}\"  =~ file\\ 2                              ]]\n    [[   \"${lines[7]}\"  =~ file\\ 1                              ]]\n    [[   \"${lines[8]}\"  =~ ----                                 ]]\n    [[   \"${lines[9]}\"  =~ add ]] || [[   \"${lines[10]}\" =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[ ! \"${lines[2]}\"  =~ three                                ]]\n    [[ ! \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[ ! \"${lines[3]}\"  =~ two                                  ]]\n    [[ ! \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[   \"${lines[3]}\"  =~ file\\ 3                              ]]\n    [[   \"${lines[4]}\"  =~ file\\ 2                              ]]\n    [[   \"${lines[5]}\"  =~ file\\ 1                              ]]\n    [[   \"${lines[6]}\"  =~ ----                                 ]]\n    [[   \"${lines[7]}\"  =~ add ]] || [[   \"${lines[8]}\"  =~ add ]]\n  fi\n\n  run \"${_NB}\" ls Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~ three                                ]]\n    [[   \"${lines[4]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[5]}\"  =~ two                                  ]]\n    [[   \"${lines[5]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[6]}\"  =~ one                                  ]]\n    [[ ! \"${lines[6]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[6]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ three                                ]]\n    [[   \"${lines[2]}\"  =~ 🔖\\ 🔒                               ]]\n    [[   \"${lines[3]}\"  =~ two                                  ]]\n    [[   \"${lines[3]}\"  =~ 🔖                                   ]]\n    [[   \"${lines[4]}\"  =~ one                                  ]]\n    [[ ! \"${lines[4]}\"  =~ 🔖                                   ]]\n    [[ ! \"${lines[4]}\"  =~ 🔒                                   ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n\n@test \"'ls folder/folder/folder/' exits with 0 and lists files in folder/folder/folder in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/file 1.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"Example Folder/file 2.md\" --content \"Example content two.\"\n    \"${_NB}\" add \"Example Folder/file 3.md\" --content \"Example content three.\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/one.md\"                        \\\n      --title \"one\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/two.bookmark.md\"               \\\n      --content \"<https://example.test>\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/three.bookmark.md\"             \\\n      --content \"<https://example.test>\"                                      \\\n      --encrypt --password=password\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Document One.md\"   \\\n      --content \"Example content one.\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Document Two.md\"   \\\n      --content \"Example content two.\"\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Document Three.md\" \\\n      --content \"Example content three.\"\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[ ! \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[ ! \"${lines[4]}\"  =~  three                               ]]\n    [[ ! \"${lines[4]}\"  =~  🔖\\ 🔒                              ]]\n    [[ ! \"${lines[5]}\"  =~  two                                 ]]\n    [[ ! \"${lines[5]}\"  =~  🔖                                  ]]\n    [[ ! \"${lines[6]}\"  =~  one                                 ]]\n    [[ ! \"${lines[6]}\"  =~  🔖                                  ]]\n    [[ ! \"${lines[6]}\"  =~  🔒                                  ]]\n    [[   \"${lines[4]}\"  =~  Sample\\ Folder                      ]]\n    [[   \"${lines[5]}\"  =~  file\\ 3                             ]]\n    [[   \"${lines[6]}\"  =~  file\\ 2                             ]]\n    [[   \"${lines[7]}\"  =~  file\\ 1                             ]]\n    [[   \"${lines[8]}\"  =~ ----                                 ]]\n    [[   \"${lines[9]}\"  =~ add ]] || [[   \"${lines[10]}\" =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[ ! \"${lines[2]}\"  =~  three                               ]]\n    [[ ! \"${lines[2]}\"  =~  🔖\\ 🔒                              ]]\n    [[ ! \"${lines[3]}\"  =~  two                                 ]]\n    [[ ! \"${lines[3]}\"  =~  🔖                                  ]]\n    [[ ! \"${lines[4]}\"  =~  one                                 ]]\n    [[ ! \"${lines[4]}\"  =~  🔖                                  ]]\n    [[ ! \"${lines[4]}\"  =~  🔒                                  ]]\n    [[   \"${lines[2]}\"  =~  Sample\\ Folder                      ]]\n    [[   \"${lines[3]}\"  =~  file\\ 3                             ]]\n    [[   \"${lines[4]}\"  =~  file\\ 2                             ]]\n    [[   \"${lines[5]}\"  =~  file\\ 1                             ]]\n    [[   \"${lines[6]}\"  =~ ----                                 ]]\n    [[   \"${lines[7]}\"  =~ add ]] || [[   \"${lines[0]}\"  =~ add ]]\n  fi\n\n  run \"${_NB}\" ls Example\\ Folder/Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[ ! \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~  Demo\\ Folder                        ]]\n    [[   \"${lines[5]}\"  =~  three                               ]]\n    [[   \"${lines[5]}\"  =~  🔖\\ 🔒                              ]]\n    [[   \"${lines[6]}\"  =~  two                                 ]]\n    [[   \"${lines[6]}\"  =~  🔖                                  ]]\n    [[   \"${lines[7]}\"  =~  one                                 ]]\n    [[ ! \"${lines[7]}\"  =~  🔖                                  ]]\n    [[ ! \"${lines[7]}\"  =~  🔒                                  ]]\n    [[   \"${lines[8]}\"  =~ ----                                 ]]\n    [[   \"${lines[9]}\"  =~ add ]] || [[   \"${lines[10]}\" =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~  Demo\\ Folder                        ]]\n    [[   \"${lines[3]}\"  =~  three                               ]]\n    [[   \"${lines[3]}\"  =~  🔖\\ 🔒                              ]]\n    [[   \"${lines[4]}\"  =~  two                                 ]]\n    [[   \"${lines[4]}\"  =~  🔖                                  ]]\n    [[   \"${lines[5]}\"  =~  one                                 ]]\n    [[ ! \"${lines[5]}\"  =~  🔖                                  ]]\n    [[ ! \"${lines[5]}\"  =~  🔒                                  ]]\n    [[   \"${lines[6]}\"  =~ ----                                 ]]\n    [[   \"${lines[7]}\"  =~ add ]] || [[   \"${lines[8]}\"  =~ add ]]\n  fi\n\n  run \"${_NB}\" ls Example\\ Folder/Sample\\ Folder/Demo\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  if ((_FOLDER_HEADER_ENABLED))\n  then\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n    [[   \"${lines[2]}\"  =~ ^Example\\ Folder                     ]]\n    [[ ! \"${lines[2]}\"  =~ ^📂\\ Example\\ Folder                 ]]\n    [[   \"${lines[2]}\"  =~ Sample\\ Folder                       ]]\n    [[   \"${lines[2]}\"  =~ Demo\\ Folder                         ]]\n    [[   \"${lines[3]}\"  =~ ----                                 ]]\n    [[   \"${lines[4]}\"  =~  Document\\ Three.md                  ]]\n    [[   \"${lines[5]}\"  =~  Document\\ Two.md                    ]]\n    [[   \"${lines[6]}\"  =~  Document\\ One.md                    ]]\n    [[   \"${lines[7]}\"  =~ ----                                 ]]\n    [[   \"${lines[8]}\"  =~ add ]] || [[   \"${lines[9]}\"  =~ add ]]\n  else\n    [[   \"${status}\"    -eq 0                                   ]]\n\n    [[   \"${lines[0]}\"  =~ home                                 ]]\n    [[   \"${lines[1]}\"  =~ -----                                ]]\n\n    [[   \"${lines[2]}\"  =~  Document\\ Three.md                  ]]\n    [[   \"${lines[3]}\"  =~  Document\\ Two.md                    ]]\n    [[   \"${lines[4]}\"  =~  Document\\ One.md                    ]]\n    [[   \"${lines[5]}\"  =~ ----                                 ]]\n    [[   \"${lines[6]}\"  =~ add ]] || [[   \"${lines[7]}\"  =~ add ]]\n  fi\n}\n"
  },
  {
    "path": "test/folders-move.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# shortcut alias ##############################################################\n\n@test \"'mv <folder>/<id> <notebook>:<folder>/' (shortcut) moves file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n\n    \"${_NB}\" add folder \"Sample Notebook:Sample Folder\"\n\n    [[   -f \"${NB_DIR}/home/Example Folder/Example File.md\"           ]]\n    [[   -d \"${NB_DIR}/Sample Notebook/Sample Folder\"                 ]]\n    [[ ! -e \"${NB_DIR}/Sample Notebook/Sample Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" mv \"Example Folder/1\" \"Sample Notebook:Sample Folder/\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.md\"             ]]\n  [[   -f \"${NB_DIR}/Sample Notebook/Sample Folder/Example File.md\"   ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete'\n\n  cd \"${NB_DIR}/Sample Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  \\\nMoving:\\ \\ \\ .*\\[.*Example\\ Folder/1.*\\].*\\ .*Example\\ File.md      ]]\n  [[ \"${lines[1]}\"  =~  \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Sample\\ Notebook:Sample\\ Folder/Example\\ File.md ]]\n  [[ \"${lines[2]}\"  =~  \\\nMoved\\ to:\\ .*Sample\\ Notebook:Sample\\ Folder/Example\\ File.md      ]]\n}\n\n# edge cases ##################################################################\n\n@test \"'move <notebook>:<id> <notebook>:<folder-id>/' moves file.\" {\n  {\n    \"${_NB}\" init\n\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" add folder \"Sample Folder\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" move       \\\n    \"Example Notebook:1\"  \\\n    \"Example Notebook:2/\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/Example Notebook/Example File.md\"                ]]\n  [[ ! -e \"${NB_DIR}/Example Notebook/2/Example File.md\"              ]]\n  [[   -f \"${NB_DIR}/Example Notebook/Sample Folder/Example File.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  Moving:\\ \\ \\ .*\\[.*1.*\\].*\\ .*Example\\ File.md  ]]\n  [[ \"${lines[1]}\"  =~  \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Example\\ Notebook:Sample\\ Folder/Example\\ File.md    ]]\n  [[ \"${lines[2]}\"  =~  \\\nMoved\\ to:\\ .*Example\\ Notebook:Sample\\ Folder/Example\\ File.md         ]]\n}\n\n@test \"'move <notebook-1>:<id> <notebook-2>:<folder>/' with <notebook-1> as current moves file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" move \"home:1\" \"Example Notebook:Sample Folder/\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example File.md\"                            ]]\n  [[   -f \"${NB_DIR}/Example Notebook/Sample Folder/Example File.md\"  ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete'\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  Moving:\\ \\ \\ .*\\[.*1.*\\].*\\ .*Example\\ File.md  ]]\n  [[ \"${lines[1]}\"  =~  \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Example\\ Notebook:Sample\\ Folder/Example\\ File.md    ]]\n  [[ \"${lines[2]}\"  =~  \\\nMoved\\ to:\\ .*Example\\ Notebook:Sample\\ Folder/Example\\ File.md         ]]\n}\n\n@test \"'move <notebook-1>:<filename> <notebook-2>:<folder>/' with <notebook-1> as current moves file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" move \"home:Example File.md\" \"Example Notebook:Sample Folder/\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example File.md\"                            ]]\n  [[   -f \"${NB_DIR}/Example Notebook/Sample Folder/Example File.md\"  ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete'\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  Moving:\\ \\ \\ .*\\[.*1.*\\].*\\ .*Example\\ File.md  ]]\n  [[ \"${lines[1]}\"  =~  \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Example\\ Notebook:Sample\\ Folder/Example\\ File.md    ]]\n  [[ \"${lines[2]}\"  =~  \\\nMoved\\ to:\\ .*Example\\ Notebook:Sample\\ Folder/Example\\ File.md         ]]\n}\n\n@test \"'move <notebook-1>:<filename> <notebook-2>:<folder>/' without either as current moves file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n  }\n\n  run \"${_NB}\" move \"home:Example File.md\" \"Example Notebook:Sample Folder/\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example File.md\"                            ]]\n  [[   -f \"${NB_DIR}/Example Notebook/Sample Folder/Example File.md\"  ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete'\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  Moving:\\ \\ \\ .*\\[.*1.*\\].*\\ .*home:Example\\ File.md ]]\n  [[ \"${lines[1]}\"  =~  \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Example\\ Notebook:Sample\\ Folder/Example\\ File.md        ]]\n  [[ \"${lines[2]}\"  =~  \\\nMoved\\ to:\\ .*Example\\ Notebook:Sample\\ Folder/Example\\ File.md             ]]\n}\n\n# only extension ##############################################################\n\n@test \"'move .<extension>' with nested note changes the file extension while retaining the name and folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\" \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" move Example\\ Folder/Sample\\ Folder/1 .js <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                                                      ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\"  ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.js\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ Folder/Sample\\ Folder/Example\\ File\\.md.* ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Example\\ Folder/Sample\\ Folder/Example\\ File\\.js.*          ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*Example\\ Folder/Sample\\ Folder/Example\\ File\\.js.*  ]]\n}\n\n# --to-note ###############################################################\n\n@test \"'move --to-note' with nested <filename> argument renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.bookmark.md\" \\\n      --content   \"Example content.\"\n\n    [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  }\n\n  run \"${_NB}\" rename                                       \\\n    \"Example Folder/Sample Folder/Example File.bookmark.md\" \\\n    --to-note <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\"    -eq 0                   ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\"          ]]\n\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  declare _item_id=\n  _item_id=\"$(\n    \"${_NB}\" index get_id                   \\\n      \"Example File.md\"                     \\\n      \"${NB_DIR}/home/Example Folder/Sample Folder\"\n  )\"\n\n  [[ \"${_item_id}\"  ==  \"1\"                 ]]\n\n  # Prints output:\n\n  [[ \"${output}\"    =~  Moved\\ to                                       ]]\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/Example\\ File.md ]]\n}\n\n# --to-bookmark ###############################################################\n\n@test \"'move --to-bookmark' with nested <filename> argument renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"      \\\n      --content   \"Example content.\"\n\n    [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" rename \"Example Folder/Sample Folder/Example File.md\"  \\\n    --to-bookmark <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\"    -eq 0                   ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\"          ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  declare _item_id=\n  _item_id=\"$(\n    \"${_NB}\" index get_id                   \\\n      \"Example File.bookmark.md\"            \\\n      \"${NB_DIR}/home/Example Folder/Sample Folder\"\n  )\"\n\n  [[ \"${_item_id}\"  ==  \"1\"                 ]]\n\n  # Prints output:\n\n  [[ \"${output}\"    =~  Moved\\ to                                                 ]]\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/Example\\ File.bookmark.md  ]]\n}\n\n# --reset #####################################################################\n\n@test \"'move --reset' with nested <filename> argument renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"      \\\n      --content   \"Example content.\"\n\n    [[ -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" rename \"Example Folder/Sample Folder/Example File.md\"  \\\n    --reset <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\"    -eq 0                   ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/Example Folder/Sample Folder/\"))\n  printf \"\\${_files[0]}: '%s'\\\\n\" \"${_files[0]}\"\n\n  [[ \"${_files[0]}\" =~ [A-Za-z0-9]+.md      ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  declare _item_id=\n  _item_id=\"$(\n    \"${_NB}\" index get_id \\\n      \"${_files[0]}\"      \\\n      \"${NB_DIR}/home/Example Folder/Sample Folder\"\n  )\"\n\n  [[ \"${_item_id}\"  ==  \"1\"                 ]]\n\n  # Prints output:\n\n  [[ \"${output}\"    =~  Moved\\ to                                       ]]\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/[A-Za-z0-9]+.md  ]]\n}\n\n# --to-title ##################################################################\n\n@test \"'move --to-title' with title and nested note renames to title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Example File.md\"  \\\n      --content   \"Example content.\"                              \\\n      --title                                                     \\\n\"Example Title: A*string•with/a\\\\bunch|of?invalid<filename\\\"characters>\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\"     ]]\n\n    declare _target_filename=\"example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md\"\n  }\n\n  run \"${_NB}\" move 1/1/1 --to-title <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                        ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\"      ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/Sample Folder/${_target_filename}\"  ]]\n\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ File\\.md.*\\ \\\"Example\\ Title:\\     ]]\n  [[ \"${lines[0]}\" =~ \\\nTitle:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"  ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*${_target_filename}            ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*${_target_filename}.*  ]]\n  [[ \"${lines[2]}\" =~ \\\n \\\"Example\\ Title:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"  ]]\n}\n\n@test \"'move --to-title' with title and root-level note renames to title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"   \\\n      --content   \"Example content.\"  \\\n      --title                         \\\n\"Example Title: A*string•with/a\\\\bunch|of?invalid<filename\\\"characters>\"\n  }\n\n  run \"${_NB}\" move 1 --to-title <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                            ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"     ]]\n  [[    -f \\\n\"${NB_DIR}/home/example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md\"    ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ File\\.md.*\\ \\\"Example\\ Title:\\     ]]\n  [[ \"${lines[0]}\" =~ \\\nTitle:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"  ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md  ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md.*  ]]\n  [[ \"${lines[2]}\" =~ \\\n \\\"Example\\ Title:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"  ]]\n}\n\n# intermediate folders ########################################################\n\n@test \"'move notebook:folder/<id>' moves across notebooks and creates intermediate folders.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Test Folder/Sample File.bookmark.md\"  \\\n      --title   \"Sample Title\"                          \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n\n    [[   -d \"${NB_DIR}/home/Test Folder\"                                              ]]\n    [[   -f \"${NB_DIR}/home/Test Folder/Sample File.bookmark.md\"                      ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                             ]]\n    [[ ! -e \"${NB_DIR}/one/Example Folder\"                                            ]]\n    [[ ! -e \"${NB_DIR}/one/Example Folder/Sample Folder\"                              ]]\n    [[ ! -e \"${NB_DIR}/one/Example Folder/Sample Folder/Demo Folder\"                  ]]\n    [[ ! -e \"${NB_DIR}/one/Example Folder/Sample Folder/Demo Folder/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move                                                 \\\n    \"Test Folder/1\"                                                 \\\n    \"one:Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -d \"${NB_DIR}/home/Test Folder\"                                              ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample File.bookmark.md\"                   ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                             ]]\n  [[   -d \"${NB_DIR}/one/Example Folder\"                                            ]]\n  [[   -d \"${NB_DIR}/one/Example Folder/Sample Folder\"                              ]]\n  [[   -d \"${NB_DIR}/one/Example Folder/Sample Folder/Demo Folder\"                  ]]\n  [[   -f \"${NB_DIR}/one/Example Folder/Sample Folder/Demo Folder/Example File.md\"  ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete:'\n\n  cd \"${NB_DIR}/one\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                                        ]]\n  [[ \"${output}\" =~ one:Example\\ Folder/Sample\\ Folder/Demo\\ Folder/1                 ]]\n  [[ \"${output}\" =~ one:Example\\ Folder/Sample\\ Folder/Demo\\ Folder/Example\\ File.md  ]]\n}\n\n@test \"'move folder/<id>' moves and creates intermediate folders.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample File.bookmark.md\"   \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n\n    [[   -d \"${NB_DIR}/home/Example Folder\"                                           ]]\n    [[   -f \"${NB_DIR}/home/Example Folder/Sample File.bookmark.md\"                   ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder\"                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"                 ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" move                                             \\\n    \"Example Folder/1\"                                          \\\n    \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -d \"${NB_DIR}/home/Example Folder\"                                           ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample File.bookmark.md\"                   ]]\n  [[   -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                             ]]\n  [[   -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"                 ]]\n  [[   -f \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Example File.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                                    ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Demo\\ Folder/1                 ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Demo\\ Folder/Example\\ File.md  ]]\n}\n\n# error handling ##############################################################\n\n@test \"'move folder/<filename>' with invalid filename returns with error and message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move             \\\n    \"Example Folder/not-valid\"  \\\n    \"Example Folder/example.md\" \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1 ]]\n\n  # Does not move file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Not\\ found:               ]]\n  [[ \"${output}\" =~ Example\\ Folder/not-valid ]]\n}\n\n# into folder/ ################################################################\n\n@test \"'move <notebook>:<selector> <notebook>:folder/' with existing folder moves item into folder.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"  \\\n      --title   \"Sample Title\"              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                ]]\n    [[   -d \"${NB_DIR}/home/Example Folder\"                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" move           \\\n    \"Sample File.bookmark.md\" \\\n    \"Example Folder/\"         \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Sample File.bookmark.md\"                ]]\n  [[   -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                         ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ File.bookmark.md  ]]\n}\n\n@test \"'move <selector> folder/' creates folder and moves item into folder.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"  \\\n      --title   \"Sample Title\"              \\\n      --content \"<https://1.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                ]]\n    [[ ! -d \"${NB_DIR}/home/Example Folder\"                         ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" move           \\\n    \"Sample File.bookmark.md\" \\\n    \"Example Folder/\"         \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Sample File.bookmark.md\"                ]]\n  [[   -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                         ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ File.bookmark.md  ]]\n}\n\n@test \"'move <notebook>:<selector> <notebook>:folder/' moves item into folder.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"  \\\n      --title   \"Sample Title\"              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    \"${_NB}\" notebooks add \"two\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                ]]\n    [[ ! -d \"${NB_DIR}/home/Example Folder\"                         ]]\n    [[ ! -d \"${NB_DIR}/two/Example Folder\"                          ]]\n    [[ ! -e \"${NB_DIR}/two/Example Folder/Sample File.bookmark.md\"  ]]\n  }\n\n  run \"${_NB}\" move                 \\\n    \"home:Sample File.bookmark.md\"  \\\n    \"two:Example Folder/\"           \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Sample File.bookmark.md\"                ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"                         ]]\n  [[   -d \"${NB_DIR}/two/Example Folder\"                          ]]\n  [[   -e \"${NB_DIR}/two/Example Folder/Sample File.bookmark.md\"  ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete:'\n\n  cd \"${NB_DIR}/two\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                    ]]\n  [[ \"${output}\" =~ two:Example\\ Folder/1                         ]]\n  [[ \"${output}\" =~ two:Example\\ Folder/Sample\\ File.bookmark.md  ]]\n}\n\n# <filename> ##################################################################\n\n@test \"'move notebook:folder/folder/<filename>' moves across notebooks and levels without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n    [[ ! -e \"${NB_DIR}/one/example.md\"                                              ]]\n    [[ ! -e \"${NB_DIR}/one/Example Folder/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/two/example.md\"                                              ]]\n    [[ ! -e \"${NB_DIR}/two/Example Folder\"                                          ]]\n    [[ ! -e \"${NB_DIR}/two/Example Folder/example.md\"                               ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks add \"two\"\n\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" move                                               \\\n    \"home:Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n    \"two:Example Folder/example.md\"                               \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete:'\n\n  cd \"${NB_DIR}/two\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n  [[ ! -e \"${NB_DIR}/one/example.md\"                                              ]]\n  [[ ! -e \"${NB_DIR}/one/Example Folder/example.md\"                               ]]\n  [[ ! -e \"${NB_DIR}/two/example.md\"                                              ]]\n  [[   -e \"${NB_DIR}/two/Example Folder/example.md\"                               ]]\n  [[   -e \"${NB_DIR}/two/Example Folder/.index\"                                   ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                      ]]\n  [[ \"${output}\" =~ two:Example\\ Folder/1           ]]\n  [[ \"${output}\" =~ two:Example\\ Folder/example.md  ]]\n}\n\n@test \"'move folder/<filename>' moves properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                           \\\n    \"Example Folder/Example File.bookmark.md\" \\\n    \"Example Folder/example.md\"               \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/1           ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'move folder/folder/<filename>' moves properly on same level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                                         \\\n    \"Example Folder/Sample Folder/Example File.bookmark.md\" \\\n    \"Example Folder/Sample Folder/example.md\"               \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                                ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example.md                 ]]\n}\n\n@test \"'move folder/folder/<filename>' moves properly up one level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n  }\n\n  run \"${_NB}\" move                                         \\\n    \"Example Folder/Sample Folder/Example File.bookmark.md\" \\\n    \"Example Folder/example.md\"                             \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/2           ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'move notebook:folder/<filename>' moves properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                                 \\\n    \"home:Example Folder/Example File.bookmark.md\"  \\\n    \"home:Example Folder/example.md\"                \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1          ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/example.md ]]\n}\n\n@test \"'move notebook:folder/folder/<filename>' moves properly on same level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                                               \\\n    \"home:Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n    \"home:Example Folder/Sample Folder/example.md\"                \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1           ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/example.md  ]]\n}\n\n@test \"'move notebook:folder/folder/<filename>' moves properly up one level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" move                                               \\\n    \"home:Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n    \"home:Example Folder/example.md\"                              \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/2          ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/example.md ]]\n}\n\n# <id> ########################################################################\n\n@test \"'move notebook:folder/folder/<id>' moves across notebooks and levels without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n    [[ ! -e \"${NB_DIR}/one/example.md\"                                              ]]\n    [[ ! -e \"${NB_DIR}/one/Example Folder/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/two/example.md\"                                              ]]\n    [[ ! -e \"${NB_DIR}/two/Example Folder/example.md\"                               ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks add \"two\"\n\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" move                       \\\n    \"home:Example Folder/Sample Folder/1\" \\\n    \"two:Example Folder/example.md\"       \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete:'\n\n  cd \"${NB_DIR}/two\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n  [[ ! -e \"${NB_DIR}/one/example.md\"                                              ]]\n  [[ ! -e \"${NB_DIR}/one/Example Folder/example.md\"                               ]]\n  [[ ! -e \"${NB_DIR}/two/example.md\"                                              ]]\n  [[   -e \"${NB_DIR}/two/Example Folder/example.md\"                               ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                      ]]\n  [[ \"${output}\" =~ two:Example\\ Folder/1           ]]\n  [[ \"${output}\" =~ two:Example\\ Folder/example.md  ]]\n}\n\n@test \"'move folder/<id>' moves properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move             \\\n    \"Example Folder/1\"          \\\n    \"Example Folder/example.md\" \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/1           ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'move folder/folder/<id>' moves properly on same level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                           \\\n    \"Example Folder/Sample Folder/1\"          \\\n    \"Example Folder/Sample Folder/example.md\" \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                                ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example.md                 ]]\n}\n\n@test \"'move folder/folder/<id>' moves properly up one level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n  }\n\n  run \"${_NB}\" move                   \\\n    \"Example Folder/Sample Folder/1\"  \\\n    \"Example Folder/example.md\"       \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/2           ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'move notebook:folder/<id>' moves properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                   \\\n    \"home:Example Folder/1\"           \\\n    \"home:Example Folder/example.md\"  \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1          ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/example.md ]]\n}\n\n@test \"'move notebook:folder/folder/<id>' moves properly on same level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                                 \\\n    \"home:Example Folder/Sample Folder/1\"           \\\n    \"home:Example Folder/Sample Folder/example.md\"  \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1           ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/example.md  ]]\n}\n\n@test \"'move notebook:folder/folder/<id>' moves properly up one level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" move                       \\\n    \"home:Example Folder/Sample Folder/1\" \\\n    \"home:Example Folder/example.md\"      \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/2          ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/example.md ]]\n}\n\n# <title> #####################################################################\n\n@test \"'move notebook:folder/folder/<title>' moves across notebooks and levels without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n    [[ ! -e \"${NB_DIR}/one/example.md\"                                              ]]\n    [[ ! -e \"${NB_DIR}/one/Example Folder/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/two/example.md\"                                              ]]\n    [[ ! -e \"${NB_DIR}/two/Example Folder/example.md\"                               ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks add \"two\"\n\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" move                                   \\\n    \"home:Example Folder/Sample Folder/Example Title\" \\\n    \"two:Example Folder/example.md\"                   \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete:'\n\n  cd \"${NB_DIR}/two\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n  [[ ! -e \"${NB_DIR}/one/example.md\"                                              ]]\n  [[ ! -e \"${NB_DIR}/one/Example Folder/example.md\"                               ]]\n  [[ ! -e \"${NB_DIR}/two/example.md\"                                              ]]\n  [[   -e \"${NB_DIR}/two/Example Folder/example.md\"                               ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/1           ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'move folder/<title>' moves properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                 \\\n    \"Example Folder/Example Title\"  \\\n    \"Example Folder/example.md\"     \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/1           ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'move folder/folder/<title>' moves properly on same level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                               \\\n    \"Example Folder/Sample Folder/Example Title\"  \\\n    \"Example Folder/Sample Folder/example.md\"     \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                                ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                          ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/example.md                 ]]\n}\n\n@test \"'move folder/folder/<title>' moves properly up one level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n  }\n\n  run \"${_NB}\" move                               \\\n    \"Example Folder/Sample Folder/Example Title\"  \\\n    \"Example Folder/example.md\"                   \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                  ]]\n  [[ \"${output}\" =~ Example\\ Folder/2           ]]\n  [[ \"${output}\" =~ Example\\ Folder/example.md  ]]\n}\n\n@test \"'move notebook:folder/<title>' moves properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                  \\\n      --title   \"Sample Title\"                              \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                             \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                     \\\n    \"home:Example Folder/Example Title\" \\\n    \"home:Example Folder/example.md\"    \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                  ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                               ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1          ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/example.md ]]\n}\n\n@test \"'move notebook:folder/folder/<title>' moves properly on same level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n  }\n\n  run \"${_NB}\" move                                   \\\n    \"home:Example Folder/Sample Folder/Example Title\" \\\n    \"home:Example Folder/Sample Folder/example.md\"    \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/example.md\"                ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1           ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/example.md  ]]\n}\n\n@test \"'move notebook:folder/folder/<title>' moves properly up one level without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.bookmark.md\"                                \\\n      --title   \"Sample Title\"                                            \\\n      --content \"<https://1.example.test>\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.bookmark.md\"  \\\n      --title   \"Example Title\"                                           \\\n      --content \"<https://2.example.test>\"\n\n    [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n    [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n    [[ ! -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" move                                   \\\n    \"home:Example Folder/Sample Folder/Example Title\" \\\n    \"home:Example Folder/example.md\"                  \\\n    --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move:'\n\n  # Moves file:\n\n  [[   -e \"${NB_DIR}/home/Sample File.bookmark.md\"                                ]]\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.bookmark.md\"  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\"                                             ]]\n  [[   -e \"${NB_DIR}/home/Example Folder/example.md\"                              ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to:                      ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/2          ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/example.md ]]\n}\n"
  },
  {
    "path": "test/folders-search.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_folders_and_files() {\n  local _title_prefix=\n\n  if [[ \"${1:-}\" == \"--local\" ]]\n  then\n    _title_prefix=\"Local / \"\n  fi\n\n  # notebook root\n\n  \"${_NB}\" add  \"File One.md\"                 \\\n    --title     \"${_title_prefix}Root One\"    \\\n    --content   \"example phrase\"\n\n  \"${_NB}\" add  \"File Two.md\"                 \\\n    --title     \"${_title_prefix}Root Two\"    \\\n    --content   \"sample phrase\"\n\n  \"${_NB}\" add  \"File Three.md\"               \\\n    --title     \"${_title_prefix}Root Three\"  \\\n    --content   \"example phrase\"\n\n  \"${_NB}\" add  \"File Four.md\"                \\\n    --title     \"${_title_prefix}Root Four\"   \\\n    --content   \"demo phrase\"\n\n  # Example Folder /\n\n  \"${_NB}\" add  \"Example Folder/File One.md\"              \\\n    --title     \"${_title_prefix}Example Folder / One\"    \\\n    --content   \"demo phrase\"\n\n  \"${_NB}\" add  \"Example Folder/File Two.md\"              \\\n    --title     \"${_title_prefix}Example Folder / Two\"    \\\n    --content   \"example phrase\"\n\n  \"${_NB}\" add  \"Example Folder/File Three.md\"            \\\n    --title     \"${_title_prefix}Example Folder / Three\"  \\\n    --content   \"sample phrase\"\n\n  \"${_NB}\" add  \"Example Folder/File Four.md\"             \\\n    --title     \"${_title_prefix}Example Folder / Four\"   \\\n    --content   \"example phrase\"\n\n  # Example Folder / Sample Folder /\n\n  \"${_NB}\" add  \"Example Folder/Sample Folder/File One.md\"                \\\n    --title     \"${_title_prefix}Example Folder / Sample Folder / One\"    \\\n    --content   \"example phrase\"\n\n  \"${_NB}\" add  \"Example Folder/Sample Folder/File Two.md\"                \\\n    --title     \"${_title_prefix}Example Folder / Sample Folder / Two\"    \\\n    --content   \"demo phrase\"\n\n  \"${_NB}\" add  \"Example Folder/Sample Folder/File Three.md\"              \\\n    --title     \"${_title_prefix}Example Folder / Sample Folder / Three\"  \\\n    --content   \"example phrase\"\n\n  \"${_NB}\" add  \"Example Folder/Sample Folder/File Four.md\"               \\\n    --title     \"${_title_prefix}Example Folder / Sample Folder / Four\"   \\\n    --content   \"sample phrase\"\n}\n\n# <path> selectors ############################################################\n\n@test \"'search /path/to/<filename>' (no slash, query) searches for <query> in <filename>.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"${NB_DIR}/home/File One.md\" \"example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                       ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Root\\ One  ]]\n  [[ \"${lines[1]}\"  =~  ---                     ]]\n  [[ \"${lines[2]}\"  =~  3.*:.*example.*\\ phrase ]]\n}\n\n@test \"'search /path/to/<notebook>' (no slash, query) searches for <query> in <notebook> recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"${NB_DIR}/home\" \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                       ]]\n  [[ \"${#lines[@]}\" -eq 37                      ]]\n\n  [[ \"${output}\"    =~  .*[.*1.*].*\\ Root\\ One  ]]\n  [[ \"${output}\"    =~  ---                     ]]\n  [[ \"${output}\"    =~  3.*:.*example.*\\ phrase ]]\n\n  [[ \"${output}\"    =~  \\\n.*[.*Example\\ Folder/Sample\\ Folder/4.*].*\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Four ]]\n  [[ \"${output}\"    =~  ---                     ]]\n  [[ \"${output}\"    =~  1.*:.*#\\ .*Example.*\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Four        ]]\n}\n\n@test \"'search /path/to/<notebook>/' (slash, query) searches for <query> in <notebook> recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"${NB_DIR}/home/\" \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                       ]]\n  [[ \"${#lines[@]}\" -eq 37                      ]]\n\n  [[ \"${output}\"    =~  .*[.*1.*].*\\ Root\\ One  ]]\n  [[ \"${output}\"    =~  ---                     ]]\n  [[ \"${output}\"    =~  3.*:.*example.*\\ phrase ]]\n\n  [[ \"${output}\"    =~  \\\n.*[.*Example\\ Folder/Sample\\ Folder/4.*].*\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Four ]]\n  [[ \"${output}\"    =~  ---                     ]]\n  [[ \"${output}\"    =~  1.*:.*#\\ .*Example.*\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Four        ]]\n}\n\n@test \"'search /path/to/<folder>' (no slash, query) searches for <query> in <folder> recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"${NB_DIR}/home/Example Folder\" \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"    -eq 0                       ]]\n  [[    \"${#lines[@]}\" -eq 28                      ]]\n\n  [[ !  \"${output}\"    =~  .*[.*1.*].*\\ Root\\ One  ]]\n\n  [[    \"${output}\"    =~  \\\n.*[.*Example\\ Folder/Sample\\ Folder/4.*].*\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Four ]]\n  [[    \"${output}\"    =~  ---                     ]]\n  [[    \"${output}\"    =~  1.*:.*#\\ .*Example.*\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Four     ]]\n}\n\n@test \"'search /path/to/<folder>/' (slash, query) searches for <query> in <folder> recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"${NB_DIR}/home/Example Folder/\" \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"    -eq 0                        ]]\n  [[    \"${#lines[@]}\" -eq 28                       ]]\n\n  [[ !  \"${output}\"    =~  .*[.*1.*].*\\ Root\\ One   ]]\n\n  [[    \"${output}\"    =~  \\\n.*[.*Example\\ Folder/Sample\\ Folder/4.*].*\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Four ]]\n  [[    \"${output}\"    =~  ---                      ]]\n  [[    \"${output}\"    =~  1.*:.*#\\ .*Example.*\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Four     ]]\n}\n\n# <filename> and <folder> selectors ###########################################\n\n@test \"'search <filename>' (no slash, no query) searches for <filename> in current notebook recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${output}\"    =~  1.*File\\ One.md.*\\ ·\\ Root\\ One   ]]\n  [[ \"${output}\"    =~  ----------------                  ]]\n  [[ \"${lines[2]}\"  =~  Filename\\ Match:\\ .*File\\ One.md  ]]\n\n  [[ \"${output}\"    =~  \\\nExample\\ Folder/1.*File\\ One.md.*\\ ·\\ Example\\ Folder\\ /\\ One ]]\n  [[ \"${output}\"    =~  ----------------                  ]]\n  [[ \"${lines[5]}\"  =~  Filename\\ Match:\\ .*File\\ One.md  ]]\n\n  [[ \"${output}\"    =~  \\\nExample\\ Folder/1.*File\\ One.md.*\\ ·\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One ]]\n  [[ \"${output}\"    =~  ----------------                  ]]\n  [[ \"${lines[8]}\"  =~  Filename\\ Match:\\ .*File\\ One.md  ]]\n}\n\n@test \"'search <filename>/' (slash, no query) searches for <filename> in current notebook recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search File\\ One.md/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${output}\"    =~  1.*File\\ One.md.*\\ ·\\ Root\\ One   ]]\n  [[ \"${output}\"    =~  ----------------                  ]]\n  [[ \"${lines[2]}\"  =~  Filename\\ Match:\\ .*File\\ One.md  ]]\n\n  [[ \"${output}\"    =~  \\\nExample\\ Folder/1.*File\\ One.md.*\\ ·\\ Example\\ Folder\\ /\\ One ]]\n  [[ \"${output}\"    =~  ----------------                  ]]\n  [[ \"${lines[5]}\"  =~  Filename\\ Match:\\ .*File\\ One.md  ]]\n\n  [[ \"${output}\"    =~  \\\nExample\\ Folder/1.*File\\ One.md.*\\ ·\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One ]]\n  [[ \"${output}\"    =~  ----------------                  ]]\n  [[ \"${lines[8]}\"  =~  Filename\\ Match:\\ .*File\\ One.md  ]]\n}\n\n@test \"'search <folder>' (no slash, no query) searches for <folder> in current notebook recursively with matching content.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                          ]]\n\n  [[ !  \"${output}\"    =~  [^/]1[^/]*One                              ]]\n\n  [[    \"${output}\"    =~  Example\\ Folder/5.*\\ 📂\\ .*Sample\\ Folder  ]]\n  [[    \"${output}\"    =~  ------------------------------------       ]]\n  [[    \"${output}\"    =~  Folder\\ Name\\ Match:\\ .*Sample\\ Folder     ]]\n\n  [[    \"${output}\"    =~ \\\n          Example\\ Folder/Sample\\ Folder/1.*Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One   ]]\n  [[    \"${output}\"    =~ \\\n          Example\\ Folder/Sample\\ Folder/2.*Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Two   ]]\n  [[    \"${output}\"    =~ \\\n          Example\\ Folder/Sample\\ Folder/3.*Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Three ]]\n  [[    \"${output}\"    =~ \\\n          Example\\ Folder/Sample\\ Folder/4.*Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Four  ]]\n}\n\n@test \"'search <folder>' (no slash, no query) searches for <folder> in current notebook recursively with only matching folder names.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" rename                   \\\n      \"Example Folder/Sample Folder\"  \\\n      \"Example Folder/Demo Folder\"    \\\n      --force\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Demo Folder\" ]]\n  }\n\n  run \"${_NB}\" search \"Demo Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                          ]]\n\n  [[    \"${#lines[@]}\" -eq 3                                          ]]\n\n  [[    \"${output}\"    =~  Example\\ Folder/5.*\\ 📂\\ .*Demo\\ Folder    ]]\n  [[    \"${output}\"    =~  [^-]---------------------------------[^-]  ]]\n  [[    \"${output}\"    =~  Folder\\ Name\\ Match:\\ .*Demo\\ Folder       ]]\n}\n\n@test \"'search <folder>/' (slash, no query) with matching folder name returns 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq  1           ]]\n\n  [[    \"${lines[0]}\"  =~   Usage.*:    ]]\n  [[    \"${lines[1]}\"  =~   nb\\ search  ]]\n}\n\n@test \"'search <folder>/' (slash, no query) with no match searches for nested <folder> in current notebook recursively with only matching folder names.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" rename                   \\\n      \"Example Folder/Sample Folder\"  \\\n      \"Example Folder/Demo Folder\"    \\\n      --force\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Demo Folder\" ]]\n  }\n\n  run \"${_NB}\" search Demo\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                          ]]\n\n  [[    \"${#lines[@]}\" -eq 3                                          ]]\n\n  [[    \"${output}\"    =~  Example\\ Folder/5.*\\ 📂\\ .*Demo\\ Folder    ]]\n  [[    \"${output}\"    =~  [^-]---------------------------------[^-]  ]]\n  [[    \"${output}\"    =~  Folder\\ Name\\ Match:\\ .*Demo\\ Folder       ]]\n}\n\n@test \"'search <folder-id>/' (slash, no query) with matching folder returns 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search 5/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1            ]]\n\n  [[    \"${lines[0]}\"    =~  Usage.*:   ]]\n  [[    \"${lines[1]}\"    =~  nb\\ search ]]\n}\n\n@test \"'search <folder-id>/' (slash, no query) with no matching folder searches for <folder-id> recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" edit \"Example Folder/File Three.md\"              \\\n      --content   \"12345\"\n    \"${_NB}\" edit \"Example Folder/Sample Folder/File Two.md\"  \\\n      --content   \"12345\"\n  }\n\n  run \"${_NB}\" search 12345/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                                            ]]\n\n  [[    \"${#lines[@]}\" -eq 6                                                            ]]\n\n  [[    \"${output}\"    =~  Example\\ Folder/3.*Example\\ Folder\\ /\\ Three                 ]]\n  [[    \"${lines[1]}\"  =~  ---------------                                              ]]\n  [[    \"${lines[2]}\"  =~  12345                                                        ]]\n  [[    \"${output}\"    =~  \\\n          Example\\ Folder/Sample\\ Folder/2.*Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Two  ]]\n  [[    \"${lines[4]}\"  =~  ---------------                                              ]]\n  [[    \"${lines[5]}\"  =~  12345                                                        ]]\n}\n\n# <notebook> selectors ########################################################\n\n@test \"'search <notebook>:' (no query, colon) with matching notebook returns 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\" ]]\n  }\n\n  run \"${_NB}\" search Example\\ Notebook:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 1           ]]\n\n  [[    \"${lines[0]}\" =~  Usage.*:    ]]\n  [[    \"${lines[1]}\" =~  nb\\ search  ]]\n}\n\n@test \"'search <notebook>:' (no query, colon) without matching notebook searches for the string in <notebook> recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\" ]]\n\n    \"${_NB}\" edit \"Example Folder/File Two.md\"                \\\n      --content   \"Not a Notebook\"\n    \"${_NB}\" edit \"Example Folder/File Three.md\"              \\\n      --content   \"Not a Notebook:\"\n    \"${_NB}\" edit \"Example Folder/Sample Folder/File Two.md\"  \\\n      --content   \"Not a Notebook:\"\n  }\n\n  run \"${_NB}\" search Not\\ a\\ Notebook:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                                            ]]\n\n  [[    \"${#lines[@]}\" -eq 6                                                            ]]\n\n  [[ !  \"${output}\"    =~  Example\\ Folder/2.*Example\\ Folder\\ /\\ Two                   ]]\n\n  [[    \"${output}\"    =~  Example\\ Folder/3.*Example\\ Folder\\ /\\ Three                 ]]\n  [[    \"${lines[1]}\"  =~  ---------------                                              ]]\n  [[    \"${lines[2]}\"  =~  Not\\ a\\ Notebook                                             ]]\n  [[    \"${output}\"    =~  \\\n          Example\\ Folder/Sample\\ Folder/2.*Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Two  ]]\n  [[    \"${lines[4]}\"  =~  ---------------                                              ]]\n  [[    \"${lines[5]}\"  =~  Not\\ a\\ Notebook                                             ]]\n}\n\n@test \"'search <notebook>' (no query, no colon) with matching notebook searches for the string in <notebook> recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\" ]]\n\n    \"${_NB}\" edit \"Example Folder/File Two.md\"                \\\n      --content   \"Example Notebook\"\n    \"${_NB}\" edit \"Example Folder/File Three.md\"              \\\n      --content   \"Example Notebook:\"\n    \"${_NB}\" edit \"Example Folder/Sample Folder/File Two.md\"  \\\n      --content   \"Example Notebook:\"\n  }\n\n  run \"${_NB}\" search Example\\ Notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                                            ]]\n\n  [[    \"${#lines[@]}\" -eq 9                                                            ]]\n\n  [[    \"${output}\"    =~  Example\\ Folder/3.*Example\\ Folder\\ /\\ Three                 ]]\n  [[    \"${lines[1]}\"  =~  ---------------                                              ]]\n  [[    \"${lines[2]}\"  =~  Example\\ Notebook                                            ]]\n\n  [[    \"${output}\"    =~  Example\\ Folder/2.*Example\\ Folder\\ /\\ Two                   ]]\n  [[    \"${lines[4]}\"  =~  ---------------                                              ]]\n  [[    \"${lines[5]}\"  =~  Example\\ Notebook                                            ]]\n\n  [[    \"${output}\"    =~  \\\n          Example\\ Folder/Sample\\ Folder/2.*Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Two  ]]\n  [[    \"${lines[7]}\"  =~  ---------------                                              ]]\n  [[    \"${lines[8]}\"  =~  Example\\ Notebook                                            ]]\n}\n\n@test \"'search <notebook>:<filename>' (no slash, no space) searches for <filename> in <notebook> root.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search home:File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                     ]]\n\n  [[    \"${output}\"   =~  home:1.*File\\ One.md.*\\ ·\\ Root\\ One  ]]\n  [[    \"${output}\"   =~  ---------------------                 ]]\n  [[    \"${lines[2]}\" =~  Filename\\ Match:\\ .*File\\ One.md      ]]\n  [[ -z \"${lines[3]}\"                                           ]]\n\n  [[ !  \"${output}\"   =~  Example\\ Folder                     ]]\n  [[ !  \"${output}\"   =~  Sample\\ Folder                      ]]\n}\n\n@test \"'search <notebook>: <filename>' (no slash, space) searches for <filename> in <notebook> recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search home: \"File One.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n\n  [[ \"${output}\"    =~  home:1.*File\\ One.md.*\\ ·\\ Root\\ One  ]]\n  [[ \"${output}\"    =~  ---------------------                 ]]\n  [[ \"${lines[2]}\"  =~  Filename\\ Match:\\ .*File\\ One.md      ]]\n\n  [[ \"${output}\"    =~  \\\n      home:Example\\ Folder/1.*File\\ One.md.*\\ ·\\ Example\\ Folder\\ /\\ One ]]\n  [[ \"${output}\"    =~  ---------------------                 ]]\n  [[ \"${lines[5]}\"  =~  Filename\\ Match:\\ .*File\\ One.md      ]]\n\n  [[ \"${output}\"    =~  \\\n      home:Example\\ Folder/1.*File\\ One.md.*\\ ·\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One ]]\n  [[ \"${output}\"    =~  ---------------------                 ]]\n  [[ \"${lines[8]}\"  =~  Filename\\ Match:\\ .*File\\ One.md      ]]\n}\n\n@test \"'search <notebook>:<filename>/' (slash, no space) searches for <filename> in <notebook> root.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search home:File\\ One.md/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                     ]]\n\n  [[    \"${output}\"   =~  home:1.*File\\ One.md.*\\ ·\\ Root\\ One  ]]\n  [[    \"${output}\"   =~  ---------------------                 ]]\n  [[    \"${lines[2]}\" =~  Filename\\ Match:\\ .*File\\ One.md      ]]\n  [[ -z \"${lines[3]}\"                                           ]]\n\n  [[ !  \"${output}\"   =~  Example\\ Folder                       ]]\n  [[ !  \"${output}\"   =~  Sample\\ Folder                        ]]\n}\n\n@test \"'search <notebook>: <filename>/' (slash, space) searches for <filename> in <notebook> recursively.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search home: File\\ One.md/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n\n  [[ \"${output}\"    =~  home:1.*File\\ One.md.*\\ ·\\ Root\\ One  ]]\n  [[ \"${output}\"    =~  ---------------------                 ]]\n  [[ \"${lines[2]}\"  =~  Filename\\ Match:\\ .*File\\ One.md      ]]\n\n  [[ \"${output}\"    =~  \\\n      home:Example\\ Folder/1.*File\\ One.md.*\\ ·\\ Example\\ Folder\\ /\\ One ]]\n  [[ \"${output}\"    =~  ---------------------                 ]]\n  [[ \"${lines[5]}\"  =~  Filename\\ Match:\\ .*File\\ One.md      ]]\n\n  [[ \"${output}\"    =~  \\\n      home:Example\\ Folder/1.*File\\ One.md.*\\ ·\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One ]]\n  [[ \"${output}\"    =~  ---------------------                 ]]\n  [[ \"${lines[8]}\"  =~  Filename\\ Match:\\ .*File\\ One.md      ]]\n}\n\n# <query> selectors ###########################################################\n\n@test \"'search <query> <filename>' searches <filename> in current notebook for <query>.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"example\" File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                 ]]\n  [[ \"${#lines[@]}\" -eq 3                 ]]\n\n  [[ \"${output}\"    =~  [^:]1.*One        ]]\n  [[ \"${output}\"    =~  -------           ]]\n  [[ \"${lines[2]}\"  =~  example.*\\ phrase ]]\n}\n\n@test \"'search <query> <notebook>:<filename>' (no slash) searches <filename> in <notebook> for <query>.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"example\" home:File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n\n  [[ \"${output}\"    =~  home:1.*Root\\ One         ]]\n  [[ \"${output}\"    =~  [^-]-----------------[^-] ]]\n  [[ \"${lines[2]}\"  =~  example.*\\ phrase         ]]\n}\n\n@test \"'search <query> <notebook>:' searches within <notebook> subfolders.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"example phrase\" home:\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[6]}:  '%s'\\\\n\" \"${#lines[6]}\"\n  printf \"\\${#lines[7]}:  '%s'\\\\n\" \"${#lines[7]}\"\n\n  [[ \"${status}\"      -eq 0                         ]]\n\n  [[ \"${output}\"      =~  home:1.*One               ]]\n\n  [[ \"${lines[1]}\"    =~  ------------              ]]\n  [[ \"${#lines[1]}\"   == \"$((${#lines[0]} - 21))\"   ]]\n  [[ \"${lines[2]}\"    =~  3                         ]]\n  [[ \"${lines[2]}\"    =~  example\\ phrase           ]]\n\n  [[ \"${output}\"      =~  home:3.*Three             ]]\n\n  [[ \"${lines[4]}\"    =~  ------------              ]]\n  [[ \"${#lines[4]}\"   == \"$((${#lines[3]} - 21))\"   ]]\n  [[ \"${lines[5]}\"    =~  3                         ]]\n  [[ \"${lines[5]}\"    =~  example\\ phrase           ]]\n\n  [[ \"${output}\"      =~  home:Example\\ Folder/Sample\\ Folder/3         ]]\n  [[ \"${output}\"      =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Three  ]]\n\n  [[ \"${lines[7]}\"    =~  ------------              ]]\n  [[ \"${#lines[7]}\"   == \"$((${#lines[6]} - 21))\"   ]]\n  [[ \"${lines[8]}\"    =~  3                         ]]\n  [[ \"${lines[8]}\"    =~  example\\ phrase           ]]\n\n  [[ \"${output}\"      =~  home:Example\\ Folder/Sample\\ Folder/1         ]]\n  [[ \"${output}\"      =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One    ]]\n\n  [[ \"${lines[10]}\"   =~  ------------              ]]\n  [[ \"${#lines[10]}\"  == \"$((${#lines[9]} - 21))\"   ]]\n  [[ \"${lines[11]}\"   =~  3                         ]]\n  [[ \"${lines[11]}\"   =~  example\\ phrase           ]]\n\n  [[ \"${output}\"      =~ home:Example\\ Folder/2.*Example\\ Folder\\ /\\ Two    ]]\n\n  [[ \"${lines[13]}\"   =~  ------------              ]]\n  [[ \"${#lines[13]}\"  == \"$((${#lines[12]} - 21))\"  ]]\n  [[ \"${lines[14]}\"   =~  3                         ]]\n  [[ \"${lines[14]}\"   =~  example\\ phrase           ]]\n\n  [[ \"${output}\"      =~  home:Example\\ Folder/4.*Example\\ Folder\\ /\\ Four  ]]\n\n  [[ \"${lines[16]}\"   =~  ------------              ]]\n  [[ \"${#lines[16]}\"  == \"$((${#lines[15]} - 21))\"  ]]\n  [[ \"${lines[17]}\"   =~  3                         ]]\n  [[ \"${lines[17]}\"   =~  example\\ phrase           ]]\n}\n\n@test \"'search <query> <notebook>:<folder>/' (slash) searches within <folder> and subfolders in <notebook>.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"example phrase\" home:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                 ]]\n\n  [[ \"${output}\"    =~  home:Example\\ Folder/Sample\\ Folder/3             ]]\n  [[ \"${output}\"    =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Three      ]]\n\n  [[ \"${lines[1]}\"  =~  -----------------------------                     ]]\n  [[ \"${lines[2]}\"  =~  3                                                 ]]\n  [[ \"${lines[2]}\"  =~  example\\ phrase                                   ]]\n\n  [[ \"${output}\"    =~  home:Example\\ Folder/Sample\\ Folder/1             ]]\n  [[ \"${output}\"    =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One        ]]\n\n  [[ \"${lines[4]}\"  =~  -----------------------------                     ]]\n  [[ \"${lines[5]}\"  =~  3                                                 ]]\n  [[ \"${lines[5]}\"  =~  example\\ phrase                                   ]]\n\n  [[ \"${output}\"    =~  home:Example\\ Folder/2.*Example\\ Folder\\ /\\ Two   ]]\n\n  [[ \"${lines[7]}\"  =~  -----------------------------                     ]]\n  [[ \"${lines[8]}\"  =~  3                                                 ]]\n  [[ \"${lines[8]}\"  =~  example\\ phrase                                   ]]\n\n  [[ \"${output}\"    =~  home:Example\\ Folder/4.*Example\\ Folder\\ /\\ Four  ]]\n\n  [[ \"${lines[10]}\" =~  -----------------------------                     ]]\n  [[ \"${lines[11]}\" =~  3                                                 ]]\n  [[ \"${lines[11]}\" =~  example\\ phrase                                   ]]\n}\n\n@test \"'search <query> <notebook>:<folder>' (no slash) searches within <folder> and subfolders in <notebook>.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"example phrase\" home:Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                   ]]\n\n  [[ \"${output}\"    =~  home:Example\\ Folder/Sample\\ Folder/3           ]]\n  [[ \"${output}\"    =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Three        ]]\n\n  [[ \"${lines[1]}\"  =~  -----------------------------                       ]]\n  [[ \"${lines[2]}\"  =~  3                                                   ]]\n  [[ \"${lines[2]}\"  =~  example\\ phrase                                     ]]\n\n  [[ \"${output}\"    =~  home:Example\\ Folder/Sample\\ Folder/1           ]]\n  [[ \"${output}\"    =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One          ]]\n\n  [[ \"${lines[4]}\"  =~  -----------------------------                       ]]\n  [[ \"${lines[5]}\"  =~  3                                                   ]]\n  [[ \"${lines[5]}\"  =~  example\\ phrase                                     ]]\n\n  [[ \"${output}\"    =~  home:Example\\ Folder/2.*Example\\ Folder\\ /\\ Two   ]]\n\n  [[ \"${lines[7]}\"  =~  -----------------------------                       ]]\n  [[ \"${lines[8]}\"  =~  3                                                   ]]\n  [[ \"${lines[8]}\"  =~  example\\ phrase                                     ]]\n\n  [[ \"${output}\"    =~  home:Example\\ Folder/4.*Example\\ Folder\\ /\\ Four  ]]\n\n  [[ \"${lines[10]}\" =~  -----------------------------                       ]]\n  [[ \"${lines[11]}\" =~  3                                                   ]]\n  [[ \"${lines[11]}\" =~  example\\ phrase                                     ]]\n}\n\n# `search` spacing and alignment ##############################################\n\n@test \"'search <query> --list / -l' includes extra spacing to align with max id length in folder.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    for ((_i=0; _i < 12; _i++))\n    do\n      \"${_NB}\" add \"note ${_i}\"\n    done\n\n    \"${_NB}\" add                            \\\n      --filename  \"example.bookmark.md\"     \\\n      --folder    \"Example Folder\"          \\\n      --content   \"<http://example.test/>\"  \\\n      --title     \"Example Title One\"\n  }\n\n  run \"${_NB}\" search 'example.test' --no-color --list\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                     ]]\n  [[    \"${#lines[@]}\"  -eq 1                     ]]\n\n  [[ !  \"${lines[0]}\"   =~  example-1.bookmark.md ]]\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/6     ]]\n  [[    \"${lines[0]}\"   =~  Example\\ Title\\ One   ]]\n  [[    \"${lines[0]}\"   =~  \\]\\ 🔖                ]]\n\n  for ((_i=0; _i < 12; _i++))\n  do\n    \"${_NB}\" add \"Example Folder/note ${_i}\"\n  done\n\n  run \"${_NB}\" search 'example.test' --no-color --list\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                     ]]\n  [[    \"${#lines[@]}\"  -eq 1                     ]]\n\n  [[ !  \"${lines[0]}\"   =~  example-1.bookmark.md ]]\n  [[    \"${lines[0]}\"   =~  Example\\ Folder/6   ]]\n  [[    \"${lines[0]}\"   =~  Example\\ Title\\ One   ]]\n  [[    \"${lines[0]}\"   =~  \\]\\ \\ 🔖              ]]\n}\n\n# `search` ####################################################################\n\n@test \"'search <query>' skips unindexed subfolders.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    mkdir -p \"${NB_DIR}/home/Example Unindexed/Sample Unindexed\"\n    cat <<HEREDOC > \"${NB_DIR}/home/Example Unindexed/Sample Unindexed/document.md\"\n# Example Unindexed / Sample Unindexed / Document\n\nexample phrase\nHEREDOC\n  }\n\n  run \"${_NB}\" search \"example phrase\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                                             ]]\n\n  [[ !  \"${output}\" =~  Unindexed                                     ]]\n\n  [[    \"${output}\" =~  Example\\ Folder/Sample\\ Folder/3              ]]\n  [[    \"${output}\" =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Three  ]]\n}\n\n# `search <folder>/` ##########################################################\n\n@test \"'search <query> <folder>/' (slash) searches for <query> within <folder> and subfolders.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"example phrase\" Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/3              ]]\n  [[ \"${output}\"    =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Three  ]]\n\n  [[ \"${lines[1]}\"  =~  -----------------------------                 ]]\n  [[ \"${lines[2]}\"  =~  3                                             ]]\n  [[ \"${lines[2]}\"  =~  example\\ phrase                               ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/1              ]]\n  [[ \"${output}\"    =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One    ]]\n\n  [[ \"${lines[4]}\"  =~  -----------------------------                 ]]\n  [[ \"${lines[5]}\"  =~  3                                             ]]\n  [[ \"${lines[5]}\"  =~  example\\ phrase                               ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/2.*Example\\ Folder\\ /\\ Two    ]]\n\n  [[ \"${lines[7]}\"  =~  -----------------------------                 ]]\n  [[ \"${lines[8]}\"  =~  3                                             ]]\n  [[ \"${lines[8]}\"  =~  example\\ phrase                               ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/4.*Example\\ Folder\\ /\\ Four   ]]\n\n  [[ \"${lines[10]}\" =~  -----------------------------                 ]]\n  [[ \"${lines[11]}\" =~  3                                             ]]\n  [[ \"${lines[11]}\" =~  example\\ phrase                               ]]\n}\n\n@test \"'search <query> <folder>' (no slash) searches for <query> within <folder> and subfolders.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"example phrase\" Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/3              ]]\n  [[ \"${output}\"    =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Three  ]]\n\n  [[ \"${lines[1]}\"  =~  -----------------------------                 ]]\n  [[ \"${lines[2]}\"  =~  3                                             ]]\n  [[ \"${lines[2]}\"  =~  example\\ phrase                               ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/1              ]]\n  [[ \"${output}\"    =~  Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One    ]]\n\n  [[ \"${lines[4]}\"  =~  -----------------------------                 ]]\n  [[ \"${lines[5]}\"  =~  3                                             ]]\n  [[ \"${lines[5]}\"  =~  example\\ phrase                               ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/2.*Example\\ Folder\\ /\\ Two    ]]\n\n  [[ \"${lines[7]}\"  =~  -----------------------------                 ]]\n  [[ \"${lines[8]}\"  =~  3                                             ]]\n  [[ \"${lines[8]}\"  =~  example\\ phrase                               ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/4.*Example\\ Folder\\ /\\ Four   ]]\n\n  [[ \"${lines[10]}\" =~  -----------------------------                 ]]\n  [[ \"${lines[11]}\" =~  3                                             ]]\n  [[ \"${lines[11]}\" =~  example\\ phrase                               ]]\n}\n\n# `search --no-recurse` #######################################################\n\n@test \"'search <query> <folder>/ --no-recurse' (slash) searches within <folder> only.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"example phrase\" Example\\ Folder/ --no-recurse\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                              ]]\n\n  [[    \"${lines[0]}\"  =~  Example\\ Folder/4              ]]\n  [[    \"${lines[0]}\"  =~  Example\\ Folder\\ /\\            ]]\n  [[    \"${lines[0]}\"  =~  Two|Four                       ]]\n  [[    \"${lines[1]}\"  =~  -----------------------------  ]]\n  [[    \"${lines[2]}\"  =~  3                              ]]\n  [[    \"${lines[2]}\"  =~  example\\ phrase                ]]\n\n  [[    \"${lines[3]}\"  =~  Example\\ Folder/2              ]]\n  [[    \"${lines[3]}\"  =~  Example\\ Folder\\ /\\            ]]\n  [[    \"${lines[3]}\"  =~  Two|Four                       ]]\n  [[    \"${lines[4]}\"  =~  -----------------------------  ]]\n  [[    \"${lines[5]}\"  =~  3                              ]]\n  [[    \"${lines[5]}\"  =~  example\\ phrase                ]]\n\n  [[ -z \"${lines[6]}\"                                     ]]\n}\n\n@test \"'search <query> <folder> --no-recurse' (no slash) searches within <folder> only.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"example phrase\" Example\\ Folder --no-recurse\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                              ]]\n\n  [[    \"${lines[0]}\"  =~  Example\\ Folder/4              ]]\n  [[    \"${lines[0]}\"  =~  Example\\ Folder\\ /\\            ]]\n  [[    \"${lines[0]}\"  =~  Two|Four                       ]]\n  [[    \"${lines[1]}\"  =~  -----------------------------  ]]\n  [[    \"${lines[2]}\"  =~  3                              ]]\n  [[    \"${lines[2]}\"  =~  example\\ phrase                ]]\n\n  [[    \"${lines[3]}\"  =~  Example\\ Folder/2              ]]\n  [[    \"${lines[3]}\"  =~  Example\\ Folder\\ /\\            ]]\n  [[    \"${lines[3]}\"  =~  Two|Four                       ]]\n  [[    \"${lines[4]}\"  =~  -----------------------------  ]]\n  [[    \"${lines[5]}\"  =~  3                              ]]\n  [[    \"${lines[5]}\"  =~  example\\ phrase                ]]\n\n  [[ -z \"${lines[6]}\"                                     ]]\n}\n\n# `search` local notebook #####################################################\n\n@test \"'search <query> <folder>/' (slash) in local notebook exits with status 0 and prints output.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n\n    _setup_folders_and_files --local\n  }\n\n  run \"${_NB}\" search \"example phrase\" Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                       ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/3                        ]]\n  [[ \"${output}\"    =~  Local\\ /\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Three  ]]\n\n  [[ \"${lines[1]}\"  =~  -----------------------------                           ]]\n  [[ \"${lines[2]}\"  =~  3                                                       ]]\n  [[ \"${lines[2]}\"  =~  example\\ phrase                                         ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/1                        ]]\n  [[ \"${output}\"    =~  Local\\ /\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One    ]]\n\n  [[ \"${lines[4]}\"  =~  -----------------------------                           ]]\n  [[ \"${lines[5]}\"  =~  3                                                       ]]\n  [[ \"${lines[5]}\"  =~  example\\ phrase                                         ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/2.*Local\\ /\\ Example\\ Folder\\ /\\ Two    ]]\n\n  [[ \"${lines[7]}\"  =~  -----------------------------                           ]]\n  [[ \"${lines[8]}\"  =~  3                                                       ]]\n  [[ \"${lines[8]}\"  =~  example\\ phrase                                         ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/4.*Local\\ /\\ Example\\ Folder\\ /\\ Four   ]]\n\n  [[ \"${lines[10]}\" =~  -----------------------------                           ]]\n  [[ \"${lines[11]}\" =~  3                                                       ]]\n  [[ \"${lines[11]}\" =~  example\\ phrase                                         ]]\n}\n\n@test \"'search <query> <folder>' (no slash) in local notebook exits with status 0 and prints output.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n\n    _setup_folders_and_files --local\n  }\n\n  run \"${_NB}\" search \"example phrase\" Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                       ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/3                        ]]\n  [[ \"${output}\"    =~  Local\\ /\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ Three  ]]\n\n  [[ \"${lines[1]}\"  =~  -----------------------------                           ]]\n  [[ \"${lines[2]}\"  =~  3                                                       ]]\n  [[ \"${lines[2]}\"  =~  example\\ phrase                                         ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/1                        ]]\n  [[ \"${output}\"    =~  Local\\ /\\ Example\\ Folder\\ /\\ Sample\\ Folder\\ /\\ One    ]]\n\n  [[ \"${lines[4]}\"  =~  -----------------------------                           ]]\n  [[ \"${lines[5]}\"  =~  3                                                       ]]\n  [[ \"${lines[5]}\"  =~  example\\ phrase                                         ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/2.*Local\\ /\\ Example\\ Folder\\ /\\ Two    ]]\n\n  [[ \"${lines[7]}\"  =~  -----------------------------                           ]]\n  [[ \"${lines[8]}\"  =~  3                                                       ]]\n  [[ \"${lines[8]}\"  =~  example\\ phrase                                         ]]\n\n  [[ \"${output}\"    =~  Example\\ Folder/4.*Local\\ /\\ Example\\ Folder\\ /\\ Four   ]]\n\n  [[ \"${lines[10]}\" =~  -----------------------------                           ]]\n  [[ \"${lines[11]}\" =~  3                                                       ]]\n  [[ \"${lines[11]}\" =~  example\\ phrase                                         ]]\n}\n\n# no match ####################################################################\n\n@test \"'search <no-match-query> <filename>/' (slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"no-match-query\" File\\ One.md/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                     ]]\n  [[ \"${#lines[@]}\" -eq 1                                     ]]\n  [[ \"${output}\"    =~  Not\\ found\\ in                        ]]\n  [[ \"${output}\"    =~  File\\ One.md[^/].*:\\ .*no-match-query ]]\n}\n\n@test \"'search <no-match-query> <filename>' (no slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"no-match-query\" File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                     ]]\n  [[ \"${#lines[@]}\" -eq 1                                     ]]\n  [[ \"${output}\"    =~  Not\\ found\\ in                        ]]\n  [[ \"${output}\"    =~  File\\ One.md[^/].*:\\ .*no-match-query ]]\n}\n\n@test \"'search <no-match-query> <folder>/' (slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"no-match-query\" Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                     ]]\n  [[ \"${#lines[@]}\" -eq 1                                     ]]\n  [[ \"${output}\"    =~  Not\\ found\\ in                        ]]\n  [[ \"${output}\"    =~  Example\\ Folder/.*:\\ .*no-match-query ]]\n}\n\n@test \"'search <no-match-query> <folder>' (no slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n  }\n\n  run \"${_NB}\" search \"no-match-query\" Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                     ]]\n  [[ \"${#lines[@]}\" -eq 1                                     ]]\n  [[ \"${output}\"    =~  Not\\ found\\ in                        ]]\n  [[ \"${output}\"    =~  Example\\ Folder/.*:\\ .*no-match-query ]]\n}\n\n@test \"'search <no-match-query> <notebook>:<folder>/' (slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"no-match-query\" home:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                           ]]\n  [[ \"${#lines[@]}\" -eq 1                                           ]]\n  [[ \"${output}\"    =~  Not\\ found\\ in                              ]]\n  [[ \"${output}\"    =~  home:Example\\ Folder/.*:\\ .*no-match-query  ]]\n}\n\n@test \"'search <no-match-query> <notebook>:<folder>' (no slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"no-match-query\" home:Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                           ]]\n  [[ \"${#lines[@]}\" -eq 1                                           ]]\n  [[ \"${output}\"    =~  Not\\ found\\ in                              ]]\n  [[ \"${output}\"    =~  home:Example\\ Folder/.*:\\ .*no-match-query  ]]\n}\n\n@test \"'search <no-match-query> <notebook>:<folder-id>/' (slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"no-match-query\" home:5/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                             ]]\n  [[ \"${#lines[@]}\" -eq 1                             ]]\n  [[ \"${output}\"    =~  Not\\ found\\ in                ]]\n  [[ \"${output}\"    =~  home:5/.*:\\ .*no-match-query  ]]\n}\n\n@test \"'search <no-match-query> <notebook>:<folder-id>' (no slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"no-match-query\" home:5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                             ]]\n  [[ \"${#lines[@]}\" -eq 1                             ]]\n  [[ \"${output}\"    =~  Not\\ found\\ in                ]]\n  [[ \"${output}\"    =~  home:5/.*:\\ .*no-match-query  ]]\n}\n\n@test \"'search <notebook>: <no-match>' (no slash, space / query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search home: no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                     ]]\n  [[ \"${#lines[@]}\" -eq 1                                     ]]\n  [[ \"${output}\"    =~  Not\\ found\\ in\\ .*home.*:\\ .*no-match ]]\n}\n\n@test \"'search <query> <notebook>:<no-match>' (no slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"no-match-query\" home:no-match.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n  [[ \"${output}\"    =~  home.*:\\ .*no-match-query ]]\n}\n\n@test \"'search <notebook>:<no-match>' (no slash, no space, no query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search home:no-match.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                       ]]\n  [[ \"${#lines[@]}\" -eq 1                       ]]\n  [[ \"${output}\"    =~  home.*:\\ .*no-match.md  ]]\n}\n\n@test \"'search <notebook>:<no-match>/' (slash, no space, no query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search home:no-match.md/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                           ]]\n  [[ \"${#lines[@]}\" -eq 1                           ]]\n  [[ \"${output}\"    =~  home.*:\\ .*no-match.md[^/]  ]]\n}\n\n@test \"'search <no-match-query> <notebook>:<no-match>/' (slash, no space, query) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_folders_and_files\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" search \"no-match-query\" home:no-match.md/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n  [[ \"${output}\"    =~  home.*:\\ .*no-match-query ]]\n}\n"
  },
  {
    "path": "test/folders-show.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# show error handling #########################################################\n\n@test \"'show filename/<id>' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.md\"     --title \"one\"     --content \"Content one.\"\n    \"${_NB}\" add \"example.md\" --title \"example\" --content \"Content example.\"\n  }\n\n  run \"${_NB}\" show one.md/example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 1             ]]\n\n  [[   \"${lines[0]}\"  =~ Not\\ found:    ]]\n  [[   \"${lines[0]}\"  =~ one.md/example ]]\n  [[   \"${#lines[@]}\" == 1              ]]\n}\n\n# show --id ###################################################################\n\n@test \"'show <folder>/<filename> --id' exits with status 0 and prints note id.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Example File.md\"\n  }\n\n  run \"${_NB}\" show \"Example Folder/Example File.md\" --id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0   ]]\n  [[ \"${output}\" ==   \"1\" ]]\n}\n\n# show --relative-path ########################################################\n\n@test \"'show <selector> --relative-path' with numeric folder name gives precedence to ids.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                        \\\n      --content   \"Example content 2.\"  \\\n      --filename  \"2\"\n\n    \"${_NB}\" add                        \\\n      --filename  \"1\"                   \\\n      --type      \"folder\"\n\n\n    [[ -d \"${NB_DIR}/home/1\" ]]\n    [[ -f \"${NB_DIR}/home/2\" ]]\n  }\n\n  run \"${_NB}\" show 1 --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n  [[ \"${output}\" ==  \"2\"    ]]\n\n  run \"${_NB}\" show 2 --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0      ]]\n  [[ \"${output}\" ==  \"1\"    ]]\n}\n\n@test \"'show <id> --relative-path' with filename matching notebook name prints filename.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add --filename \"one:\" --content \"Example content one.\"\n    \"${_NB}\" add --filename \"two:\" --content \"Example content two.\"\n\n    \"${_NB}\" notebooks add \"one\"\n\n    [[ -d \"${NB_DIR}/one\"       ]]\n    [[ -f \"${NB_DIR}/home/one:\" ]]\n    [[ -f \"${NB_DIR}/home/two:\" ]]\n  }\n\n  run \"${_NB}\" show 1 --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0          ]]\n  [[ \"${output}\" ==  \"one:\"     ]]\n\n  run \"${_NB}\" show 2 --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0          ]]\n  [[ \"${output}\" ==  \"two:\"     ]]\n}\n\n@test \"'show folder/folder/<title> --relative-path' displays relative path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder/Example Title\" --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${NB_DIR}/home/Example Folder/Sample Folder/\"\n\n  [[ \"${status}\"  -eq 0                                                     ]]\n  [[ \"${output}\"  =~  ^Example\\ Folder/Sample\\ Folder/example.bookmark.md   ]]\n}\n\n@test \"'show folder/folder/<filename> --relative-path' displays relative path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder/example.bookmark.md\" --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${NB_DIR}/home/Example Folder/Sample Folder/\"\n\n  [[ \"${status}\"  -eq 0                                                     ]]\n  [[ \"${output}\"  =~  ^Example\\ Folder/Sample\\ Folder/example.bookmark.md   ]]\n}\n\n@test \"'show folder/folder/<id> --relative-path' displays relative path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder/1\" --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _example_selector=\"Example Folder/Sample Folder/1\"\n  printf \"'%s'\\\\n\" \"${_example_selector%\\/*}\"\n  printf \"'%s'\\\\n\" \"${_example_selector##*\\/}\"\n  \"${_NB}\" index get_basename   \\\n    \"${_example_selector##*\\/}\" \\\n    \"${NB_DIR}/home/${_example_selector%\\/*}\"\n\n  [[ \"${status}\"  -eq 0                                                   ]]\n  [[ \"${output}\"  =~  ^Example\\ Folder/Sample\\ Folder/example.bookmark.md ]]\n}\n\n@test \"'show notebook:folder/folder/<id> --relative-path' displays relative path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"one\"\n\n    \"${_NB}\" one:add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                                \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/one/Example Folder\"                                    ]]\n    [[ -d \"${NB_DIR}/one/Example Folder/Sample Folder\"                      ]]\n    [[ -f \"${NB_DIR}/one/Example Folder/Sample Folder/example.bookmark.md\"  ]]\n  }\n\n  run \"${_NB}\" show \"one:Example Folder/Sample Folder/1\" --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                   ]]\n  [[ \"${output}\"  =~  ^Example\\ Folder/Sample\\ Folder/example.bookmark.md ]]\n}\n\n@test \"'show notebook: --relative-path' prints empty string.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"one\"\n\n    \"${_NB}\" one:add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                                \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/one/Example Folder\"                                    ]]\n    [[ -d \"${NB_DIR}/one/Example Folder/Sample Folder\"                      ]]\n    [[ -f \"${NB_DIR}/one/Example Folder/Sample Folder/example.bookmark.md\"  ]]\n  }\n\n  run \"${_NB}\" show \"one:\" --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n# show --folder-path ########################################################\n\n@test \"'show <id> --folder-path' with filename matching notebook name prints nothing.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add --filename \"one:\" --content \"Example content one.\"\n    \"${_NB}\" add --filename \"two:\" --content \"Example content two.\"\n\n    \"${_NB}\" notebooks add \"one\"\n\n    [[ -d \"${NB_DIR}/one\"       ]]\n    [[ -f \"${NB_DIR}/home/one:\" ]]\n    [[ -f \"${NB_DIR}/home/two:\" ]]\n  }\n\n  run \"${_NB}\" show 1 --folder-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output:-}\"     ]]\n\n  run \"${_NB}\" show 2 --folder-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output:-}\"     ]]\n}\n\n@test \"'show folder/folder --folder-path' (no slash) displays folder path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder\" --folder-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n}\n\n@test \"'show folder/folder/ --folder-path' (slash) displays folder path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder/\" --folder-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  =~  ^Example\\ Folder/Sample\\ Folder ]]\n}\n\n@test \"'show folder/folder/<title> --folder-path' displays folder path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder/Example Title\" --folder-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${NB_DIR}/home/Example Folder/Sample Folder/\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  =~  ^Example\\ Folder/Sample\\ Folder ]]\n}\n\n@test \"'show folder/folder/<filename> --folder-path' displays folder path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder/example.bookmark.md\" --folder-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${NB_DIR}/home/Example Folder/Sample Folder/\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  =~  ^Example\\ Folder/Sample\\ Folder ]]\n}\n\n@test \"'show folder/folder/<id> --folder-path' displays folder path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder/1\" --folder-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _example_selector=\"Example Folder/Sample Folder/1\"\n  printf \"'%s'\\\\n\" \"${_example_selector%\\/*}\"\n  printf \"'%s'\\\\n\" \"${_example_selector##*\\/}\"\n  \"${_NB}\" index get_basename   \\\n    \"${_example_selector##*\\/}\" \\\n    \"${NB_DIR}/home/${_example_selector%\\/*}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  =~  ^Example\\ Folder/Sample\\ Folder ]]\n}\n\n@test \"'show notebook:folder/folder/<id> --folder-path' displays folder path.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"one\"\n\n    \"${_NB}\" one:add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                                \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/one/Example Folder\"                                    ]]\n    [[ -d \"${NB_DIR}/one/Example Folder/Sample Folder\"                      ]]\n    [[ -f \"${NB_DIR}/one/Example Folder/Sample Folder/example.bookmark.md\"  ]]\n  }\n\n  run \"${_NB}\" show \"one:Example Folder/Sample Folder/1\" --folder-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  =~  ^Example\\ Folder/Sample\\ Folder ]]\n}\n\n@test \"'show notebook: --folder-path' prints empty string.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"one\"\n\n    \"${_NB}\" one:add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                                \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/one/Example Folder\"                                    ]]\n    [[ -d \"${NB_DIR}/one/Example Folder/Sample Folder\"                      ]]\n    [[ -f \"${NB_DIR}/one/Example Folder/Sample Folder/example.bookmark.md\"  ]]\n  }\n\n  run \"${_NB}\" show \"one:\" --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n# show <path-with-folder> --info-line #########################################\n\n@test \"'show folder/folder/<filename> --info-line' displays info line.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder/1\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${NB_DIR}/home/Example Folder/Sample Folder/\"\n\n  [[   \"${status}\"    -eq 0                                                   ]]\n  [[   \"${output}\"    =~  1                                                   ]]\n  [[   \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/example.bookmark.md  ]]\n  [[   \"${output}\"    =~  Example\\ Title                                      ]]\n  [[   \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/1                    ]]\n  [[ ! \"${output}\"    =~  home                                                ]]\n  [[   \"${output}\"    =~  🔖                                                  ]]\n}\n\n@test \"'show notebook:folder/folder/<filename> --info-line' displays info line.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" show \"home:Example Folder/Sample Folder/1\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${NB_DIR}/home/Example Folder/Sample Folder/\"\n\n  [[ \"${status}\"    -eq 0                                                   ]]\n  [[ \"${output}\"    =~  1                                                   ]]\n  [[ \"${output}\"    =~  Example\\ Folder/Sample\\ Folder/example.bookmark.md  ]]\n  [[ \"${output}\"    =~  Example\\ Title                                      ]]\n  [[ \"${output}\"    =~  home:Example\\ Folder/Sample\\ Folder/1               ]]\n  [[ \"${output}\"    =~  🔖                                                  ]]\n}\n\n# show <path-with-folder> --selector-id #######################################\n\n@test \"'show folder/folder/<filename> --selector-id' displays selector id.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder/example.md\" --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                         ]]\n  [[ \"${output}\"  =~  Example\\ Folder/Sample\\ Folder/example.md ]]\n}\n\n@test \"'show demo:folder/folder/<filename> --selector-id' displays selector id.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.bookmark.md\" \\\n      --content \"<https://example.test>\"                            \\\n      --title   \"Example Title\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                   ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                     ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" show \"demo:Example Folder/Sample Folder/example.md\" --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                         ]]\n  [[ \"${output}\"  =~  Example\\ Folder/Sample\\ Folder/example.md ]]\n}\n"
  },
  {
    "path": "test/folders-subcommand.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# alias #######################################################################\n\n@test \"'f add <name>' adds folder with <name>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"     ]]\n  }\n\n  run \"${_NB}\" f add \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 0                                      ]]\n  [[      \"${output}\"   =~ Added:\\ .*[.*1.*].*\\ .*Example\\ Folder ]]\n  [[ -d   \"${NB_DIR}/home/Example Folder\"                         ]]\n}\n\n# add ########################################################################\n\n@test \"'folders add' with no name prints help.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/folder\"             ]]\n  }\n\n  run \"${_NB}\" folders add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 1                    ]]\n  [[      \"${lines[0]}\" =~ Usage                ]]\n  [[      \"${lines[1]}\" =~ nb\\ folders\\ add     ]]\n  [[      \"${lines[2]}\" =~ nb\\ folders\\ delete  ]]\n  [[ ! -e \"${NB_DIR}/home/folder\"               ]]\n}\n\n@test \"'folders a' with no name prints help.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/folder\"             ]]\n  }\n\n  run \"${_NB}\" folders add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 1                    ]]\n  [[      \"${lines[0]}\" =~ Usage                ]]\n  [[      \"${lines[1]}\" =~ nb\\ folders\\ add     ]]\n  [[      \"${lines[2]}\" =~ nb\\ folders\\ delete  ]]\n  [[ ! -e \"${NB_DIR}/home/folder\"               ]]\n}\n\n@test \"'folders +' with no name prints help.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/folder\"             ]]\n  }\n\n  run \"${_NB}\" folders add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 1                    ]]\n  [[      \"${lines[0]}\" =~ Usage                ]]\n  [[      \"${lines[1]}\" =~ nb\\ folders\\ add     ]]\n  [[      \"${lines[2]}\" =~ nb\\ folders\\ delete  ]]\n  [[ ! -e \"${NB_DIR}/home/folder\"               ]]\n}\n\n@test \"'folders add <name>' adds folder with <name>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"     ]]\n  }\n\n  run \"${_NB}\" folders add \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 0                                      ]]\n  [[      \"${output}\"   =~ Added:\\ .*[.*1.*].*\\ .*Example\\ Folder ]]\n  [[ -d   \"${NB_DIR}/home/Example Folder\"                         ]]\n}\n\n@test \"'folders a <name>' adds folder with <name>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"     ]]\n  }\n\n  run \"${_NB}\" folders a \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 0                                      ]]\n  [[      \"${output}\"   =~ Added:\\ .*[.*1.*].*\\ .*Example\\ Folder ]]\n  [[ -d   \"${NB_DIR}/home/Example Folder\"                         ]]\n}\n\n@test \"'folders + <name>' adds folder with <name>.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"     ]]\n  }\n\n  run \"${_NB}\" folders + \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 0                                      ]]\n  [[      \"${output}\"   =~ Added:\\ .*[.*1.*].*\\ .*Example\\ Folder ]]\n  [[ -d   \"${NB_DIR}/home/Example Folder\"                         ]]\n}\n\n# delete ######################################################################\n\n@test \"'folders delete' with no name prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" folders delete\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 1                    ]]\n  [[      \"${lines[0]}\" =~ Usage                ]]\n  [[      \"${lines[1]}\" =~ nb\\ folders\\ add     ]]\n  [[      \"${lines[2]}\" =~ nb\\ folders\\ delete  ]]\n}\n\n@test \"'folders d' with no name prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" folders d\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 1                    ]]\n  [[      \"${lines[0]}\" =~ Usage                ]]\n  [[      \"${lines[1]}\" =~ nb\\ folders\\ add     ]]\n  [[      \"${lines[2]}\" =~ nb\\ folders\\ delete  ]]\n}\n\n@test \"'folders -' with no name prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" folders -\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 1                    ]]\n  [[      \"${lines[0]}\" =~ Usage                ]]\n  [[      \"${lines[1]}\" =~ nb\\ folders\\ add     ]]\n  [[      \"${lines[2]}\" =~ nb\\ folders\\ delete  ]]\n}\n\n@test \"'folders rm' with no name prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" folders rm\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 1                    ]]\n  [[      \"${lines[0]}\" =~ Usage                ]]\n  [[      \"${lines[1]}\" =~ nb\\ folders\\ add     ]]\n  [[      \"${lines[2]}\" =~ nb\\ folders\\ delete  ]]\n}\n\n@test \"'folders delete <name>' with non-folder prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"      ]]\n  }\n\n  run \"${_NB}\" folders delete \"Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 1                                            ]]\n  [[      \"${output}\"   =~ !.*\\ Not\\ a\\ folder:\\ .*Example\\ File.md     ]]\n  [[   -e \"${NB_DIR}/home/Example File.md\"                              ]]\n}\n\n@test \"'folders delete <name>' with no matching folder <name> prints message.\" {\n  {\n    \"${_NB}\" init\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder\"       ]]\n  }\n\n  run \"${_NB}\" folders delete \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 1                                    ]]\n  [[      \"${output}\"   =~ !.*\\ Not\\ found:\\ .*Example\\ Folder  ]]\n}\n\n@test \"'folders delete <name>' with existing folder deletes folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    [[ -e \"${NB_DIR}/home/Example Folder\"       ]]\n  }\n\n  run \"${_NB}\" folders delete \"Example Folder\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 0                                              ]]\n  [[      \"${output}\"   =~ Deleted:\\ \\ .*[.*1.*].*\\ 📂\\ .*Example\\ Folder ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"                                 ]]\n}\n\n@test \"'folders d <name>' with existing folder deletes folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    [[ -e \"${NB_DIR}/home/Example Folder\"       ]]\n  }\n\n  run \"${_NB}\" folders d \"Example Folder\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 0                                              ]]\n  [[      \"${output}\"   =~ Deleted:\\ \\ .*[.*1.*].*\\ 📂\\ .*Example\\ Folder ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"                                 ]]\n}\n\n@test \"'folders - <name>' with existing folder deletes folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    [[ -e \"${NB_DIR}/home/Example Folder\"       ]]\n  }\n\n  run \"${_NB}\" folders - \"Example Folder\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 0                                              ]]\n  [[      \"${output}\"   =~ Deleted:\\ \\ .*[.*1.*].*\\ 📂\\ .*Example\\ Folder ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"                                 ]]\n}\n\n@test \"'folders rm <name>' with existing folder deletes folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    [[ -e \"${NB_DIR}/home/Example Folder\"       ]]\n  }\n\n  run \"${_NB}\" folders rm \"Example Folder\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   == 0                                              ]]\n  [[      \"${output}\"   =~ Deleted:\\ \\ .*[.*1.*].*\\ 📂\\ .*Example\\ Folder ]]\n  [[ ! -d \"${NB_DIR}/home/Example Folder\"                                 ]]\n}\n\n# list / default ##############################################################\n\n@test \"'folders' with no folders displays message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" folders\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  0\\ folders\\.                          ]]\n}\n\n@test \"'folders' with folders in current notebook lists folders.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Demo Folder\"\n\n    \"${_NB}\" pin \"Demo Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File Two.md\" --content \"Example content two.\"\n\n    sleep 1\n\n    \"${_NB}\" add folder \"Sample Folder\"\n  }\n\n  run \"${_NB}\" folders\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  .*[.*1.*].*\\ 📌\\ 📂\\ Demo\\ Folder     ]]\n  [[   \"${lines[1]}\"  =~  .*[.*5.*].*\\ 📂\\ Sample\\ Folder       ]]\n  [[   \"${lines[2]}\"  =~  .*[.*3.*].*\\ 📂\\ Example\\ Folder      ]]\n}\n\n@test \"'folders ls' with folders in current notebook lists folders.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Demo Folder\"\n\n    \"${_NB}\" pin \"Demo Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File Two.md\" --content \"Example content two.\"\n\n    sleep 1\n\n    \"${_NB}\" add folder \"Sample Folder\"\n  }\n\n  run \"${_NB}\" folders ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  .*[.*1.*].*\\ 📌\\ 📂\\ Demo\\ Folder     ]]\n  [[   \"${lines[1]}\"  =~  .*[.*5.*].*\\ 📂\\ Sample\\ Folder       ]]\n  [[   \"${lines[2]}\"  =~  .*[.*3.*].*\\ 📂\\ Example\\ Folder      ]]\n}\n\n@test \"'folders list' with folders in current notebook lists folders.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Demo Folder\"\n\n    \"${_NB}\" pin \"Demo Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File Two.md\" --content \"Example content two.\"\n\n    sleep 1\n\n    \"${_NB}\" add folder \"Sample Folder\"\n  }\n\n  run \"${_NB}\" folders list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                     ]]\n  [[   \"${lines[0]}\"  =~  .*[.*1.*].*\\ 📌\\ 📂\\ Demo\\ Folder     ]]\n  [[   \"${lines[1]}\"  =~  .*[.*5.*].*\\ 📂\\ Sample\\ Folder       ]]\n  [[   \"${lines[2]}\"  =~  .*[.*3.*].*\\ 📂\\ Example\\ Folder      ]]\n}\n\n@test \"'folders <notebook>:' with folders in <notebook> lists folders.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Demo Folder\"\n\n    \"${_NB}\" pin \"Demo Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File Two.md\" --content \"Example content two.\"\n\n    sleep 1\n\n    \"${_NB}\" add folder \"Sample Folder\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n  }\n\n  run \"${_NB}\" folders home:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                       ]]\n  [[   \"${lines[0]}\"  =~  .*[.*home:1.*].*\\ 📌\\ 📂\\ Demo\\ Folder  ]]\n  [[   \"${lines[1]}\"  =~  .*[.*home:5.*].*\\ 📂\\ Sample\\ Folder    ]]\n  [[   \"${lines[2]}\"  =~  .*[.*home:3.*].*\\ 📂\\ Example\\ Folder   ]]\n}\n\n@test \"'folders ls <notebook>:' with folders in <notebook> lists folders.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Demo Folder\"\n\n    \"${_NB}\" pin \"Demo Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File Two.md\" --content \"Example content two.\"\n\n    sleep 1\n\n    \"${_NB}\" add folder \"Sample Folder\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n  }\n\n  run \"${_NB}\" folders ls home:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                       ]]\n  [[   \"${lines[0]}\"  =~  .*[.*home:1.*].*\\ 📌\\ 📂\\ Demo\\ Folder  ]]\n  [[   \"${lines[1]}\"  =~  .*[.*home:5.*].*\\ 📂\\ Sample\\ Folder    ]]\n  [[   \"${lines[2]}\"  =~  .*[.*home:3.*].*\\ 📂\\ Example\\ Folder   ]]\n\n  run \"${_NB}\" folders home: ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                       ]]\n  [[   \"${lines[0]}\"  =~  .*[.*home:1.*].*\\ 📌\\ 📂\\ Demo\\ Folder  ]]\n  [[   \"${lines[1]}\"  =~  .*[.*home:5.*].*\\ 📂\\ Sample\\ Folder    ]]\n  [[   \"${lines[2]}\"  =~  .*[.*home:3.*].*\\ 📂\\ Example\\ Folder   ]]\n}\n\n@test \"'folders list <notebook>:' with folders in <notebook> lists folders.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add folder \"Demo Folder\"\n\n    \"${_NB}\" pin \"Demo Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    sleep 1\n\n    \"${_NB}\" add \"File Two.md\" --content \"Example content two.\"\n\n    sleep 1\n\n    \"${_NB}\" add folder \"Sample Folder\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n  }\n\n  run \"${_NB}\" folders list home:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                       ]]\n  [[   \"${lines[0]}\"  =~  .*[.*home:1.*].*\\ 📌\\ 📂\\ Demo\\ Folder  ]]\n  [[   \"${lines[1]}\"  =~  .*[.*home:5.*].*\\ 📂\\ Sample\\ Folder    ]]\n  [[   \"${lines[2]}\"  =~  .*[.*home:3.*].*\\ 📂\\ Example\\ Folder   ]]\n\n  run \"${_NB}\" folders home: list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                       ]]\n  [[   \"${lines[0]}\"  =~  .*[.*home:1.*].*\\ 📌\\ 📂\\ Demo\\ Folder  ]]\n  [[   \"${lines[1]}\"  =~  .*[.*home:5.*].*\\ 📂\\ Sample\\ Folder    ]]\n  [[   \"${lines[2]}\"  =~  .*[.*home:3.*].*\\ 📂\\ Example\\ Folder   ]]\n}\n"
  },
  {
    "path": "test/git.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031\n\nload test_helper\n\n# git checkpoint ##############################################################\n\n@test \"'git checkpoint' with no message and clean repo does not create new commit.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    printf \"New content.\\\\n\" >> \"${NB_DIR}/home/Example File.md\"\n\n    grep -q \"New content\" \"${NB_DIR}/home/Example File.md\"\n  }\n\n  run \"${_NB}\" git checkpoint\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q -v '\\[nb\\] Commit'\n}\n\n@test \"'git checkpoint' with no message and dirty repo creates a new commit with the default message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    printf \"New content.\\\\n\" >> \"${NB_DIR}/home/Example File.md\"\n\n    grep -q \"New content\" \"${NB_DIR}/home/Example File.md\"\n  }\n\n  run \"${_NB}\" git checkpoint\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Commit'\n}\n\n@test \"'git checkpoint <message>' with dirty repo creates a new commit with <message>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    printf \"New content.\\\\n\" >> \"${NB_DIR}/home/Example File.md\"\n\n    grep -q \"New content\" \"${NB_DIR}/home/Example File.md\"\n  }\n\n  run \"${_NB}\" git checkpoint \"Unique message.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q 'Unique message.'\n}\n\n# git dirty ###################################################################\n\n@test \"'git dirty' with dirty repo returns 0 and does not create commit.\" {\n  {\n    \"${_NB}\" init\n\n    touch \"${NB_DIR:?}/home/example.md\"\n\n    [[ -n \"$(git -C \"${NB_DIR:?}/home\" status --porcelain)\" ]]\n  }\n\n  run \"${_NB}\" git dirty\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # does not create git commit\n\n  sleep 1\n\n  git log | grep -v -q 'Commit'\n}\n\n@test \"'<notebook>:git dirty' with dirty repo returns 0 and does not create commit.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n\n    touch \"${NB_DIR:?}/one/example.md\"\n\n    [[ -n \"$(git -C \"${NB_DIR:?}/one\" status --porcelain)\" ]]\n  }\n\n  run \"${_NB}\" one:git dirty\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # does not create git commit\n\n  sleep 1\n\n  git log | grep -v -q 'Commit'\n}\n\n@test \"'git dirty' with clean repo returns 1 and does not create commit.\" {\n  {\n    \"${_NB}\" init\n\n    [[ -z \"$(git -C \"${NB_DIR:?}/home\" status --porcelain)\" ]]\n  }\n\n  run \"${_NB}\" git dirty\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 1\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # does not create git commit\n\n  sleep 1\n\n  git log | grep -v -q 'Commit'\n}\n\n@test \"'<notebook>:git dirty' with clean repo returns 1 and does not create commit.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n\n    [[ -z \"$(git -C \"${NB_DIR:?}/one\" status --porcelain)\" ]]\n  }\n\n  run \"${_NB}\" one:git dirty\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 1\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # does not create git commit\n\n  sleep 1\n\n  git log | grep -v -q 'Commit'\n}\n\n# git config ##################################################################\n\n@test \"'_git_required()' recognizes git configuration that uses 'includeIf' with 'hasconfig:remote' when inside the specified directory.\" {\n  {\n    export HOME=\"${_TMP_DIR}\"\n\n    git config --global user.name   \"Sample Name\"\n    git config --global user.email  \"sample@example.test\"\n\n    cat <<HEREDOC > \"${_TMP_DIR}/.gitconfig_conditional_include_example\"\n[user]\n  name  = Example Name\n  email = example@example.test\nHEREDOC\n\n    cat <<HEREDOC >> \"${_TMP_DIR}/.gitconfig\"\n[includeIf \"hasconfig:remote.*.url:file://${_TMP_DIR}*/**\"]\n  path = ${_TMP_DIR}/.gitconfig_conditional_include_example\nHEREDOC\n\n    cat \"${_TMP_DIR}/.gitconfig\"\n\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" notebooks create \"Example Notebook\"\n    \"${_NB}\" use \"Example Notebook\"\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" show home:1 --author\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                                       ]]\n  [[ \"${output}\" ==   \"Sample Name <sample@example.test>\"     ]]\n\n  run \"${_NB}\" show Example\\ Notebook:1 --author\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                                       ]]\n  [[ \"${output}\" ==   \"Example Name <example@example.test>\"   ]]\n}\n\n@test \"'_git_required()' recognizes git configuration that uses 'includeIf' when inside the specified directory.\" {\n  {\n    export HOME=\"${_TMP_DIR}\"\n\n    git config --global user.name   \"Example Name\"\n    git config --global user.email  \"example@example.test\"\n\n    cat <<HEREDOC > \"${_TMP_DIR}/.gitconfig_conditional_include_example\"\n[user]\n  name  = Sample Name\n  email = sample@example.test\nHEREDOC\n\n    cat <<HEREDOC >> \"${_TMP_DIR}/.gitconfig\"\n[includeIf \"gitdir:~/\"]\n  path = ${_TMP_DIR}/.gitconfig_conditional_include_example\nHEREDOC\n\n    cat \"${_TMP_DIR}/.gitconfig\"\n\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" show 1 --author\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                                     ]]\n  [[ \"${output}\" ==   \"Sample Name <sample@example.test>\"   ]]\n}\n\n@test \"'_git_required()' recognizes global git configuration  ignores 'includeIf' when outiside the specified directory.\" {\n  {\n    export HOME=\"${_TMP_DIR}\"\n\n    git config --global user.name   \"Example Name\"\n    git config --global user.email  \"example@example.test\"\n\n    cat <<HEREDOC > \"${_TMP_DIR}/.gitconfig_conditional_include_example\"\n[user]\n  name  = Sample Name\n  email = sample@example.test\nHEREDOC\n\n    cat <<HEREDOC >> \"${_TMP_DIR}/.gitconfig\"\n[includeIf \"gitdir:~/example-path\"]\n  path = ${_TMP_DIR}/.gitconfig_conditional_include_example\nHEREDOC\n\n    cat \"${_TMP_DIR}/.gitconfig\"\n\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" show 1 --author\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                                     ]]\n  [[ \"${output}\" ==   \"Example Name <example@example.test>\" ]]\n}\n\n@test \"'_git_required()' recognizes global git configuration for the user.\" {\n  {\n    export HOME=\"${_TMP_DIR}\"\n\n    git config --global user.name   \"Example Name\"\n    git config --global user.email  \"example@example.test\"\n\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" show 1 --author\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                                     ]]\n  [[ \"${output}\" ==   \"Example Name <example@example.test>\" ]]\n}\n"
  },
  {
    "path": "test/help.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2089,SC2090\n\nload test_helper\n\n# error handling ##############################################################\n\n@test \"'help example' exits with 0 and prints message.\" {\n  run \"${_NB}\" help example_name_123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                       ]]\n  [[ \"${#lines[@]}\" -eq 1                                       ]]\n\n  [[ \"${lines[0]}\"  =~  \\\nNo\\ additional\\ information\\ for\\ .*\\`.*example_name_123.*\\`.*$ ]]\n}\n\n@test \"'help example:' exits with 0 and prints message.\" {\n  run \"${_NB}\" help example:name:123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                       ]]\n  [[ \"${#lines[@]}\" -eq 1                                       ]]\n\n  [[ \"${lines[0]}\"  =~  \\\nNo\\ additional\\ information\\ for\\ .*\\`.*example:name:123.*\\`.*$ ]]\n}\n\n# color #######################################################################\n\n@test \"'help' and 'help <subcommand>' respect --no-color option.\" {\n  run \"${_NB}\" help --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                                           ]]\n  [[    \"${output}\" =~  \\\nnb\\ -h\\ \\|\\ \\-\\-help\\ \\|\\ help\\ \\[\\<subcommand\\>\\ \\|\\ \\-\\-readme\\]  ]]\n\n  run \"${_NB}\" help browse --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq  0                                          ]]\n  [[    \"${output}\" =~  \\[\\-s\\ \\|\\ \\-\\-serve\\]                      ]]\n}\n\n@test \"'help' and 'help <subcommand>' color usage.\" {\n  run \"${_NB}\" help\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                                                             ]]\n\n  [[    \"${output}\" =~  \\\nnb\\ -h\\ .*\\|.*\\ \\-\\-help\\ .*\\|.*\\ help\\ .*\\[.*\\<subcommand\\>\\ .*\\|.*\\ \\-\\-readme.*\\]  ]]\n  [[ !  \"${output}\" =~  \\\nnb\\ -h\\ \\|\\ \\-\\-help\\ \\|\\ help\\ \\[\\<subcommand\\>\\ \\|\\ \\-\\-readme\\]                    ]]\n\n  run \"${_NB}\" help browse\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq  0                              ]]\n\n  [[    \"${output}\" =~  \\[.*\\-s\\ .*\\|.*\\ \\-\\-serve.*\\]  ]]\n  [[ !  \"${output}\" =~  \\[\\-s\\ \\|\\ \\-\\-serve\\]          ]]\n}\n\n@test \"'help' and 'help <subcomman>' color hash in #tag* patterns.\" {\n  run \"${_NB}\" help\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0               ]]\n\n  [[ \"${output}\" =~   \\ .*#.*tagging  ]]\n\n  run \"${_NB}\" help browse\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0               ]]\n\n  [[ \"${output}\" =~   \\ .*#.*tags     ]]\n}\n\n# `help` ######################################################################\n\n@test \"'help' with no arguments exits with status 0 and prints default help.\" {\n  run \"${_NB}\" help\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                         ]]\n\n  [[ \"${output}\" =~   nb\\ help\\ \\<subcommand\\>  ]]\n  [[ \"${output}\" =~   nb\\ edit                  ]]\n}\n\n@test \"'-h' exits with 0 and prints default help.\" {\n  run \"${_NB}\" -h\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                       ]]\n\n  [[ \"${output}\" =~ nb\\ help\\ \\<subcommand\\>  ]]\n  [[ \"${output}\" =~ nb\\ edit                  ]]\n}\n\n@test \"'--help' exits with 0 and prints default help.\" {\n  run \"${_NB}\" --help\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                       ]]\n\n  [[ \"${output}\" =~ nb\\ help\\ \\<subcommand\\>  ]]\n  [[ \"${output}\" =~ nb\\ edit                  ]]\n}\n\n@test \"'help help' exits with 0 and prints 'help' subcommand usage.\" {\n  run \"${_NB}\" help help\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                       ]]\n\n  [[ \"${lines[17]}\" =~ Shortcut\\ Alias.*\\:$   ]]\n  [[ \"${lines[18]}\" =~ ^\\ \\ nb\\ h$            ]]\n}\n\n@test \"'help settings' exits with 0 and prints 'settings' subcommand usage.\" {\n  run \"${_NB}\" help settings\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq  0          ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:    ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ set ]]\n}\n\n@test \"'h settings' exits with 0 and prints 'settings' subcommand usage.\" {\n  run \"${_NB}\" h settings\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq  0          ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:    ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ set ]]\n}\n\n@test \"'--help settings' exits with 0 and prints 'settings' subcommand usage.\" {\n  run \"${_NB}\" --help settings\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq  0          ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:    ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ set ]]\n}\n\n@test \"'settings --help' exits with 0 and prints 'settings' subcommand usage.\" {\n  run \"${_NB}\" settings --help\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq  0          ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:    ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ set ]]\n}\n\n@test \"'-h settings' exits with 0 and prints 'settings' subcommand usage.\" {\n  run \"${_NB}\" -h settings\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq  0          ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:    ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ set ]]\n}\n\n@test \"'settings -h' exits with 0 and prints 'settings' subcommand usage.\" {\n  run \"${_NB}\" settings -h\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq  0          ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*:    ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ set ]]\n}\n"
  },
  {
    "path": "test/helpers-build-related-list.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'_build_related_list()' builds a Markdown-formatted list of related URLs and selectors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" helpers build_related_list \\\n    \"http://example.com\"                  \\\n    \"example:123\"                         \\\n    \"http://example.org\"                  \\\n    \"[[sample:456]]\"                      \\\n    \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0 ]]\n\n  diff                            \\\n    <(printf \"%s\\\\n\" \"${output}\") \\\n    <(cat <<HEREDOC\n- <http://example.com>\n- [[example:123]]\n- <http://example.org>\n- [[sample:456]]\n- [[Example Title]]\nHEREDOC\n    )\n}\n\n@test \"'_build_related_list()' prints nothing with no input.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" helpers build_related_list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output}\"         ]]\n}\n"
  },
  {
    "path": "test/helpers-file-is-text.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'_file_is_text()' returns status 0 for text file.\" {\n  run \"${_NB}\" helpers file_is_text \"${NB_TEST_BASE_PATH}/example.asciidoc\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_file_is_text()' returns status 1 for pdf file.\" {\n  run \"${_NB}\" helpers file_is_text \"${NB_TEST_BASE_PATH}/example.pdf\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 1  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_file_is_text()' returns status 1 for nonexistent file.\" {\n  run \"${_NB}\" helpers file_is_text \"${NB_TEST_BASE_PATH}/nonexistent\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 1  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_file_is_text()' returns status 1 for blank file path.\" {\n  run \"${_NB}\" helpers file_is_text \"\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 1  ]]\n  [[ -z \"${output}\"         ]]\n}\n"
  },
  {
    "path": "test/helpers-get-content.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `_get_content()` ##############################################################\n\n@test \"'_get_content()' prints first line when there are two lines.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example line one.${_NEWLINE}Example line two.\"\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                ]]\n  [[    \"${output}\"  ==  \"__first_line:Example line one.\" ]]\n}\n\n@test \"'_get_content()' prints first line when there is only one line.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"Example single line.\"\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                                    ]]\n  [[    \"${output}\"  ==  \"__first_line:Example single line.\"  ]]\n}\n\n@test \"'_get_content()' skips folders.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_get_content() --title' does not return first line when no .org title.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"one.org\"\n# Markdown Title in .org File\n\nline three (line two is blank)\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/one.org\" --title\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0               ]]\n  [[ -z \"${output}\"                      ]]\n  [[ !  \"${output}\"  =~  __first_line    ]]\n  [[ !  \"${output}\"  =~  Markdown\\ Title ]]\n}\n\n@test \"'_get_content() --title' detects and returns markdown titles.\" {\n  {\n    \"${_NB}\" init\n\n    cat <<HEREDOC | \"${_NB}\" add \"one.md\"\n# Title One\nline two\nline three\nline four\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"two.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"three.md\"\n# Title Three\nline two\nline three\nline four\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"four.md\"\n---\nsummary: Example Summary\ncustom: variable\n---\n# Title Four\nline six\nline seven\nline eight\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"five.md\"\n---\nsummary: Example Summary\ntitle: Title Five\ncustom: variable\n---\n# Second Title Five\nline seven\nline eight\nline nine\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"six.md\"\n---\nsummary: Example Summary\ncustom: variable\n---\nline five\nline six\nline seven\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"seven.md\"\nTitle Seven\n===========\n\nline four\nline five\nline six\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"eight.md\"\n---\nsummary: Example Summary\ncustom: variable\n---\n\n  Title Eight\n  ===========\n\nline nine\nline ten\nline eleven\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"nine.md\"\n---\nsummary: Example Summary\ncustom: variable\n---\nTitle Nine\n===========\n\nline nine\nline ten\nline eleven\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"ten.md\"\n# Title Ten #\nline two\nline three\nline four\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"eleven.md\"\n[](https://example.com/example.png)\n\n# Title Eleven\nline two\nline three\nline four\nHEREDOC\n\n    # shellcheck disable=SC2006\n    cat <<HEREDOC | \"${_NB}\" add \"twelve.md\"\n[](https://example.com/example.png)\n\n\\`\\`\\`text\n# Example In Code Block\n\\`\\`\\`\n\n# Title Twelve\nline two\nline three\nline four\nHEREDOC\n\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" list --no-color --reverse\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n\n  [[ ${status} -eq 0                                        ]]\n  [[ \"${lines[0]}\"  == \"[1]  Title One\"                     ]]\n  [[ \"${lines[1]}\"  == \"[2]  two.md · \\\"line one\\\"\"         ]]\n  [[ \"${lines[2]}\"  == \"[3]  Title Three\"                   ]]\n  [[ \"${lines[3]}\"  == \"[4]  Title Four\"                    ]]\n  [[ \"${lines[4]}\"  == \"[5]  Title Five\"                    ]]\n  [[ \"${lines[5]}\"  == \"[6]  six.md · \\\"line five\\\"\"        ]]\n  [[ \"${lines[6]}\"  == \"[7]  Title Seven\"                   ]]\n  [[ \"${lines[7]}\"  == \"[8]  Title Eight\"                   ]]\n  [[ \"${lines[8]}\"  == \"[9]  Title Nine\"                    ]]\n  [[ \"${lines[9]}\"  == \"[10] Title Ten\"                     ]]\n  [[ \"${lines[10]}\" == \"[11] Title Eleven\"                  ]]\n  [[ \"${lines[11]}\" == \"[12] Title Twelve\"                  ]]\n}\n\n@test \"'_get_content() --title' detects and returns org titles.\" {\n  {\n    \"${_NB}\" init\n\n    cat <<HEREDOC | \"${_NB}\" add \"one.org\"\n#+TITLE: Example Org Title\n\nline three\nline four\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"two.org\"\n#+TITLE: Example\n#+TITLE: Multi-Line\n#+TITLE: Org Title\n\nline three\nline four\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"three.org\"\n# -*- mode: org; coding: utf-8; -*-\n* Header Information                                               :noexport:\n#+TITLE: Example\n#+TITLE: Multi-Line\n#+TITLE: Org Title\n#+AUTHOR: Author Name\n\nline three\nline four\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"one.org\"\n#+title: Example Org Title With Lowercase Export Option\n\nline three\nline four\nHEREDOC\n\n    cat <<HEREDOC | \"${_NB}\" add \"two.org\"\n#+title: Example\n#+title: Multi-Line\n#+title: Org Title\n#+title: With Lowercase Export Option\n\nline three\nline four\nHEREDOC\n\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" list --no-color --reverse\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n\n  [[ \"${status}\"    -eq 0                                                               ]]\n  [[ \"${lines[0]}\"  ==  \"[1] Example Org Title\"                                         ]]\n  [[ \"${lines[1]}\"  ==  \"[2] Example Multi-Line Org Title\"                              ]]\n  [[ \"${lines[2]}\"  ==  \"[3] Example Multi-Line Org Title\"                              ]]\n  [[ \"${lines[3]}\"  ==  \"[4] Example Org Title With Lowercase Export Option\"            ]]\n  [[ \"${lines[4]}\"  ==  \"[5] Example Multi-Line Org Title With Lowercase Export Option\" ]]\n}\n\n@test \"'_get_content() --title' detects and returns LaTeX titles.\" {\n  {\n    \"${_NB}\" init\n\n    cat <<HEREDOC | \"${_NB}\" add \"one.latex\"\n\\documentclass{article}\n\\usepackage{graphicx}\n\n\\begin{document}\n\n\\title{Introduction to \\LaTeX{}}\n\\author{Author's Name}\n\n\\maketitle\n\n\\begin{abstract}\nThe abstract text goes here.\n\\end{abstract}\n\n\\section{Introduction}\nHere is the text of your introduction.\n\n\\begin{equation}\n    \\label{simple_equation}\n    \\alpha = \\sqrt{ \\beta }\n\\end{equation}\n\n\\subsection{Subsection Heading Here}\nWrite your subsection text here.\n\n\\begin{figure}\n    \\centering\n    \\includegraphics[width=3.0in]{myfigure}\n    \\caption{Simulation Results}\n    \\label{simulationfigure}\n\\end{figure}\n\n\\section{Conclusion}\nWrite your conclusion here.\n\n\\end{document}\nHEREDOC\n\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" list --no-color --reverse\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n\n  [[ ${status} -eq 0                                  ]]\n  [[ \"${lines[0]}\"  == \"[1] Introduction to \\LaTeX{}\" ]]\n}\n\n@test \"'_get_content() --title' detects and returns AsciiDoc titles.\" {\n  {\n    \"${_NB}\" init\n\n    cat <<HEREDOC | \"${_NB}\" add \"one.asciidoc\"\n= Example AsciiDoc Title\n\nExample AsciiDoc content.\nHEREDOC\n\n    sleep 1\n\n    cat <<HEREDOC | \"${_NB}\" add \"two.adoc\"\n= Sample AsciiDoc Title\n\nSample AsciiDoc content.\nHEREDOC\n\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" list --no-color --reverse\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"${lines[0]}\"  == \"[1] Example AsciiDoc Title\" ]]\n  [[ \"${lines[1]}\"  == \"[2] Sample AsciiDoc Title\"  ]]\n}\n\n@test \"'_get_content()' returns first line when no title.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"one.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/one.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status}    -eq 0                         ]]\n  [[ \"${output}\"  ==  \"__first_line:line one\"   ]]\n}\n\n@test \"'_get_content()' returns first line after newlines.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"two.md\"\n\n\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/two.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status}    -eq 0                         ]]\n  [[ \"${output}\"  ==  \"__first_line:line three\" ]]\n}\n\n@test \"'_get_content()' returns first line after code block.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"three.md\"\n\\`\\`\\`example\nexample=code\n\\`\\`\\`\n\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/three.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/three.md\"\n\n  [[ ${status}    -eq 0                       ]]\n  [[ \"${output}\"  ==  \"__first_line:line one\" ]]\n}\n\n@test \"'_get_content()' returns first line after code block and front matter.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"four.md\"\n---\nfront: matter\n---\n\n\\`\\`\\`example\nexample=code\n\\`\\`\\`\n\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/four.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status}    -eq 0                       ]]\n  [[ \"${output}\"  ==  \"__first_line:line one\" ]]\n}\n\n@test \"'_get_content()' returns first line after front matter.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"five.md\"\n---\nfront: matter\n---\n\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/five.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status}    -eq 0                       ]]\n  [[ \"${output}\"  ==  \"__first_line:line one\" ]]\n}\n\n@test \"'_get_content()' returns nothing with only code block and front matter.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"four.md\"\n---\nfront: matter\n---\n\n\\`\\`\\`example\nexample=code\n\\`\\`\\`\n\nHEREDOC\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/four.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status}    -eq 0 ]]\n  [[ -z \"${output}\"     ]]\n}\n\n@test \"'_get_content()' returns first line in Org file.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.org\"\n\n\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/example.org\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status}    -eq 0                         ]]\n  [[ \"${output}\"  ==  \"__first_line:line three\" ]]\n}\n\n@test \"'_get_content()' returns first line in LaTeX file.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.latex\"\n\n\n\\documentclass{article}\n\\usepackage{graphicx}\n\n\\begin{document}\n\n\\author{Author's Name}\n\n\\maketitle\n\n\\begin{abstract}\nThe abstract text goes here.\n\\end{abstract}\n\n\\section{Introduction}\nHere is the text of your introduction.\n\n\\begin{equation}\n    \\label{simple_equation}\n    \\alpha = \\sqrt{ \\beta }\n\\end{equation}\n\n\\subsection{Subsection Heading Here}\nWrite your subsection text here.\n\n\\begin{figure}\n    \\centering\n    \\includegraphics[width=3.0in]{myfigure}\n    \\caption{Simulation Results}\n    \\label{simulationfigure}\n\\end{figure}\n\n\\section{Conclusion}\nWrite your conclusion here.\n\n\\end{document}\nHEREDOC\n}\n\n  run \"${_NB}\" helpers get_content \"${NB_DIR}/home/example.latex\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status}    -eq 0                                       ]]\n  [[ \"${output}\"  ==  \"__first_line:\\\\documentclass{article}\" ]]\n}\n"
  },
  {
    "path": "test/helpers-get-id-selector.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# local #######################################################################\n\n@test \"'helpers get_id_selector <notebook-full-path> --notebook' in local notebook exits with 0 and prints local notebook selector.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n    \"${_NB}\" add  \"Example File.md\" \\\n      --title     \"Title One\"       \\\n      --content   \"Content one.\"\n\n    [[ -d \"${_TMP_DIR}/Example Local\"                 ]]\n    [[ -f \"${_TMP_DIR}/Example Local/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" helpers              \\\n    get_id_selector                 \\\n    \"${_TMP_DIR}/Example Local\"     \\\n    --notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0         ]]\n  [[   \"${#lines[@]}\" ==  1         ]]\n\n  [[   \"${lines[0]}\"  ==  \"local:\"  ]]\n}\n\n@test \"'helpers get_id_selector <id>/<id>/<id>/<id> --notebook' in local notebook exits with 0 and prints id selector with notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"Title One\"                                                 \\\n      --content   \"Content one.\"\n\n    [[ -d \"${_TMP_DIR}/Example Local/Example Folder\"        ]]\n    [[ -f \"${_TMP_DIR}/Example Local/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"1/1/1/1\"           \\\n    --notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0               ]]\n  [[   \"${#lines[@]}\" ==  1               ]]\n\n  [[   \"${lines[0]}\"  ==  \"local:1/1/1/1\" ]]\n}\n\n@test \"'helpers get_id_selector <id>/<id>/<id>/<id>' in local notebook exits with 0 and prints id selector without notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"Title One\"                                                 \\\n      --content   \"Content one.\"\n\n    [[ -d \"${_TMP_DIR}/Example Local/Example Folder\"        ]]\n    [[ -f \"${_TMP_DIR}/Example Local/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"1/1/1/1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0         ]]\n  [[   \"${#lines[@]}\" ==  1         ]]\n\n  [[   \"${lines[0]}\"  ==  \"1/1/1/1\" ]]\n}\n\n@test \"'helpers get_id_selector local:<id>/<id>/<id>/<id>' exits with 0 and prints id selector with notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"Title One\"                                                 \\\n      --content   \"Content one.\"\n\n    [[ -d \"${_TMP_DIR}/Example Local/Example Folder\"        ]]\n    [[ -f \"${_TMP_DIR}/Example Local/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"local:1/1/1/1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0               ]]\n  [[   \"${#lines[@]}\" ==  1               ]]\n\n  [[   \"${lines[0]}\"  ==  \"local:1/1/1/1\" ]]\n}\n\n@test \"'helpers get_id_selector /<notebook-path>/<folder>/<folder>/<folder>/<filename>' exits with 0 and prints id selector without notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"Title One\"                                                 \\\n      --content   \"Content one.\"\n\n    [[ -d \"${_TMP_DIR}/Example Local/Example Folder\"        ]]\n    [[ -f \"${_TMP_DIR}/Example Local/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" helpers                                                \\\n    get_id_selector                                                   \\\n    \"${_TMP_DIR}/Example Local/Example Folder/Sample Folder/Demo Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0               ]]\n  [[   \"${#lines[@]}\" ==  1               ]]\n\n  [[   \"${lines[0]}\"  ==  \"local:1/1/1/1\" ]]\n}\n\n@test \"'helpers get_id_selector /<notebook-path>/<folder>/<folder>/<folder>/<filename> --notebook' exits with 0 and prints id selector with notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"Title One\"                                                 \\\n      --content   \"Content one.\"\n\n    [[ -d \"${_TMP_DIR}/Example Local/Example Folder\"        ]]\n    [[ -f \"${_TMP_DIR}/Example Local/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" helpers                                                                    \\\n    get_id_selector                                                                       \\\n    \"${_TMP_DIR}/Example Local/Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n    --notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0               ]]\n  [[   \"${#lines[@]}\" ==  1               ]]\n\n  [[   \"${lines[0]}\"  ==  \"local:1/1/1/1\" ]]\n}\n\n@test \"'helpers get_id_selector <folder>/<folder>/<folder>/<filename> --notebook' exits with 0 and prints id selector with notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"Title One\"                                                 \\\n      --content   \"Content one.\"\n\n    [[ -d \"${_TMP_DIR}/Example Local/Example Folder\"        ]]\n    [[ -f \"${_TMP_DIR}/Example Local/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" helpers                                                \\\n    get_id_selector                                                   \\\n    \"local:Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n    --notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0               ]]\n  [[   \"${#lines[@]}\" ==  1               ]]\n\n  [[   \"${lines[0]}\"  ==  \"local:1/1/1/1\" ]]\n}\n\n@test \"'helpers get_id_selector <folder>/<folder>/<folder>/<filename>' exits with 0 and prints id selector without notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"Title One\"                                                 \\\n      --content   \"Content one.\"\n\n    [[ -d \"${_TMP_DIR}/Example Local/Example Folder\"        ]]\n    [[ -f \"${_TMP_DIR}/Example Local/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"Example Folder/Sample Folder/Demo Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0         ]]\n  [[   \"${#lines[@]}\" ==  1         ]]\n\n  [[   \"${lines[0]}\"  ==  \"1/1/1/1\" ]]\n}\n\n@test \"'helpers get_id_selector local:<folder>/<folder>/<folder>/<filename>' exits with 0 and prints id selector with notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local\"\n\n    cd \"${_TMP_DIR}/Example Local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/Example Local\" ]]\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"Title One\"                                                 \\\n      --content   \"Content one.\"\n\n    [[ -d \"${_TMP_DIR}/Example Local/Example Folder\"        ]]\n    [[ -f \"${_TMP_DIR}/Example Local/Example Folder/.index\" ]]\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"local:Example Folder/Sample Folder/Demo Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0               ]]\n  [[   \"${#lines[@]}\" ==  1               ]]\n\n  [[   \"${lines[0]}\"  ==  \"local:1/1/1/1\" ]]\n}\n\n# selectors ###################################################################\n\n@test \"'helpers get_id_selector <notebook>:<id>/<id>/<id>/<id>' exits with 0 and prints id selector.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"one\"                                                       \\\n      --content   \"Content one.\"\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"home:1/1/1/1\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0               ]]\n  [[   \"${#lines[@]}\" ==  1               ]]\n\n  [[   \"${lines[0]}\"  ==  \"home:1/1/1/1\"  ]]\n}\n\n# conflicting id / name #######################################################\n\n@test \"'helpers get_id_selector' favors id with conflicting id and folder name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n    \"${_NB}\" add \"Sample Folder/File One.md\" --content \"Example content.\"\n\n    \"${_NB}\" move \"Example Folder\"  \"2\" --force\n    \"${_NB}\" move \"Sample Folder\"   \"1\" --force\n\n    [[ -d \"${NB_DIR}/home/2\"              ]]\n    [[ -f \"${NB_DIR}/home/1/File One.md\"  ]]\n  }\n\n  run \"${_NB}\" helpers get_id_selector 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"2/\"              ]]\n\n  run \"${_NB}\" helpers get_id_selector 1/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"2/1\"             ]]\n\n  run \"${_NB}\" helpers get_id_selector 2/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"1/\"              ]]\n}\n\n# full path ###################################################################\n\n@test \"'helpers get_id_selector </full/path/to/file>' exits with 0 and prints id selector.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"one\"                                                       \\\n      --content   \"Content one.\"\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0         ]]\n  [[   \"${#lines[@]}\" ==  1         ]]\n\n  [[   \"${lines[0]}\"  ==  \"home:1/1/1/1\" ]]\n}\n\n# not-valid ###################################################################\n\n@test \"'helpers get_id_selector <not-valid/path>' exits with 1 and prints nothing.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"one\"                                                       \\\n      --content   \"Content one.\"\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"Example Folder/Not Valid/Demo Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1       ]]\n  [[    \"${#lines[@]}\"  ==  0       ]]\n\n  [[ -z \"${output}\"                 ]]\n}\n\n# get_id_selector #############################################################\n\n@test \"'helpers get_id_selector' resolves name to folder id selectors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File Example.md\"\n    \"${_NB}\" add \"Sample Folder/File Sample.md\"\n\n    \"${_NB}\" move \"Sample Folder\" \"1\" --force\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n    [[ -d \"${NB_DIR}/home/1\"              ]]\n  }\n\n  run \"${_NB}\" helpers get_id_selector 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                   ]]\n  [[ \"${output}\"  ==  \"1\"                 ]]\n\n  run \"${_NB}\" helpers get_id_selector 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                   ]]\n  [[ \"${output}\"  ==  \"2/\"                ]]\n\n  run \"${_NB}\" helpers get_id_selector 1/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                   ]]\n  [[ \"${output}\"  ==  \"2/1\"               ]]\n\n\n  run \"${_NB}\" helpers get_id_selector 1/File\\ Sample.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                   ]]\n  [[ \"${output}\"  ==  \"2/1\"               ]]\n\n  run \"${_NB}\" helpers get_id_selector Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                   ]]\n  [[ \"${output}\"  ==  \"1/\"                ]]\n\n  run \"${_NB}\" helpers get_id_selector Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                   ]]\n  [[ \"${output}\"  ==  \"1/1\"               ]]\n\n\n  run \"${_NB}\" helpers get_id_selector Example\\ Folder/File\\ Example.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                   ]]\n  [[ \"${output}\"  ==  \"1/1\"               ]]\n}\n\n@test \"'helpers get_id_selector <relative/path/to/file>' exits with 0 and prints id selector.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"one\"                                                       \\\n      --content   \"Content one.\"\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"Example Folder/Sample Folder/Demo Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0         ]]\n  [[   \"${#lines[@]}\" ==  1         ]]\n\n  [[   \"${lines[0]}\"  ==  \"1/1/1/1\" ]]\n}\n\n@test \"'helpers get_id_selector <relative/path/to/folder>/' (slash) exits with 0 and prints id selector to folder with trailing slash.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"one\"                                                       \\\n      --content   \"Content one.\"\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"Example Folder/Sample Folder/Demo Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0         ]]\n  [[   \"${#lines[@]}\" ==  1         ]]\n\n  [[   \"${lines[0]}\"  ==  \"1/1/1/\"  ]]\n}\n\n@test \"'helpers get_id_selector <relative/path/to/folder>' (no slash) exits with 0 and prints id selector to folder with no slash.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Sample Folder/Demo Folder/Example File.md\"  \\\n      --title     \"one\"                                                       \\\n      --content   \"Content one.\"\n  }\n\n  run \"${_NB}\" helpers  \\\n    get_id_selector     \\\n    \"Example Folder/Sample Folder/Demo Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0       ]]\n  [[   \"${#lines[@]}\" ==  1       ]]\n\n  [[   \"${lines[0]}\"  ==  \"1/1/1\" ]]\n}\n"
  },
  {
    "path": "test/helpers-get-unique-relative-path.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `_get_unique_relative_path()` ###############################################\n\n@test \"'_get_unique_relative_path()' with no arguments prints generated filename without extension.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0            ]]\n  [[ \"${lines[0]}\" =~ ^[0-9]+$  ]]\n}\n\n@test \"'_get_unique_relative_path()' prints generated filename without extension with one-level relative path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/.index\"\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \"Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/[0-9]+$ ]]\n}\n\n@test \"'_get_unique_relative_path()' prints generated filename without extension with two-level relative path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/.index\"\n\n    mkdir \"${NB_DIR}/home/Example Folder/Sample Folder\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \"Example Folder/Sample Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                          ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/Sample\\ Folder/[0-9]+$  ]]\n}\n\n# file extension ##############################################################\n\n@test \"'_get_unique_relative_path()' prints generated filename for extension.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \".rst\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0             ]]\n  [[ \"${lines[0]}\" =~ [0-9]+.rst ]]\n}\n\n@test \"'_get_unique_relative_path()' prints generated filename for extension with nested notebook path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${NB_DIR}/home/${NB_DIR}/home\"\n    touch \"${NB_DIR}/home/${NB_DIR}/home/.index\"\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \"${NB_DIR}/home/.rst\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"${lines[0]}\" =~ ${NB_DIR}/home/[0-9]+.rst  ]]\n}\n\n@test \"'_get_unique_relative_path()' prints generated filename for extension with one-level relative path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/.index\"\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \"Example Folder/.rst\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/[0-9]+.rst  ]]\n}\n\n@test \"'_get_unique_relative_path()' prints generated filename for extension with two-level relative path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/.index\"\n\n    mkdir \"${NB_DIR}/home/Example Folder/Sample Folder\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \"Example Folder/Sample Folder/.rst\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                            ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/Sample\\ Folder/[0-9]+.rst ]]\n}\n\n# file path ###################################################################\n\n@test \"'_get_unique_relative_path()' prints one-level file path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/example.txt\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"              ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/example.txt\"  ]]\n\n    run \"${_NB}\" list\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    \"${_NB}\" git log\n\n    [[ \"${status}\" -eq 0              ]]\n    [[ \"${output}\" =~ 1               ]]\n    [[ \"${output}\" =~ 📂              ]]\n    [[ \"${output}\" =~ Example\\ Folder ]]\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \"Example Folder/example.txt\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/example-1.txt ]]\n}\n\n@test \"'_get_unique_relative_path()' prints one-level folder path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/.index\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n\n    run \"${_NB}\" list\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    \"${_NB}\" git log\n\n    [[ \"${status}\" -eq 0              ]]\n    [[ \"${output}\" =~ 1               ]]\n    [[ \"${output}\" =~ 📂              ]]\n    [[ \"${output}\" =~ Example\\ Folder ]]\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                    ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder-1 ]]\n}\n\n@test \"'_get_unique_relative_path()' prints two-level file path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/.index\"\n\n    mkdir \"${NB_DIR}/home/Example Folder/Sample Folder\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/example.txt\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                            ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"              ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.txt\"  ]]\n\n    run \"${_NB}\" list\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    \"${_NB}\" git log\n\n    [[ \"${status}\" -eq 0              ]]\n    [[ \"${output}\" =~ 1               ]]\n    [[ \"${output}\" =~ 📂              ]]\n    [[ \"${output}\" =~ Example\\ Folder ]]\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path  \\\n    \"Example Folder/Sample Folder/example.txt\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                                ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/Sample\\ Folder/example-1.txt  ]]\n}\n\n@test \"'_get_unique_relative_path()' prints two-level folder path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/.index\"\n\n    mkdir \"${NB_DIR}/home/Example Folder/Sample Folder\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/example.txt\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                            ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"              ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"       ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/example.txt\"  ]]\n\n    run \"${_NB}\" list\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    \"${_NB}\" git log\n\n    [[ \"${status}\" -eq 0              ]]\n    [[ \"${output}\" =~ 1               ]]\n    [[ \"${output}\" =~ 📂              ]]\n    [[ \"${output}\" =~ Example\\ Folder ]]\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \"Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                    ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/Sample\\ Folder-1  ]]\n}\n\n@test \"'_get_unique_relative_path()' prints three-level file path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/.index\"\n\n    mkdir \"${NB_DIR}/home/Example Folder/Sample Folder\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n    mkdir \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/example.txt\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                        ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                          ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"              ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/example.txt\"  ]]\n\n    run \"${_NB}\" list\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    \"${_NB}\" git log\n\n    [[ \"${status}\" -eq 0              ]]\n    [[ \"${output}\" =~ 1               ]]\n    [[ \"${output}\" =~ 📂              ]]\n    [[ \"${output}\" =~ Example\\ Folder ]]\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path  \\\n    \"Example Folder/Sample Folder/Demo Folder/example.txt\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                                            ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/Sample\\ Folder/Demo\\ Folder/example-1.txt ]]\n}\n\n@test \"'_get_unique_relative_path()' prints three-level folder path.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${NB_DIR}/home/Example Folder\"\n    touch \"${NB_DIR}/home/Example Folder/.index\"\n\n    mkdir \"${NB_DIR}/home/Example Folder/Sample Folder\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"\n\n    mkdir \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\"\n    touch \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/example.txt\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                        ]]\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                          ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/.index\"                   ]]\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"              ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/.index\"       ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/example.txt\"  ]]\n\n    run \"${_NB}\" list\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    \"${_NB}\" git log\n\n    [[ \"${status}\" -eq 0              ]]\n    [[ \"${output}\" =~ 1               ]]\n    [[ \"${output}\" =~ 📂              ]]\n    [[ \"${output}\" =~ Example\\ Folder ]]\n  }\n\n  run \"${_NB}\" helpers get_unique_relative_path \"Example Folder/Sample Folder/Demo Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                                ]]\n  [[ \"${lines[0]}\" =~ Example\\ Folder/Sample\\ Folder/Demo\\ Folder-1 ]]\n}\n\n# types #######################################################################\n\n@test \"'_get_unique_relative_path()' works for notes.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\"\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ example-2.md  ]]\n}\n\n@test \"'_get_unique_relative_path()' works for encrypted notes.\" {\n  {\n    run \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\" \\\n    --encrypt --password password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ \"${lines[0]}\" =~ example.md.enc  ]]\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\" \\\n    --encrypt --password password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                    ]]\n  [[ \"${lines[0]}\" =~ example-1.md.enc  ]]\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\" \\\n    --encrypt --password password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                    ]]\n  [[ \"${lines[0]}\" =~ example-2.md.enc  ]]\n}\n\n@test \"'_get_unique_relative_path()' works for bookmarks.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.bookmark.md\" --content \"<https://example.com>\"\n  }\n\n  run \"${_NB}\" add \"example.bookmark.md\" --content \"<https://example.com>\"\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                        ]]\n  [[ \"${lines[0]}\" =~ example-1.bookmark.md ]]\n\n  run \"${_NB}\" add \"example.bookmark.md\" --content \"<https://example.com>\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                        ]]\n  [[ \"${lines[0]}\" =~ example-2.bookmark.md ]]\n}\n\n@test \"'_get_unique_relative_path()' works for encrypted bookmarks.\" {\n  {\n    run \"${_NB}\" init\n  }\n\n  run  \"${_NB}\" add \"example.bookmark.md\"   \\\n      --content \"<https://example.com>\"     \\\n      --encrypt --password password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${lines[0]}\" =~ example.bookmark.md.enc ]]\n\n  run \"${_NB}\" add \"example.bookmark.md\"  \\\n    --content \"<https://example.com>\"     \\\n    --encrypt --password password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${lines[0]}\" =~ example-1.bookmark.md.enc ]]\n\n  run \"${_NB}\" add \"example.bookmark.md\"  \\\n    --content \"<https://example.com>\"     \\\n    --encrypt --password password\n\n  [[ ${status} -eq 0 ]]\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${lines[0]}\" =~ example-2.bookmark.md.enc ]]\n}\n\n@test \"'_get_unique_relative_path()' works for encrypted conflicted bookmarks.\" {\n  {\n    local _filename=\"example.bookmark.md\"\n\n    run \"${_NB}\" init\n  }\n\n  run  \"${_NB}\" add \"${_filename%%.*}--conflicted-copy.${_filename#*.}\"   \\\n      --content \"<https://example.com>\"                                   \\\n      --encrypt --password password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                            ]]\n  [[ \"${lines[0]}\" =~ example--conflicted-copy.bookmark.md.enc  ]]\n\n  run \"${_NB}\" add \"example--conflicted-copy.bookmark.md\"   \\\n    --content \"<https://example.com>\"                       \\\n    --encrypt --password password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                              ]]\n  [[ \"${lines[0]}\" =~ example--conflicted-copy-1.bookmark.md.enc  ]]\n\n  run \"${_NB}\" add \"example--conflicted-copy.bookmark.md\"   \\\n    --content \"<https://example.com>\"                       \\\n    --encrypt --password password\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                                              ]]\n  [[ \"${lines[0]}\" =~ example--conflicted-copy-2.bookmark.md.enc  ]]\n}\n"
  },
  {
    "path": "test/helpers-get-uri.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'_get_uri()' encodes unencoded URLs.\" {\n  run \"${_NB}\" helpers get-uri http://example.com\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                             ]]\n  [[ \"${output}\"  ==  \"http%3A%2F%2Fexample.com\"    ]]\n\n  run \"${_NB}\" helpers get-uri --encode https://example.com\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                             ]]\n  [[ \"${output}\"  ==  \"https%3A%2F%2Fexample.com\"   ]]\n}\n\n@test \"'_get_uri()' decodes encoded URLs.\" {\n  run \"${_NB}\" helpers get-uri http%3A%2F%2Fexample.com\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                           ]]\n  [[ \"${output}\"  ==  \"http://example.com\"        ]]\n\n  run \"${_NB}\" helpers get-uri --decode https%3A%2F%2Fexample.com\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                           ]]\n  [[ \"${output}\"  ==  \"https://example.com\"       ]]\n}\n"
  },
  {
    "path": "test/helpers-highlight-syntax.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'_highlight_syntax_if_available()' with piped content and no arguments highlights as Markdown.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo '# Piped' | ${_NB} helpers highlight_syntax\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0          ]]\n  [[    \"${lines[0]}\"  =~  Piped      ]]\n  [[ !  \"${lines[0]}\"  ==  \"# Piped\"  ]]\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"${lines[0]}\") \\\n    <(printf \"%s\\\\n\" \"# Piped\")     \\\n    || true\n}\n\n@test \"'_highlight_syntax_if_available()' with piped content and language argument highlights as language.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo '# Piped' | ${_NB} helpers highlight_syntax txt\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0          ]]\n  [[    \"${lines[0]}\"  =~  Piped      ]]\n\n  diff                                                    \\\n    <(printf \"%s\\\\n\" \"${lines[0]}\")                       \\\n    <(echo '# Piped' | \"${_NB}\" helpers highlight_syntax) \\\n    || true\n}\n\n@test \"'_highlight_syntax_if_available()' with <path> highlights as extension.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                    \\\n      --filename  \"Example File.md\" \\\n      --title     \"Example Title\"   \\\n      --content   \"Example content with *formatting*.\"\n  }\n\n  run \"${_NB}\" helpers highlight_syntax \"${NB_DIR}/home/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                              ]]\n  [[    \"${lines[0]}\"  =~  \\#.*Example\\ Title                             ]]\n  [[ !  \"${lines[0]}\"  ==  \"# Example Title\"                              ]]\n  [[    \"${lines[1]}\"  =~  Example\\ content\\ with.*\\*.*formatting.*\\*.*\\. ]]\n  [[ !  \"${lines[1]}\"  ==  \"Example content with *formatting*.\"           ]]\n\n  diff                                                                    \\\n    <(printf \"%s\\\\n\" \"${output}\")                                         \\\n    <(\"${_NB}\" helpers highlight_syntax \"${NB_DIR}/home/Example File.md\")\n}\n\n@test \"'_highlight_syntax_if_available()' with .db extension skips --language option.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                    \\\n      --filename  \"Example File.md\" \\\n      --title     \"Example Title\"   \\\n      --content   \"Example content with *formatting*.\"\n\n    \"${_NB}\" add                    \\\n      --filename  \"Example File.db\" \\\n      --title     \"Example Title\"   \\\n      --content   \"Example content with *formatting*.\"\n  }\n\n  run \"${_NB}\" helpers highlight_syntax \"${NB_DIR}/home/Example File.db\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                              ]]\n  [[    \"${lines[0]}\"  =~  \\#.*Example\\ Title                             ]]\n  [[ !  \"${lines[0]}\"  ==  \"# Example Title\"                              ]]\n  [[    \"${lines[1]}\"  =~  Example\\ content\\ with.*\\*.*formatting.*\\*.*\\. ]]\n  [[ !  \"${lines[1]}\"  ==  \"Example content with *formatting*.\"           ]]\n\n  diff                                                                    \\\n    <(printf \"%s\\\\n\" \"${output}\")                                         \\\n    <(\"${_NB}\" helpers highlight_syntax \"${NB_DIR}/home/Example File.md\") \\\n    || true\n}\n"
  },
  {
    "path": "test/helpers-normalize-options.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'_normalize_options()' separates joined single-letter options.\" {\n  run \"${_NB}\" helpers print_normalized_options -abc\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 5                           ]]\n  [[ \"${lines[0]}\"  ==  \"helpers\"                   ]]\n  [[ \"${lines[1]}\"  ==  \"print_normalized_options\"  ]]\n  [[ \"${lines[2]}\"  ==  \"-a\"                        ]]\n  [[ \"${lines[3]}\"  ==  \"-b\"                        ]]\n  [[ \"${lines[4]}\"  ==  \"-c\"                        ]]\n}\n\n@test \"'_normalize_options()' retains multi-digit option.\" {\n  run \"${_NB}\" helpers print_normalized_options -123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 3                           ]]\n  [[ \"${lines[0]}\"  ==  \"helpers\"                   ]]\n  [[ \"${lines[1]}\"  ==  \"print_normalized_options\"  ]]\n  [[ \"${lines[2]}\"  ==  \"-123\"                      ]]\n}\n\n@test \"'_normalize_options()' keeps multiple digits together.\" {\n  run \"${_NB}\" helpers print_normalized_options -abc123edf45\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 10                          ]]\n  [[ \"${lines[0]}\"  ==  \"helpers\"                   ]]\n  [[ \"${lines[1]}\"  ==  \"print_normalized_options\"  ]]\n  [[ \"${lines[2]}\"  ==  \"-a\"                        ]]\n  [[ \"${lines[3]}\"  ==  \"-b\"                        ]]\n  [[ \"${lines[4]}\"  ==  \"-c\"                        ]]\n  [[ \"${lines[5]}\"  ==  \"-123\"                      ]]\n  [[ \"${lines[6]}\"  ==  \"-e\"                        ]]\n  [[ \"${lines[7]}\"  ==  \"-d\"                        ]]\n  [[ \"${lines[8]}\"  ==  \"-f\"                        ]]\n  [[ \"${lines[9]}\"  ==  \"-45\"                       ]]\n}\n"
  },
  {
    "path": "test/helpers-render.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC1072,SC1073\n\nload test_helper\n\n# checkboxes ##################################################################\n\n@test \"'_render' with todo item displays marked-up done / closed checkbox.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [x] Example todo one.\"\n  }\n\n  run \"${_NB}\" helpers render  \"${NB_DIR}/home/Example One.todo.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                    ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\#\\ \\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>x\\</span\\>      ]]\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>x\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>        ]]\n}\n\n@test \"'_render' with todo item displays marked-up undone / open checkbox (space).\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [ ] Example todo one.\"\n  }\n\n  run \"${_NB}\" helpers render  \"${NB_DIR}/home/Example One.todo.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                    ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\#\\ \\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>${_S}\\</span\\>  ]]\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>${_S}\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>    ]]\n}\n\n@test \"'_render' with todo item displays marked-up undone / open checkbox (no space).\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [] Example todo one.\"\n  }\n\n  run \"${_NB}\" helpers render  \"${NB_DIR}/home/Example One.todo.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                    ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\#\\ \\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>${_S}\\</span\\>  ]]\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>${_S}\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>    ]]\n}\n\n@test \"'_render --pandoc' with todo item displays marked-up done / closed checkbox.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [x] Example todo one.\"\n  }\n\n  run \"${_NB}\" helpers render  \"${NB_DIR}/home/Example One.todo.md\" --pandoc\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                    ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<h1\\ id=\\\"x-example-todo-one.\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>              ]]\n  [[    \"${output}\"    =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>x\\</span\\>                                 ]]\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>x\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>      ]]\n}\n\n@test \"'_render --pandoc' with todo item displays marked-up undone / open checkbox (space).\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [ ] Example todo one.\"\n  }\n\n  run \"${_NB}\" helpers render  \"${NB_DIR}/home/Example One.todo.md\" --pandoc\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                    ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<h1\\ id=\\\"example-todo-one.\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>                ]]\n  [[    \"${output}\"    =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>${_S}\\</span\\>                             ]]\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>${_S}\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>  ]]\n}\n\n@test \"'_render --pandoc' with todo item displays marked-up undone / open checkbox (no space).\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.todo.md\" --content \"# [] Example todo one.\"\n  }\n\n  run \"${_NB}\" helpers render  \"${NB_DIR}/home/Example One.todo.md\" --pandoc\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                    ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>  ]]\n\n  [[    \"${output}\"    =~  \\\n\\<h1\\ id=\\\"example-todo-one.\\\"\\>\\<span\\ class=\\\"muted\\\"\\>\\[\\</span\\>                ]]\n  [[    \"${output}\"    =~  \\\n\\[\\</span\\>\\<span\\ class=\\\"identifier\\\"\\>${_S}\\</span\\>                             ]]\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"identifier\\\"\\>${_S}\\<\\/span\\>\\<span\\ class=\\\"muted\\\"\\>\\]\\<\\/span\\>  ]]\n}\n\n# <title> #####################################################################\n\n@test \"'_render --title <title>' sets HTML '<title></title>' to <title>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File One.md\"   \\\n      --title     \"Example Title One\"     \\\n      --content   \"Example content one.\"\n  }\n\n  run \"${_NB}\" helpers render             \\\n    \"${NB_DIR}/home/Example File.md\"      \\\n    --title \"Example HTML Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                      ]]\n  [[    \"${output}\"    =~  \\<title\\>Example\\ HTML\\ Title\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                    ]]\n}\n\n@test \"'_render' without '--title' sets HTML '<title></title>' to default.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File One.md\"   \\\n      --title     \"Example Title One\"     \\\n      --content   \"Example content one.\"\n  }\n\n  run \"${_NB}\" helpers render             \\\n    \"${NB_DIR}/home/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                      ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>    ]]\n  [[    \"${output}\"    =~  \\<title\\>nb\\</title\\>  ]]\n}\n\n@test \"'_render --title <title> --pandoc' sets HTML '<title></title>' to <title>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File One.md\"   \\\n      --title     \"Example Title One\"     \\\n      --content   \"Example content one.\"\n  }\n\n  run \"${_NB}\" helpers render             \\\n    \"${NB_DIR}/home/Example File.md\"      \\\n    --pandoc                              \\\n    --title \"Example HTML Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                        ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                      ]]\n  [[    \"${output}\"    =~  \\<title\\>Example\\ HTML\\ Title\\</title\\>  ]]\n  [[ !  \"${output}\"    =~  \\<title\\>nb\\</title\\>                    ]]\n}\n\n@test \"'_render --pandoc' without '--title' sets HTML '<title></title>' to default.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File One.md\"   \\\n      --title     \"Example Title One\"     \\\n      --content   \"Example content one.\"\n  }\n\n  run \"${_NB}\" helpers render             \\\n    \"${NB_DIR}/home/Example File.md\"      \\\n    --pandoc\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                      ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>    ]]\n  [[    \"${output}\"    =~  \\<title\\>nb\\</title\\>  ]]\n}\n\n# empty <p> elements ##########################################################\n\n@test \"'_render --pandoc' with markdown file preserves empty <p> elements after '## Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" \\\n      --content   \"$(<<HEREDOC cat\n<https://example.test>\n\n## Description\n\nDescription paragraph one.\n\n \n\nDescription paragraph three.\n\n## Content\n\nContent paragraph one.\n\n \n\nContent paragraph three.\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.md\" --pandoc\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                                 ]]\n  [[    \"${output}\"   =~  \\<\\!DOCTYPE\\ html\\>               ]]\n\n  [[    \"${output}\"   =~  \\\n.*\\<h2\\ id=\\\"description\\\"\\>Description\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ one.\\<\\/p\\>${_NEWLINE}\\\n.*\\<p\\>\\ \\</p\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ three\\.\\</p\\>${_NEWLINE}\\\n.*\\<h2\\ id=\\\"content\\\"\\>Content\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ one\\.\\</p\\>${_NEWLINE}\\\n.*\\<p\\>\\ \\</p\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ three\\.\\</p\\>                    ]]\n}\n\n@test \"'_render --bookmark --pandoc' with markdown file strips empty <p> elements after '## Page Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" \\\n      --content   \"$(<<HEREDOC cat\n<https://example.test>\n\n## Description\n\nDescription paragraph one.\n\n \n\nDescription paragraph three.\n\n## Page Content\n\nContent paragraph one.\n\n \n\nContent paragraph three.\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.md\" --bookmark --pandoc\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                                 ]]\n  [[    \"${output}\"   =~  \\<\\!DOCTYPE\\ html\\>               ]]\n\n  [[    \"${output}\"   =~ \\\n.*\\<h2\\ id=\\\"description\\\"\\>Description\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ one.\\<\\/p\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ three\\.\\</p\\>${_NEWLINE}\\\n.*\\<h2\\ id=\\\"page-content\\\"\\>Page\\ Content\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ one\\.\\</p\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ three\\.\\</p\\>                    ]]\n\n  [[ !  \"${output}\"   =~ \\\n.*\\<p\\>Content\\ paragraph\\ one\\.\\</p\\>${_NEWLINE}\\\n.*\\<p\\>\\ \\</p\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ three\\.\\</p\\>                    ]]\n\n}\n\n@test \"'_render --bookmark --pandoc' with markdown file strips empty <p> elements after '## Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" \\\n      --content   \"$(<<HEREDOC cat\n<https://example.test>\n\n## Description\n\nDescription paragraph one.\n\n \n\nDescription paragraph three.\n\n## Content\n\nContent paragraph one.\n\n \n\nContent paragraph three.\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.md\" --bookmark --pandoc\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                                 ]]\n  [[    \"${output}\"   =~  \\<\\!DOCTYPE\\ html\\>               ]]\n\n  [[    \"${output}\"   =~ \\\n.*\\<h2\\ id=\\\"description\\\"\\>Description\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ one.\\<\\/p\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ three\\.\\</p\\>${_NEWLINE}\\\n.*\\<h2\\ id=\\\"content\\\"\\>Content\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ one\\.\\</p\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ three\\.\\</p\\>                    ]]\n\n  [[ !  \"${output}\"   =~ \\\n.*\\<p\\>Content\\ paragraph\\ one\\.\\</p\\>${_NEWLINE}\\\n.*\\<p\\>\\ \\</p\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ three\\.\\</p\\>                    ]]\n}\n\n@test \"'_render --bookmark' with html file strips empty <p> elements after '## Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.html\" \\\n      --content   \"$(<<HEREDOC cat\n<p><a href=\"https://example.test\">https://example.test</a></p>\n<h2 id=\"description\">Description</h2>\n<p>Description paragraph one.</p>\n<p> </p>\n<p>Description paragraph three.</p>\n<h2 id=\"content\">Content</h2>\n<p>Content paragraph one.</p>\n<p> </p>\n<p>Content paragraph three.</p>\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.html\" --bookmark\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                                 ]]\n  [[    \"${output}\"   =~  \\<\\!DOCTYPE\\ html\\>               ]]\n\n  [[    \"${output}\"   =~ \\\n.*\\<h2\\ id=\\\"description\\\"\\>Description\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ one.\\<\\/p\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ three\\.\\</p\\>${_NEWLINE}\\\n.*\\<h2\\ id=\\\"content\\\"\\>Content\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ one\\.\\</p\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ three\\.\\</p\\>                    ]]\n\n  [[ !  \"${output}\"   =~ \\\n.*\\<p\\>Content\\ paragraph\\ one\\.\\</p\\>${_NEWLINE}\\\n.*\\<p\\>\\ \\</p\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ three\\.\\</p\\>                    ]]\n}\n\n@test \"'_render --bookmark' with html file strips empty <p> elements after '## Page Content' heading\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.html\" \\\n      --content   \"$(<<HEREDOC cat\n<p><a href=\"https://example.test\">https://example.test</a></p>\n<h2 id=\"description\">Description</h2>\n<p>Description paragraph one.</p>\n<p> </p>\n<p>Description paragraph three.</p>\n<h2 id=\"page-content\">Page Content</h2>\n<p>Content paragraph one.</p>\n<p> </p>\n<p>Content paragraph three.</p>\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.html\" --bookmark\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                                 ]]\n  [[    \"${output}\"   =~  \\<\\!DOCTYPE\\ html\\>               ]]\n\n  [[    \"${output}\"   =~ \\\n.*\\<h2\\ id=\\\"description\\\"\\>Description\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ one.\\<\\/p\\>${_NEWLINE}\\\n.*\\<p\\>Description\\ paragraph\\ three\\.\\</p\\>${_NEWLINE}\\\n.*\\<h2\\ id=\\\"page-content\\\"\\>Page\\ Content\\</h2\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ one\\.\\</p\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ three\\.\\</p\\>                    ]]\n\n  [[ !  \"${output}\"   =~ \\\n.*\\<p\\>Content\\ paragraph\\ one\\.\\</p\\>${_NEWLINE}\\\n.*\\<p\\>\\ \\</p\\>${_NEWLINE}\\\n.*\\<p\\>Content\\ paragraph\\ three\\.\\</p\\>                    ]]\n}\n\n# <img> tags ##################################################################\n\n@test \"'_render --pandoc' with markdown file preserves <img> tags after '## Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" \\\n      --content   \"$(<<HEREDOC cat\n<https://example.test>\n\n## Description\n\nExample image one: ![Example Image One](/not-valid-1.png)\n\n## Content\n\nMore example ![Example Image Two](/not-valid-2.png) content ![Example Image Three](/not-valid-3.png) here.\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.md\" --pandoc\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ image\\ one:\\ \\<img\\ src=\\\"/not-valid-1.png\\\"\\ alt=\\\"Example\\ Image\\ One\\\"\\ /\\>\\</p\\>  ]]\n  [[    \"${output}\"    =~  \\\n\\<p\\>More\\ example\\ \\<img\\ src=\\\"/not-valid-2.png\\\"\\ alt=\\\"Example\\ Image\\ Two\\\"\\ /\\>\\ content\\     ]]\n  [[    \"${output}\"    =~  \\\n\\ content\\ \\<img\\ src=\\\"/not-valid-3.png\\\"\\ alt=\\\"Example\\ Image\\ Three\\\"\\ /\\>\\ here.\\</p\\>         ]]\n}\n\n@test \"'_render --bookmark --pandoc' with markdown file strips <img> tags after '## Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" \\\n      --content   \"$(<<HEREDOC cat\n<https://example.test>\n\n## Description\n\nExample image one: ![Example Image One](/not-valid-1.png)\n\n## Content\n\nMore example ![Example Image Two](/not-valid-2.png) content ![Example Image Three](/not-valid-3.png) here.\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.md\" --bookmark --pandoc\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ image\\ one:\\ \\<img\\ src=\\\"/not-valid-1.png\\\"\\ alt=\\\"Example\\ Image\\ One\\\"\\ /\\>\\</p\\>  ]]\n  [[    \"${output}\"    =~  \\<p\\>More\\ example\\ \\ content\\ \\ here.\\</p\\> ]]\n}\n\n@test \"'_render --bookmark --pandoc' with markdown file strips <img> tags after '## Page Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" \\\n      --content   \"$(<<HEREDOC cat\n<https://example.test>\n\n## Description\n\nExample image one: ![Example Image One](/not-valid-1.png)\n\n## Page Content\n\nMore example ![Example Image Two](/not-valid-2.png) content ![Example Image Three](/not-valid-3.png) here.\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.md\" --bookmark --pandoc\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ image\\ one:\\ \\<img\\ src=\\\"/not-valid-1.png\\\"\\ alt=\\\"Example\\ Image\\ One\\\"\\ /\\>\\</p\\>  ]]\n  [[    \"${output}\"    =~  \\<p\\>More\\ example\\ \\ content\\ \\ here.\\</p\\> ]]\n}\n\n@test \"'_render --bookmark' with html file strips <img> tags after '## Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.html\" \\\n      --content   \"$(<<HEREDOC cat\n<p><a href=\"https://example.test\" class=\"uri\">https://example.test</a></p>\n<h2 id=\"description\">Description</h2>\n<p>Example image one: <img src=\"/not-valid-1.png\" alt=\"Example Image One\" /></p>\n<h2 id=\"content\">Content</h2>\n<p>More example <img src=\"/not-valid-2.png\" alt=\"Example Image Two\" /> content <img src=\"/not-valid-3.png\" alt=\"Example Image Three\" /> here.</p>\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.html\" --bookmark\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ image\\ one:\\ \\<img\\ src=\\\"/not-valid-1.png\\\"\\ alt=\\\"Example\\ Image\\ One\\\"\\ /\\>\\</p\\>  ]]\n  [[    \"${output}\"    =~  \\<p\\>More\\ example\\ \\ content\\ \\ here.\\</p\\> ]]\n}\n\n@test \"'_render --bookmark' with html file strips <img> tags after '## Page Content' heading.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.html\" \\\n      --content   \"$(<<HEREDOC cat\n<p><a href=\"https://example.test\" class=\"uri\">https://example.test</a></p>\n<h2 id=\"description\">Description</h2>\n<p>Example image one: <img src=\"/not-valid-1.png\" alt=\"Example Image One\" /></p>\n<h2 id=\"page-content\">Page Content</h2>\n<p>More example <img src=\"/not-valid-2.png\" alt=\"Example Image Two\" /> content <img src=\"/not-valid-3.png\" alt=\"Example Image Three\" /> here.</p>\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.html\" --bookmark\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[    \"${output}\"    =~  \\\n\\<p\\>Example\\ image\\ one:\\ \\<img\\ src=\\\"/not-valid-1.png\\\"\\ alt=\\\"Example\\ Image\\ One\\\"\\ /\\>\\</p\\>  ]]\n  [[    \"${output}\"    =~  \\<p\\>More\\ example\\ \\ content\\ \\ here.\\</p\\> ]]\n}\n\n# code ########################################################################\n\n@test \"'_render' with .js file serves file in a code block.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.js\" --content \"console.log(\\\"hello\\\");\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.js\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                     ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>   ]]\n\n  [[ \"${output}\"    =~  \\<code\\>              ]]\n  [[ \"${output}\"    =~  \\</code\\>             ]]\n  [[ \"${output}\"    =~  \\\"hello\\\"             ]]\n}\n\n@test \"'_render --pandoc' with .js file serves file in a code block.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.js\" --content \"console.log(\\\"hello\\\");\"\n  }\n\n  run \"${_NB}\" helpers render --pandoc \"${NB_DIR}/home/Example File.js\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                 ]]\n\n  [[ \"${output}\"    =~  \\<div\\ class=\\\"sourceCode\\\"         ]]\n  [[ \"${output}\"    =~  \\<pre\\ class=\\\"sourceCode\\ js\\\"\\>   ]]\n  [[ \"${output}\"    =~  \\&quot\\;hello\\&quot\\;               ]]\n}\n\n@test \"'_render --pandoc' with .bash file serves file in a code block.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.bash\" --content \"echo \\\"hello\\\"\"\n  }\n\n  run \"${_NB}\" helpers render --pandoc \"${NB_DIR}/home/Example File.bash\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                 ]]\n\n  [[ \"${output}\"    =~  \\<div\\ class=\\\"sourceCode\\\"         ]]\n  [[ \"${output}\"    =~  \\<pre\\ class=\\\"sourceCode\\ bash\\\"\\> ]]\n  [[ \"${output}\"    =~  \\&quot\\;hello\\&quot\\;               ]]\n}\n\n# with pandoc #################################################################\n\n@test \"'_render --pandoc' prints complete HTML document with piped input.\" {\n  echo \"<span class=\\\"sample-class\\\">Example content.</span>\" | {\n    run \"${_NB}\" helpers render --pandoc\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"  -eq 0 ]]\n\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"<!DOCTYPE html>\"\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"<head>\"\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"<body>\"\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n\n    printf \"%s\\\\n\" \"${output}\" | grep -q \\\n      \"<span class=\\\"sample-class\\\">Example content.</span>\"\n  }\n}\n\n@test \"'_render --pandoc' prints complete HTML document with string input.\" {\n  run \"${_NB}\" helpers render  --pandoc \\\n    \"<span class=\\\"sample-class\\\">Example content.</span>\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<!DOCTYPE html>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<head>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<body>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"<span class=\\\"sample-class\\\">Example content.</span>\"\n}\n\n@test \"'_render --pandoc' prints markdown document converted to HTML with file input.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" \\\n      --title     \"Example Title\" \\\n      --content   \"Example content with *formatting* and [a link](https://example.test)\"\n  }\n\n  run \"${_NB}\" helpers render  --pandoc \"${NB_DIR}/home/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<!DOCTYPE html>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<head>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<body>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"<h1 id=\\\"example-title\\\">Example Title</h1>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"Example content with <em>formatting</em> and <a rel=\\\"noopener noreferrer\\\" href=\\\"https://example.test\\\">a link</a>\"\n}\n\n# without pandoc ##############################################################\n\n@test \"'_render' prints complete HTML document with piped input.\" {\n  echo \"<span class=\\\"sample-class\\\">Example content.</span>\" | {\n    run \"${_NB}\" helpers render\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"  -eq 0 ]]\n\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"<!DOCTYPE html>\"\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"<head>\"\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"<body>\"\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n    printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n\n    printf \"%s\\\\n\" \"${output}\" | grep -q \\\n      \"<span class=\\\"sample-class\\\">Example content.</span>\"\n  }\n}\n\n@test \"'_render' prints complete HTML document with string input.\" {\n  run \"${_NB}\" helpers render \\\n    \"<span class=\\\"sample-class\\\">Example content.</span>\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<!DOCTYPE html>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<head>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<body>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"<span class=\\\"sample-class\\\">Example content.</span>\"\n}\n\n@test \"'_render' prints raw markdown document with file input.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" \\\n      --title     \"Example Title\" \\\n      --content   \"Example content with *formatting* and [a link](https://example.test)\"\n  }\n\n  run \"${_NB}\" helpers render \"${NB_DIR}/home/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<!DOCTYPE html>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<head>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"<body>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"</body>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"# Example Title\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"Example content with \\*formatting\\* and \\[a link\\](https://example.test)\"\n}\n"
  },
  {
    "path": "test/helpers-resolve-links.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# error handling ##############################################################\n\n@test \"'_resolve_links' return status 1 and prints nothing when passed blank argument.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" helpers resolve_links \"\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 1  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n# local #######################################################################\n\n@test \"'_resolve_links --browse' with .org resolves local notebook links.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    declare _content=\n    _content+=\"Selector link one: [[local:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[local:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag three: #tag-3/nested-1 • \"\n    _content+=\"Tag four: #tag-4/nested-2/nested-3 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"Org mode link: [[http://example.com]] • \"\n    _content+=\"Org mode link with description: [[http://example.com][Example Description (more)]] • \"\n    _content+=\"Internal Org mode link: [[#sample]] • \"\n\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"${_NEWLINE}#tag4 #tag5 #tag6 #tag7${_NEWLINE}\"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.org\"  \\\n      --title     \"Example Org Mode Title\"                    \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n\n    declare _expected_params=\"?--columns=70&--limit=2&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n    --browse                            \\\n    \"${_TMP_DIR}/Local Notebook\"        \\\n    --type org                          \\\n    --page 123 --limit 2             \\\n    --terminal < \"${_TMP_DIR}/Local Notebook/Sample Folder/Sample Nested File One.org\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link one: \\[\\[//localhost:6789/local:2/1${_expected_params}\\]\\[\\[\\[local:2/1\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link two: \\[\\[//localhost:6789/local:3${_expected_params}\\]\\[\\[\\[Root Title One\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link one: \\[\\[//localhost:6789/local:2/1${_expected_params}\\]\\[\\[\\[Example label.\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link two: \\[\\[//localhost:6789/local:3${_expected_params}\\]\\[\\[\\[Sample label.\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag one: \\[\\[//localhost:6789/local:${_expected_params}&--query=%23tag_1\\]\\[#tag_1\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag two: \\[\\[//localhost:6789/local:${_expected_params}&--query=%23tag-2\\]\\[#tag-2\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag three: \\[\\[//localhost:6789/local:${_expected_params}&--query=%23tag-3\\/nested-1\\]\\[#tag-3\\/nested-1\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag four: \\[\\[//localhost:6789/local:${_expected_params}&--query=%23tag-4\\/nested-2\\/nested-3\\]\\[#tag-4\\/nested-2\\/nested-3\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Org mode link: \\[\\[//localhost:6789?url=http%3A%2F%2Fexample.com\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Org mode link with description: \\[\\[//localhost:6789?url=http%3A%2F%2Fexample.com\\]\\[Example Description (more)\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Internal Org mode link: \\[\\[#sample\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^\\[\\[//localhost:6789/local:${_expected_params}&--query=%23tag3\\]\\[#tag3\\]\\]$\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^\\[\\[//localhost:6789/local:${_expected_params}&--query=%23tag4\\]\\[#tag4\\]\\] \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" \\[\\[//localhost:6789/local:${_expected_params}&--query=%23tag5\\]\\[#tag5\\]\\] \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" \\[\\[//localhost:6789/local:${_expected_params}&--query=%23tag6\\]\\[#tag6\\]\\] \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" \\[\\[//localhost:6789/local:${_expected_params}&--query=%23tag7\\]\\[#tag7\\]\\]\"\n}\n\n@test \"'_resolve_links --browse' with .html resolves local notebook links.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    declare _content=\n    _content+=\"Selector link one: [[local:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[local:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag three: #tag-3/nested-1 • \"\n    _content+=\"Tag four: #tag-4/nested-2/nested-3 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"#tag4 #tag5 #tag6 #tag7${_NEWLINE}${_NEWLINE}\"\n    _content+=\"[Example Outbound Link One](http://example.com) • \"\n    _content+=\"[Example Outbound Link Two](https://test.test) • \"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.md\"   \\\n      --title     \"Sample Nested Title One\"                   \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n\n    declare _html_file_path=\"${_TMP_DIR}/unlinked.html\"\n    touch \"${_html_file_path:?}\"\n\n    cd \"${_TMP_DIR}\"\n    git init &>/dev/null\n\n    pandoc                              \\\n      --from=markdown                   \\\n      --to=html                         \\\n      --output=\"${_html_file_path}\"     \\\n      --wrap=preserve                   \\\n      \"${_TMP_DIR}/Local Notebook/Sample Folder/Sample Nested File One.md\"\n\n    [[ \"$(cat \"${_html_file_path}\")\" =~ \\<h1\\ id=\\\"sample-nested-title-one ]]\n\n    printf \"\\\\n#tag8 #tag9\\\\n\" >> \"${_html_file_path}\"\n\n    declare _expected_params=\"?--columns=70&--limit=2&--local=${_TMP_DIR//$'/'/%2F}%2FLocal%20Notebook\"\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n    --browse                            \\\n    \"${_TMP_DIR}/Local Notebook\"        \\\n    --page 123 --limit 2 --terminal  < \"${_html_file_path}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link one: <a.* href=\\\"//localhost:6789/local:2/1${_expected_params}\\\">\\[\\[local:2/1\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link two: <a.* href=\\\"//localhost:6789/local:Root Title One${_expected_params}\\\">\\[\\[Root Title One\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link one: <a.* href=\\\"//localhost:6789/local:2/1${_expected_params}\\\">\\[\\[Example label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link two: <a.* href=\\\"//localhost:6789/local:Root Title One${_expected_params}\\\">\\[\\[Sample label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag one: <a.* href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag_1\\\">#tag_1</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag two: <a.* href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag-2\\\">#tag-2</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag three: <a.* href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag-3/nested-1\\\">#tag-3/nested-1</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag four: <a.* href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag-4/nested-2/nested-3\\\">#tag-4/nested-2/nested-3</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag3\\\">#tag3</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag4\\\">#tag4</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" <a.* href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag5\\\">#tag5</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" <a.* href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag6\\\">#tag6</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" <a.* href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag7\\\">#tag7</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789?url=http%3A%2F%2Fexample.com\\\">Example Outbound Link One</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a.* href=\\\"//localhost:6789?url=https%3A%2F%2Ftest.test\\\">Example Outbound Link Two</a> •</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag8\\\">#tag8</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/local:${_expected_params}&--query=%23tag9\\\">#tag9</a>\"\n}\n\n# <nav>, <code>, and <h2>Content</h2> #########################################\n\n@test \"'_resolve_links --browse' with non-bookmark .html skips nav and code sections and does not skip <h2>Content</h2>.\" {\n  {\n    \"${_NB}\" init\n\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.md\"   \\\n      --title     \"Sample Nested Title One\"                   \\\n      --content   \"$(cat <<HEREDOC\n[[1]]\n#one\n\n<nav>\n[[2]]\n#two\n</nav>\n\n[[3]]\n#three\n\n\\`\\`\\`\ncode-one\n[[4]]\n#four\ncode-two\n\\`\\`\\`\n\nExample content line [[5]] #five without inline code.\n\nExample content line [[6]] #six with \\`[[7]] #seven\\` inline code.\n\n## Content\n\n[[8]]\n#eight\n\n#nine\nHEREDOC\n)\"\n\n    \"${_NB}\" add  \"Root File One.md\"    \\\n      --title     \"Root Title One\"      \\\n      --content   \"Root content one.\"\n\n    \"${_NB}\" add  \"Root File Two.md\"    \\\n      --title     \"Root Title Two\"      \\\n      --content   \"Root content two.\"\n\n    \"${_NB}\" add  \"Root File Three.md\"  \\\n      --title     \"Root Title Three\"    \\\n      --content   \"Root content three.\"\n\n    \"${_NB}\" add  \"Root File Four.md\"   \\\n      --title     \"Root Title Four\"     \\\n      --content   \"Root content four.\"\n\n    \"${_NB}\" add  \"Root File Five.md\"   \\\n      --title     \"Root Title Five\"     \\\n      --content   \"Root content five.\"\n\n    declare _html_file_path=\"${_TMP_DIR}/unlinked.html\"\n    touch \"${_html_file_path:?}\"\n\n    cd \"${_TMP_DIR}\"\n    git init &>/dev/null\n\n    pandoc                              \\\n      --from=markdown                   \\\n      --to=html                         \\\n      --output=\"${_html_file_path}\"     \\\n      --wrap=preserve                   \\\n      \"${NB_DIR}/home/Sample Folder/Sample Nested File One.md\"\n\n    [[ \"$(cat \"${_html_file_path}\")\" =~ \\<h1\\ id=\\\"sample-nested-title-one ]]\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n    --browse                            \\\n    \"${NB_DIR}/home\"                    \\\n    --page 123 --limit 2 --terminal < \"${_html_file_path}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<h1 id=\\\"sample-nested-title-one\\\">Sample Nested Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a href=\\\"//localhost:6789/home:1?--columns=70&--limit=2\\\">\\[\\[1\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23one\\\">#one</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<nav>${_NEWLINE}\\[\\[2\\]\\]${_NEWLINE}</nav>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a href=\\\"//localhost:6789/home:3?--columns=70&--limit=2\\\">\\[\\[3\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23three\\\">#three</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<pre><code>code-one\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^\\[\\[4\\]\\]$\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^#four$\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"code-two</code></pre>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p>Example content line <a href=\\\"//localhost:6789/home:5?--columns=70&--limit=2\\\">\\[\\[5\\]\\]</a> <a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23five\\\">#five</a> without inline code.</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p>Example content line <a href=\\\"//localhost:6789/home:6?--columns=70&--limit=2\\\">\\[\\[6\\]\\]</a> <a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23six\\\">#six</a> with <code>\\[\\[7\\]\\] #seven</code> inline code.</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a href=\\\"//localhost:6789/home:8?--columns=70&--limit=2\\\">\\[\\[8\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23eight\\\">#eight</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23nine\\\">#nine</a></p>\"\n}\n\n@test \"'_resolve_links --browse' with bookmark .html skips nav, code sections, and <h2>Content</h2>.\" {\n  {\n    \"${_NB}\" init\n\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.bookmark.md\"  \\\n      --title     \"Sample Nested Title One\"                           \\\n      --content   \"$(cat <<HEREDOC\n# Example Title\n\nhttps://example.com\n\n[[1]]\n#one\n\n<nav>\n[[2]]\n#two\n</nav>\n\n[[3]]\n#three\n\n\\`\\`\\`\ncode-one\n[[4]]\n#four\ncode-two\n\\`\\`\\`\n\nExample content line [[5]] #five without inline code.\n\nExample content line [[6]] #six with \\`[[7]] #seven\\` inline code.\n\n## Content\n\n[[8]]\n#eight\n\n#nine\nHEREDOC\n)\"\n\n    \"${_NB}\" add  \"Root File One.md\"    \\\n      --title     \"Root Title One\"      \\\n      --content   \"Root content one.\"\n\n    \"${_NB}\" add  \"Root File Two.md\"    \\\n      --title     \"Root Title Two\"      \\\n      --content   \"Root content two.\"\n\n    \"${_NB}\" add  \"Root File Three.md\"  \\\n      --title     \"Root Title Three\"    \\\n      --content   \"Root content three.\"\n\n    \"${_NB}\" add  \"Root File Four.md\"   \\\n      --title     \"Root Title Four\"     \\\n      --content   \"Root content four.\"\n\n    \"${_NB}\" add  \"Root File Five.md\"   \\\n      --title     \"Root Title Five\"     \\\n      --content   \"Root content five.\"\n\n    declare _html_file_path=\"${_TMP_DIR}/unlinked.html\"\n    touch \"${_html_file_path:?}\"\n\n    cd \"${_TMP_DIR}\"\n    git init &>/dev/null\n\n    pandoc                              \\\n      --from=markdown                   \\\n      --to=html                         \\\n      --output=\"${_html_file_path}\"     \\\n      --wrap=preserve                   \\\n      \"${NB_DIR}/home/Sample Folder/Sample Nested File One.bookmark.md\"\n\n    [[ \"$(cat \"${_html_file_path}\")\" =~ \\<h1\\ id=\\\"sample-nested-title-one ]]\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n    --browse                            \\\n    \"${NB_DIR}/home\"                    \\\n    --page 123 --limit 2 --terminal --bookmark < \"${_html_file_path}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<h1 id=\\\"sample-nested-title-one\\\">Sample Nested Title One</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a href=\\\"//localhost:6789/home:1?--columns=70&--limit=2\\\">\\[\\[1\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23one\\\">#one</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<nav>${_NEWLINE}\\[\\[2\\]\\]${_NEWLINE}</nav>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a href=\\\"//localhost:6789/home:3?--columns=70&--limit=2\\\">\\[\\[3\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23three\\\">#three</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<pre><code>code-one\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^\\[\\[4\\]\\]$\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^#four$\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"code-two</code></pre>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p>Example content line <a href=\\\"//localhost:6789/home:5?--columns=70&--limit=2\\\">\\[\\[5\\]\\]</a> <a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23five\\\">#five</a> without inline code.</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p>Example content line <a href=\\\"//localhost:6789/home:6?--columns=70&--limit=2\\\">\\[\\[6\\]\\]</a> <a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23six\\\">#six</a> with <code>\\[\\[7\\]\\] #seven</code> inline code.</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p>\\[\\[8\\]\\]\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"#eight</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p>#nine</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<p><a href=\\\"//localhost:6789/home:8?--columns=70&--limit=2\\\">\\[\\[8\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23eight\\\">#eight</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<p><a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23nine\\\">#nine</a></p>\"\n}\n\n# .html #######################################################################\n\n@test \"'_resolve_links --browse' with .html includes pagination params in tag links.\" {\n  {\n    \"${_NB}\" init\n\n    declare _content=\n    _content+=\"Selector link one: [[home:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[home:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag three: #tag-3/nested-1 • \"\n    _content+=\"Tag four: #tag-4/nested-2/nested-3 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"#tag4 #tag5 #tag6 #tag7${_NEWLINE}${_NEWLINE}\"\n    _content+=\"[Example Outbound Link One](http://example.com) • \"\n    _content+=\"[Example Outbound Link Two](https://test.test) • \"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.md\"   \\\n      --title     \"Sample Nested Title One\"                   \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n\n    declare _html_file_path=\"${_TMP_DIR}/unlinked.html\"\n    touch \"${_html_file_path:?}\"\n\n    cd \"${_TMP_DIR}\"\n    git init &>/dev/null\n\n    pandoc                              \\\n      --from=markdown                   \\\n      --to=html                         \\\n      --output=\"${_html_file_path}\"     \\\n      --wrap=preserve                   \\\n      \"${NB_DIR}/home/Sample Folder/Sample Nested File One.md\"\n\n    [[ \"$(cat \"${_html_file_path}\")\" =~ \\<h1\\ id=\\\"sample-nested-title-one ]]\n\n    printf \"\\\\n#tag8 #tag9\\\\n\" >> \"${_html_file_path}\"\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n    --browse                            \\\n    \"${NB_DIR}/home\"                    \\\n    --page 123 --limit 2 --terminal  < \"${_html_file_path}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link one: <a.* href=\\\"//localhost:6789/home:2/1?--columns=70&--limit=2\\\">\\[\\[home:2/1\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link two: <a.* href=\\\"//localhost:6789/home:Root Title One?--columns=70&--limit=2\\\">\\[\\[Root Title One\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link one: <a.* href=\\\"//localhost:6789/home:2/1?--columns=70&--limit=2\\\">\\[\\[Example label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link two: <a.* href=\\\"//localhost:6789/home:Root Title One?--columns=70&--limit=2\\\">\\[\\[Sample label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag one: <a.* href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag_1\\\">#tag_1</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag two: <a.* href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag-2\\\">#tag-2</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag three: <a.* href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag-3/nested-1\\\">#tag-3/nested-1</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag four: <a.* href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag-4/nested-2/nested-3\\\">#tag-4/nested-2/nested-3</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag3\\\">#tag3</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag4\\\">#tag4</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" <a.* href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag5\\\">#tag5</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" <a.* href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag6\\\">#tag6</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" <a.* href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag7\\\">#tag7</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789?url=http%3A%2F%2Fexample.com\\\">Example Outbound Link One</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a.* href=\\\"//localhost:6789?url=https%3A%2F%2Ftest.test\\\">Example Outbound Link Two</a> •</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag8\\\">#tag8</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag9\\\">#tag9</a>\"\n}\n\n@test \"'_resolve_links --browse' resolves [[wiki-style links]], tags, and outbound links in partial .html files to .html links to local web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    declare _content=\n    _content+=\"Selector link one: [[home:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[home:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag three: #tag-3/nested-1 • \"\n    _content+=\"Tag four: #tag-4/nested-2/nested-3 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"#tag4 #tag5 #tag6 #tag7${_NEWLINE}${_NEWLINE}\"\n    _content+=\"[Example Outbound Link One](http://example.com) • \"\n    _content+=\"[Example Outbound Link Two](https://test.test) • \"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.md\"   \\\n      --title     \"Sample Nested Title One\"                   \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n\n    declare _html_file_path=\"${_TMP_DIR}/unlinked.html\"\n    touch \"${_html_file_path:?}\"\n\n    cd \"${_TMP_DIR}\"\n    git init &>/dev/null\n\n    pandoc                              \\\n      --from=markdown                   \\\n      --to=html                         \\\n      --output=\"${_html_file_path}\"     \\\n      --wrap=preserve                   \\\n      \"${NB_DIR}/home/Sample Folder/Sample Nested File One.md\"\n\n    [[ \"$(cat \"${_html_file_path}\")\" =~ \\<h1\\ id=\\\"sample-nested-title-one ]]\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n    --browse                            \\\n    \"${NB_DIR}/home\" < \"${_html_file_path}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link one: <a.* href=\\\"//localhost:6789/home:2/1\\\">\\[\\[home:2/1\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link two: <a.* href=\\\"//localhost:6789/home:Root Title One\\\">\\[\\[Root Title One\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link one: <a.* href=\\\"//localhost:6789/home:2/1\\\">\\[\\[Example label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link two: <a.* href=\\\"//localhost:6789/home:Root Title One\\\">\\[\\[Sample label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag one: <a.* href=\\\"//localhost:6789/home:?--query=%23tag_1\\\">#tag_1</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag two: <a.* href=\\\"//localhost:6789/home:?--query=%23tag-2\\\">#tag-2</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag three: <a.* href=\\\"//localhost:6789/home:?--query=%23tag-3/nested-1\\\">#tag-3/nested-1</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag four: <a.* href=\\\"//localhost:6789/home:?--query=%23tag-4/nested-2/nested-3\\\">#tag-4/nested-2/nested-3</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789/home:?--query=%23tag3\\\">#tag3</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789/home:?--query=%23tag4\\\">#tag4</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" <a.* href=\\\"//localhost:6789/home:?--query=%23tag5\\\">#tag5</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" <a.* href=\\\"//localhost:6789/home:?--query=%23tag6\\\">#tag6</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" <a.* href=\\\"//localhost:6789/home:?--query=%23tag7\\\">#tag7</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789?url=http%3A%2F%2Fexample.com\\\">Example Outbound Link One</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a href=\\\"//localhost:6789?url=https%3A%2F%2Ftest.test\\\">Example Outbound Link Two</a> •</p>\"\n}\n\n@test \"'_resolve_links --browse' resolves [[wiki-style links]], tags, and outbound links in standalone .html files to .html links to local web server URLs without altering CSS values.\" {\n  {\n    \"${_NB}\" init\n\n    declare _content=\n    _content+=\"Selector link one: [[home:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[home:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag three: #tag-3/nested-1 • \"\n    _content+=\"Tag four: #tag-4/nested-2/nested-3 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"#tag4 #tag5 #tag6 #tag7${_NEWLINE}${_NEWLINE}\"\n    _content+=\"[Example Outbound Link One](http://example.com) • \"\n    _content+=\"[Example Outbound Link Two](https://test.test) • \"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.md\"   \\\n      --title     \"Sample Nested Title One\"                   \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n\n    declare _html_file_path=\"${_TMP_DIR}/unlinked.html\"\n    touch \"${_html_file_path:?}\"\n\n    cd \"${_TMP_DIR}\"\n    git init &>/dev/null\n\n    pandoc                              \\\n      --from=markdown                   \\\n      --to=html                         \\\n      --output=\"${_html_file_path}\"     \\\n      --standalone                      \\\n      --wrap=preserve                   \\\n      \"${NB_DIR}/home/Sample Folder/Sample Nested File One.md\"\n\n    [[ \"$(cat \"${_html_file_path}\")\" =~ \\<h1\\ id=\\\"sample-nested-title-one ]]\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n    \"${NB_DIR}/home\"                    \\\n    --browse < \"${_html_file_path}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Selector link one: <a.* href=\\\"//localhost:6789/home:2/1\\\">\\[\\[home:2/1\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Selector link two: <a.* href=\\\"//localhost:6789/home:Root Title One\\\">\\[\\[Root Title One\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Labeled link one: <a.* href=\\\"//localhost:6789/home:2/1\\\">\\[\\[Example label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Labeled link two: <a.* href=\\\"//localhost:6789/home:Root Title One\\\">\\[\\[Sample label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag one: <a.* href=\\\"//localhost:6789/home:?--query=%23tag_1\\\">#tag_1</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag two: <a.* href=\\\"//localhost:6789/home:?--query=%23tag-2\\\">#tag-2</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag three: <a.* href=\\\"//localhost:6789/home:?--query=%23tag-3/nested-1\\\">#tag-3/nested-1</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag four: <a.* href=\\\"//localhost:6789/home:?--query=%23tag-4/nested-2/nested-3\\\">#tag-4/nested-2/nested-3</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"<p><a.* href=\\\"//localhost:6789/home:?--query=%23tag3\\\">#tag3</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"color: \\#1a1a1a;\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"<p><a.* href=\\\"//localhost:6789/home:?--query=%23tag4\\\">#tag4</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \" <a.* href=\\\"//localhost:6789/home:?--query=%23tag5\\\">#tag5</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \" <a.* href=\\\"//localhost:6789/home:?--query=%23tag6\\\">#tag6</a> \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \" <a.* href=\\\"//localhost:6789/home:?--query=%23tag7\\\">#tag7</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"//localhost:6789?url=http%3A%2F%2Fexample.com\\\">Example Outbound Link One</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a.* href=\\\"//localhost:6789?url=https%3A%2F%2Ftest.test\\\">Example Outbound Link Two</a> •</p>\"\n}\n\n@test \"'_resolve_links' resolves [[wiki-style links]], tags, and outbound links in partial .html files to .html links to local file URLs without linking tags or outbound URLs.\" {\n  {\n    \"${_NB}\" init\n\n    declare _content=\n    _content+=\"Selector link one: [[home:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[home:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag three: #tag-3/nested-1 • \"\n    _content+=\"Tag four: #tag-4/nested-2/nested-3 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"#tag4 #tag5 #tag6 #tag7${_NEWLINE}${_NEWLINE}\"\n    _content+=\"[Example Outbound Link One](http://example.com) • \"\n    _content+=\"[Example Outbound Link Two](https://test.test) • \"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.md\"   \\\n      --title     \"Sample Nested Title One\"                   \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n\n    declare _html_file_path=\"${_TMP_DIR}/unlinked.html\"\n    touch \"${_html_file_path:?}\"\n\n    cd \"${_TMP_DIR}\"\n    git init &>/dev/null\n\n    pandoc                              \\\n      --from=markdown                   \\\n      --to=html                         \\\n      --output=\"${_html_file_path}\"     \\\n      --wrap=preserve                   \\\n      \"${NB_DIR}/home/Sample Folder/Sample Nested File One.md\"\n\n    [[ \"$(cat \"${_html_file_path}\")\" =~ \\<h1\\ id=\\\"sample-nested-title-one ]]\n  }\n\n  run \"${_NB}\" helpers resolve_links \"${NB_DIR}/home\" < \"${_html_file_path:-}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Selector link one: <a.* href=\\\"file://${NB_DIR}/home/Example%20Folder/Example%20Nested%20File%20One.md\\\">\\[\\[home:2/1\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Selector link two: <a.* href=\\\"file://${NB_DIR}/home/Root%20File%20One.md\\\">\\[\\[Root Title One\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Labeled link one: <a.* href=\\\"file://${NB_DIR}/home/Example%20Folder/Example%20Nested%20File%20One.md\\\">\\[\\[Example label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Labeled link two: <a.* href=\\\"file://${NB_DIR}/home/Root%20File%20One.md\\\">\\[\\[Sample label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag one: #tag_1 •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag two: #tag-2 •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag three: #tag-3/nested-1 •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag four: #tag-4/nested-2/nested-3 •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"<p>#tag3</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"<p>#tag4 #tag5 #tag6 #tag7</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"http://example.com\\\">Example Outbound Link One</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a.* href=\\\"https://test.test\\\">Example Outbound Link Two</a> •</p>\"\n}\n\n@test \"'_resolve_links' resolves [[wiki-style links]] in standalone .html files to .html links to local file URLs without linking tags or outbound URLs or altering CSS values.\" {\n  {\n    \"${_NB}\" init\n\n    declare _content=\n    _content+=\"Selector link one: [[home:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[home:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"#tag4 #tag5 #tag6 #tag7${_NEWLINE}${_NEWLINE}\"\n    _content+=\"[Example Outbound Link One](http://example.com) • \"\n    _content+=\"[Example Outbound Link Two](https://test.test) • \"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.md\"   \\\n      --title     \"Sample Nested Title One\"                   \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n\n    declare _html_file_path=\"${_TMP_DIR}/unlinked.html\"\n    touch \"${_html_file_path:?}\"\n\n    cd \"${_TMP_DIR}\"\n    git init &>/dev/null\n\n    pandoc                              \\\n      --from=markdown                   \\\n      --to=html                         \\\n      --output=\"${_html_file_path}\"     \\\n      --standalone                      \\\n      --wrap=preserve                   \\\n      \"${NB_DIR}/home/Sample Folder/Sample Nested File One.md\"\n\n    [[ \"$(cat \"${_html_file_path}\")\" =~ \\<h1\\ id=\\\"sample-nested-title-one ]]\n  }\n\n  run \"${_NB}\" helpers resolve_links \"${NB_DIR}/home\" < \"${_html_file_path}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Selector link one: <a.* href=\\\"file://${NB_DIR}/home/Example%20Folder/Example%20Nested%20File%20One.md\\\">\\[\\[home:2/1\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Selector link two: <a.* href=\\\"file://${NB_DIR}/home/Root%20File%20One.md\\\">\\[\\[Root Title One\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Labeled link one: <a.* href=\\\"file://${NB_DIR}/home/Example%20Folder/Example%20Nested%20File%20One.md\\\">\\[\\[Example label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Labeled link two: <a.* href=\\\"file://${NB_DIR}/home/Root%20File%20One.md\\\">\\[\\[Sample label.\\]\\]</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag one: #tag_1 •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag two: #tag-2 •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"<p>#tag3</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"color: \\#1a1a1a;\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n      \"<p>#tag4 #tag5 #tag6 #tag7</p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<p><a.* href=\\\"http://example.com\\\">Example Outbound Link One</a> •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"<a.* href=\\\"https://test.test\\\">Example Outbound Link Two</a> •</p>\"\n}\n\n# .org ########################################################################\n\n@test \"'_resolve_links --browse' with .org includes pagination params in tag links.\" {\n  {\n    \"${_NB}\" init\n\n    declare _content=\n    _content+=\"Selector link one: [[home:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[home:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"Org mode link: [[http://example.com]] • \"\n    _content+=\"Org mode link with description: [[http://example.com][Example Description (more)]] • \"\n    _content+=\"Internal Org mode link: [[#sample]] • \"\n\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"${_NEWLINE}#tag4 #tag5 #tag6 #tag7${_NEWLINE}\"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.org\"  \\\n      --title     \"Example Org Mode Title\"                    \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n    --browse                            \\\n    \"${NB_DIR}/home\"                    \\\n    --type org                          \\\n    --page 123 --limit 2             \\\n    --terminal < \"${NB_DIR}/home/Sample Folder/Sample Nested File One.org\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link one: \\[\\[//localhost:6789/home:2/1?--columns=70&--limit=2\\]\\[\\[\\[home:2/1\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link two: \\[\\[//localhost:6789/home:3?--columns=70&--limit=2\\]\\[\\[\\[Root Title One\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link one: \\[\\[//localhost:6789/home:2/1?--columns=70&--limit=2\\]\\[\\[\\[Example label.\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link two: \\[\\[//localhost:6789/home:3?--columns=70&--limit=2\\]\\[\\[\\[Sample label.\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag one: \\[\\[//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag_1\\]\\[#tag_1\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag two: \\[\\[//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag-2\\]\\[#tag-2\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Org mode link: \\[\\[//localhost:6789?url=http%3A%2F%2Fexample.com\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Org mode link with description: \\[\\[//localhost:6789?url=http%3A%2F%2Fexample.com\\]\\[Example Description (more)\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Internal Org mode link: \\[\\[#sample\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^\\[\\[//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag3\\]\\[#tag3\\]\\]$\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^\\[\\[//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag4\\]\\[#tag4\\]\\] \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" \\[\\[//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag5\\]\\[#tag5\\]\\] \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" \\[\\[//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag6\\]\\[#tag6\\]\\] \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" \\[\\[//localhost:6789/home:?--columns=70&--limit=2&--query=%23tag7\\]\\[#tag7\\]\\]$\"\n}\n\n@test \"'_resolve_links --browse' resolves [[wiki-style links]] and #tags in .org files to .org links to local web server URLs.\" {\n  {\n    \"${_NB}\" init\n\n    declare _content=\n    _content+=\"Selector link one: [[home:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[home:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"Org mode link: [[http://example.com]] • \"\n    _content+=\"Org mode link with description: [[http://example.com][Example Description (more)]] • \"\n    _content+=\"Internal Org mode link: [[#sample]] • \"\n\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"${_NEWLINE}#tag4 #tag5 #tag6 #tag7${_NEWLINE}\"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.org\"  \\\n      --title     \"Example Org Mode Title\"                    \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n      \"${NB_DIR}/home\"                  \\\n      --browse                          \\\n      --type org < \"${NB_DIR}/home/Sample Folder/Sample Nested File One.org\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link one: \\[\\[//localhost:6789/home:2/1\\]\\[\\[\\[home:2/1\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link two: \\[\\[//localhost:6789/home:3\\]\\[\\[\\[Root Title One\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link one: \\[\\[//localhost:6789/home:2/1\\]\\[\\[\\[Example label.\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link two: \\[\\[//localhost:6789/home:3\\]\\[\\[\\[Sample label.\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag one: \\[\\[//localhost:6789/home:?--query=%23tag_1\\]\\[#tag_1\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag two: \\[\\[//localhost:6789/home:?--query=%23tag-2\\]\\[#tag-2\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Org mode link: \\[\\[//localhost:6789?url=http%3A%2F%2Fexample.com\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Org mode link with description: \\[\\[//localhost:6789?url=http%3A%2F%2Fexample.com\\]\\[Example Description (more)\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Internal Org mode link: \\[\\[#sample\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^\\[\\[//localhost:6789/home:?--query=%23tag3\\]\\[#tag3\\]\\]$\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^\\[\\[//localhost:6789/home:?--query=%23tag4\\]\\[#tag4\\]\\] \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" \\[\\[//localhost:6789/home:?--query=%23tag5\\]\\[#tag5\\]\\] \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" \\[\\[//localhost:6789/home:?--query=%23tag6\\]\\[#tag6\\]\\] \"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\" \\[\\[//localhost:6789/home:?--query=%23tag7\\]\\[#tag7\\]\\]$\"\n}\n\n@test \"'_resolve_links' resolves [[wiki-style links]] in .org files to .org links to local file URLs.\" {\n  {\n    \"${_NB}\" init\n\n    declare _content=\n    _content+=\"Selector link one: [[home:2/1]] • \"\n    _content+=\"Selector link two: [[Root Title One]] • \"\n    _content+=\"Labeled link one: [[home:2/1|Example label.]] • \"\n    _content+=\"Labeled link two: [[Root Title One|Sample label.]] • \"\n    _content+=\"Tag one: #tag_1 • \"\n    _content+=\"Tag two: #tag-2 • \"\n    _content+=\"Tag not valid: 123#not-valid-tag • \"\n    _content+=\"Org mode link: [[http://example.com]] • \"\n    _content+=\"Org mode link with description: [[http://example.com][Example Description (more)]] • \"\n    _content+=\"Internal Org mode link: [[#sample]] • \"\n\n    _content+=\"${_NEWLINE}${_NEWLINE}#tag3${_NEWLINE}${_NEWLINE}\"\n    _content+=\"${_NEWLINE}#tag4 #tag5 #tag6 #tag7${_NEWLINE}\"\n\n    \"${_NB}\" add  \"Sample Folder/Sample Nested File One.org\"  \\\n      --title     \"Example Org Mode Title\"                    \\\n      --content   \"${_content:-}\"\n\n    \"${_NB}\" add  \"Example Folder/Example Nested File One.md\" \\\n      --title     \"Example Nested Title One\"                  \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" add  \"Root File One.md\"                          \\\n      --title     \"Root Title One\"                            \\\n      --content   \"Root content one.\"\n  }\n\n  run \"${_NB}\" helpers resolve_links    \\\n    \"${NB_DIR}/home\"                    \\\n    --type org < \"${NB_DIR}/home/Sample Folder/Sample Nested File One.org\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"  -eq 0               ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link one: \\[\\[file://${NB_DIR}/home/Example%20Folder/Example%20Nested%20File%20One.md\\]\\[\\[\\[home:2/1\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Selector link two: \\[\\[file://${NB_DIR}/home/Root%20File%20One.md\\]\\[\\[\\[Root Title One\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link one: \\[\\[file://${NB_DIR}/home/Example%20Folder/Example%20Nested%20File%20One.md\\]\\[\\[\\[Example label.\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Labeled link two: \\[\\[file://${NB_DIR}/home/Root%20File%20One.md\\]\\[\\[\\[Sample label.\\]\\]\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag one: #tag_1 •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag two: #tag-2 •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Tag not valid: 123#not-valid-tag •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Org mode link: \\[\\[http://example.com\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Org mode link with description: \\[\\[http://example.com\\]\\[Example Description (more)\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"Internal Org mode link: \\[\\[#sample\\]\\] •\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^#tag3$\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q  \\\n\"^#tag4 #tag5 #tag6 #tag7$\"\n}\n"
  },
  {
    "path": "test/helpers-selector-resolve-folders.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --build #####################################################################\n\n@test \"'_selector_resolve_folders <existing-folder> --build' (no slash) resolves existing folder name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\"         \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\"          ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Example Folder\" --build\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders <new-segment> --build' (no slash) returns 1 and prints nothing.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\"         \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\"          ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Sample Folder\" --build\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 1  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_selector_resolve_folders <new-segment>/ --build' (slash) prints new segment.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\"         \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\"          ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Sample Folder/\" --build\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0               ]]\n  [[ \"${output}\"  ==  \"Sample Folder\" ]]\n}\n\n@test \"'_selector_resolve_folders <new-segment>/<filename> --build' prints new segment.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\"         \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\"          ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Sample Folder/Example file.md\" --build\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0               ]]\n  [[ \"${output}\"  ==  \"Sample Folder\" ]]\n}\n\n@test \"'_selector_resolve_folders <notebook>:<folder-id>/<new-segment>/<filename> --build' resolves folders with new segment.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\"         \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\"           ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"home:2/Sample Folder/Example file.md\" --build\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder\"  ]]\n}\n\n# conflicting id / name #######################################################\n\n@test \"'_selector_resolve_folders()' favors id with conflicting id and folder name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n    \"${_NB}\" add \"Sample Folder\"  --type folder\n\n    \"${_NB}\" move \"Sample Folder\" \"1\" --force\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n    [[ -d \"${NB_DIR}/home/1\"              ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n\n  run \"${_NB}\" helpers selector_resolve_folders 2/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"1\"               ]]\n}\n\n# _selector_resolve_folders() (error handling) ################################\n\n@test \"'_selector_resolve_folders()' returns error with not-valid path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"         ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders not-valid/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 1               ]]\n  [[ -z \"${output}\"                       ]]\n  # [[    \"${lines[0]}\" =~  Not\\ a\\ folder: ]]\n  # [[    \"${lines[0]}\" =~  not-valid       ]]\n}\n\n@test \"'_selector_resolve_folders()' returns error with double not-valid two-level path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"         ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders not-valid/also-not-valid/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 1               ]]\n  [[ -z \"${output}\"                       ]]\n  # [[    \"${lines[0]}\" =~  Not\\ a\\ folder: ]]\n  # [[    \"${lines[0]}\" =~  not-valid       ]]\n}\n\n@test \"'_selector_resolve_folders()' returns error with second-level not-valid two-level path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"         ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders A\\ Folder/not-valid/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 1               ]]\n  [[ -z \"${output}\"                       ]]\n  # [[    \"${lines[0]}\" =~  Not\\ a\\ folder: ]]\n  # [[    \"${lines[0]}\" =~  not-valid       ]]\n}\n\n@test \"'_selector_resolve_folders()' returns error with second-level not-valid id two-level path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"         ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders A\\ Folder/99/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 1               ]]\n  [[ -z \"${output}\"                       ]]\n  # [[    \"${lines[0]}\" =~  Not\\ a\\ folder: ]]\n  # [[    \"${lines[0]}\" =~  99              ]]\n}\n\n# _selector_resolve_folders() (notebooks, folder and file ids) ################\n\n@test \"'_selector_resolve_folders()' resolves selector with notebook and root-level file id path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"       ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders home:2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with notebook and first-level folder id file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"home:2/Example file.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with notebook and second-level folder id file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                                     ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                               ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\"               ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/A Nested Folder\" ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"home:2/2/Example file.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with notebook and third-level folder id file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Example File.md\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                                                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                           ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\"                           ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                             ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/A Nested Folder\"             ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/A Nested Folder\" ]]\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"home:2/2/2/Example file.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder/Demo Folder\"  ]]\n}\n\n# _selector_resolve_folders() (folder and file ids) ####################################\n\n@test \"'_selector_resolve_folders()' resolves selector with root-level id file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"       ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with first-level folder id file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"2/Example file.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with second-level folder id file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                                     ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                               ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\"               ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/A Nested Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"2/2/Example file.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with third-level folder id file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Example File.md\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                                                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                           ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\"                           ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                             ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/A Nested Folder\"             ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/A Nested Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"2/2/2/Example file.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder/Demo Folder\"  ]]\n}\n\n# _selector_resolve_folders() (folder ids) ####################################\n\n@test \"'_selector_resolve_folders()' resolves selector with root-level folder id path, no slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/A Folder\"       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with root-level folder id path, yes slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/A Folder\"       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders 2/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with first-level folder id path, no slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"   ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"2/2\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with first-level folder id path, yes slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"   ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"2/2/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with second-level folder id path, no slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                                     ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                               ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\"               ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/A Nested Folder\" ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"     ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"2/2/2\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with second-level folder id path, yes slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                                     ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                               ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\"               ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/A Nested Folder\" ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"     ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"2/2/2/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder/Demo Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with third-level folder id path, no slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Test Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                                                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                           ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\"                           ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                             ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/A Nested Folder\"             ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/A Nested Folder\" ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Test Folder\"     ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"2/2/2/2\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder/Demo Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with third-level folder id path, yes slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/A Nested Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Test Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                                                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                                           ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\"                           ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\"                             ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/A Nested Folder\"             ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/A Nested Folder\" ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Test Folder\"     ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"2/2/2/2/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                       ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder/Demo Folder/Test Folder\"  ]]\n}\n\n# _selector_resolve_folders() (folder) ########################################\n\n@test \"'_selector_resolve_folders()' resolves selector with root-level folder path, no slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with root-level folder path, yes slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with first-level folder path, no slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Example Folder/Sample Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with first-level folder path, yes slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Example Folder/Sample Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with second-level folder path, no slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \\\n    \"Example Folder/Sample Folder/Demo Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with second-level folder path, yes slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \\\n    \"Example Folder/Sample Folder/Demo Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder/Demo Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with third-level folder path, no slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Test Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Test Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \\\n    \"Example Folder/Sample Folder/Demo Folder/Test Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder/Demo Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with third-level folder path, yes slash.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Test Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Test Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \\\n    \"Example Folder/Sample Folder/Demo Folder/Test Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                       ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder/Demo Folder/Test Folder\"  ]]\n}\n\n# _selector_resolve_folders() (file) ##########################################\n\n@test \"'_selector_resolve_folders()' resolves selector with root-level file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\" ]]\n }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with first-level file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Example Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with second-level file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \"Example Folder/Sample Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                               ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder\"  ]]\n}\n\n@test \"'_selector_resolve_folders()' resolves selector with third-level file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Sample Folder/Demo Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_folders \\\n    \"Example Folder/Sample Folder/Demo Folder/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n  [[ \"${output}\"  ==  \"Example Folder/Sample Folder/Demo Folder\"  ]]\n}\n\n"
  },
  {
    "path": "test/helpers-selector-resolve-path.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# conflicting id / name #######################################################\n\n@test \"'_selector_resolve_path()' favors id with conflicting id and folder name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\" --type folder\n    \"${_NB}\" add \"Sample Folder/File One.md\" --content \"Example content.\"\n\n    \"${_NB}\" move \"Sample Folder\" \"1\" --force\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n    [[ -f \"${NB_DIR}/home/1/File One.md\"  ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_path 1/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"Example Folder\"  ]]\n\n  run \"${_NB}\" helpers selector_resolve_path 1/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 1              ]]\n  [[ -z \"${output}\"                     ]]\n\n  run \"${_NB}\" helpers selector_resolve_path 2/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                 ]]\n  [[ \"${output}\"  ==  \"1\"               ]]\n}\n\n# edge cases ##################################################################\n\n@test \"'_selector_resolve_path()' returns message with pattern that only matches notebook name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" helpers selector_resolve_path example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output:-}\"       ]]\n}\n\n# <id> ########################################################################\n\n@test \"'_selector_resolve_path()' resolves selector with root-level id file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"         ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_path 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                     ]]\n  [[ \"${output}\"  ==  \"Example File.md\"     ]]\n\n  run \"${_NB}\" helpers selector_resolve_path 2 --full\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                 ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/home/Example File.md\"  ]]\n}\n\n@test \"'_selector_resolve_path()' resolves selector with first-level folder id file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" \\\n      --content \"Example content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_path \"2/Example File.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                 ]]\n  [[ \"${output}\"  ==  \"Example Folder/Example File.md\"  ]]\n\n\n  run \"${_NB}\" helpers selector_resolve_path \"2/Example File.md\" --full\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                               ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n}\n\n# <title> #####################################################################\n\n@test \"'_selector_resolve_path()' resolves selector with root-level title file path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"# Example Title\"\n\n    [[ -f \"${NB_DIR}/home/Example File.md\"  ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"         ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_path \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                     ]]\n  [[ \"${output}\"  ==  \"Example File.md\"     ]]\n\n  run \"${_NB}\" helpers selector_resolve_path 2 --full\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                 ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/home/Example File.md\"  ]]\n}\n\n@test \"'_selector_resolve_path()' resolves selector with first-level folder id file path and title.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" \\\n      --content \"# Example Title\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_path \"2/Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                 ]]\n  [[ \"${output}\"  ==  \"Example Folder/Example File.md\"  ]]\n\n\n  run \"${_NB}\" helpers selector_resolve_path \"2/Example Title\" --full\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                               ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/home/Example Folder/Example File.md\" ]]\n}\n\n@test \"'_selector_resolve_path()' resolves selector with first-level folder id file path and todo title.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"A Folder\" --type folder\n    \"${_NB}\" add \"Example Folder/A Nested Folder\" --type folder\n\n    \"${_NB}\" add \"Example Folder/Example File.md\"           \\\n      --content \"# Example Title\"\n\n    \"${_NB}\" add \"Example Folder/Example Todo File.todo.md\" \\\n      --content \"# [ ] Example Todo Description${_NEWLINE}${_NEWLINE}Example todo content.\"\n\n    [[ -f \"${NB_DIR}/home/Example Folder/Example File.md\"           ]]\n    [[ -f \"${NB_DIR}/home/Example Folder/Example Todo File.todo.md\" ]]\n\n    [[ -d \"${NB_DIR}/home/A Folder\"                       ]]\n    [[ -d \"${NB_DIR}/home/Example Folder\"                 ]]\n    [[ -d \"${NB_DIR}/home/Example Folder/A Nested Folder\" ]]\n  }\n\n  run \"${_NB}\" helpers selector_resolve_path \"2/Example Todo Description\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  echo \"---\"\n  cat \"${NB_DIR}/home/Example Folder/Example Todo File.todo.md\"\n  echo \"---\"\n  \"${_NB}\" helpers selector_resolve_path \"Example Folder/Example Todo File.todo.md\"\n  echo \"---\"\n  \"${_NB}\" helpers content \"${NB_DIR}/home/Example Folder/Example Todo File.todo.md\"\n  echo \"---\"\n  \"${_NB}\" helpers content \"${NB_DIR}/home/Example Folder/Example Todo File.todo.md\" --title\n  echo \"---\"\n\n  [[ \"${status}\"  -eq 0                                           ]]\n  [[ \"${output}\"  ==  \"Example Folder/Example Todo File.todo.md\"  ]]\n\n\n  run \"${_NB}\" helpers selector_resolve_path \"2/Example Todo Description\" --full\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                         ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/home/Example Folder/Example Todo File.todo.md\" ]]\n}\n"
  },
  {
    "path": "test/helpers-spinner.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'_spinner()' displays color spinner for the duration of the specified process.\" {\n  {\n    (sleep 3) &\n  }\n\n  run \"${_NB}\" helpers spinner $!\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                   ]]\n  [[    \"${#lines[@]}\"  -eq 1                   ]]\n  [[ !  \"${lines[0]}\"   =~  \\[\\|\\]              ]]\n  [[    \"${lines[0]}\"   =~  \\[.*\\|.*\\]          ]]\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*\\-.*\\].*\\ .*\\[.*\\/.*\\].*\\ .*\\[.*\\|.*\\].*  ]]\n}\n\n@test \"'_spinner() --no-color' displays nothing and waits for the duration of the specified process.\" {\n  {\n    (sleep 3) &\n  }\n\n  run \"${_NB}\" helpers spinner $! --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                   ]]\n  [[ -z \"${output}\"                             ]]\n}\n"
  },
  {
    "path": "test/helpers-string-is-email.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'_string_is_email()' matches email addresses.\" {\n  run \"${_NB}\" helpers string_is_email \"example@example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_email \"example+plusaddressing@example.text\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_email \"example+plusaddressing@example.examplelongtld\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n}\n\n@test \"'_string_is_email()' does not match non-email addresses.\" {\n  run \"${_NB}\" helpers string_is_email \"not-an-email-address\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n}\n"
  },
  {
    "path": "test/helpers-string-is-url.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'_string_is_url()' matches URLs.\" {\n  run \"${_NB}\" helpers string_is_url \"git@example.com:user/repo.git\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"aaa://host.example.com:1813;transport=udp;protocol=radius\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"aaas://host.example.com:1813;transport=udp;protocol=radius\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"acap://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"adiumxtra://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  run \"${_NB}\" helpers string_is_url \"admin://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"afp://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"afp:/at/example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"aim:example?parameters\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"app://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"app://example\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"apt:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"attachment:/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"aw://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"amss:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"barion:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"beshare://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"bitcoin:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"bolo://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"callto:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"chrome://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"chrome-extension://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"cid:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"coap://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"coaps://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"content://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"crid://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"cvs://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"dab:123.456.789.0\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"data:text/vnd-example+xyz;foo=bar;base64,R0lGODdh\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"dict://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"dns://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"dns:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"doi:10.1000/182\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"drm:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ed2k://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"facetime://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"fax:15555555555\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"feed://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"feed:http://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"feed:https://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"file:///home/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"finger:///home/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"fish:///home/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"fm:123.456.789\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ftp://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"gemini://example.com/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"geo:123.456,987.654\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"gg:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"git://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"gizmoproject://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"go://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"go:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"gopher://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"gtalk:chat?jid=example@gmail.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"h323://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"http://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"https://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"iax:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"im:example@sample\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"imap://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"irc://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"irc6://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ircs://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"itms:\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"jar:example!/sample\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"javascript:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"jdbc:example:sample\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"keyparc://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"lastfm://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ldap://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ldaps://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"magnet:?xt=urn:sha1:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"mailto:example@example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"maps:q=example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"market://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"message://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"message:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"mid:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"mms://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ms-help://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"msnim:add?contact=sample@example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"mumble://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"mvn:org.example/service/0.2.0-SNAPSHOT\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"mvn:http://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"mvn:https://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"news:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ni://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"nntp://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"notes://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"openpgp4fpr:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"palm:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"paparazzi:http://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"payto://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"platform:/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"pop://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"pres:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"proxy:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"psyc:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"query:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"reload://sample@example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"res://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"resource://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"rmi://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"rsync://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"rtmfp://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"rtmp://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"s3://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"secondlife://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"session:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"sftp://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"sftp://example.com\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"sgn://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"sip://sample@example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"sips://sample@example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"skype:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"slack://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"smb://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"sms:+15105550101\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"snmp://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"soldat://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"spotify:search:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ssh://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"steam://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"stratum+tcp://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"stratum+tcp://example\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"stratum+udp://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"stratum+udp://example\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"stun:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"stuns:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"svn://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"svn://example\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"svn+ssh://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"svn+ssh://example\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"tag:example.com,2222:1234\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"tag:example.com,2222:1234\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"teamspeak://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"tel:+15105550101\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"telnet://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"things://example?sample\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"turn:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"turns:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"udp://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"unreal://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"urn:sample:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ut2004://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ventrilo://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"view-source:http://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"view-source:https://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"view-source:https://example.com\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"vnc://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"wais://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"web-example://sample\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"webcal://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"webcal://example\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"ws:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"wtai://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"wyciwyg://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  # run \"${_NB}\" helpers string_is_url \"xfire:example\"\n\n  # printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  # printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # [[      \"${status}\" -eq 0 ]]\n  # [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"xmpp://sample@example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"xmpp://sample@example\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"xri://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"xri://example\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"ymsgr:sendIM?example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"ymsgr:sendIM?example\\\\n\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"z39.50r://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"z39.50s://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"zoommtg://zoom.us/join?confno=123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"zoomus://example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n}\n\n###############################################################################\n\n@test \"'_string_is_url()' doesn't match non-URLs.\" {\n  run \"${_NB}\" helpers string_is_url \"aim\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"aim:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"aim:123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"attachment:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"data:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"data:123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"data:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"fm:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"fm:123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"fm:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"geo:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"geo:123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"geo:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"im:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"im:123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"im:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"Not a URL.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"not-a-url\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"notaurl:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"notebook:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"notebook:123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"notebook:example/123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"notes:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"platform:123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"spotify:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"spotify:example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n}\n\n###############################################################################\n\n@test \"'_string_is_url()' doesn't match URLs with other text.\" {\n  run \"${_NB}\" helpers string_is_url \"http://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 0 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"sample http://example.com\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"http://example.com sample\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n\n  run \"${_NB}\" helpers string_is_url \"sample http://example.com sample\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\" -eq 1 ]]\n  [[  -z  \"${output}\"       ]]\n}\n"
  },
  {
    "path": "test/helpers-web-browser.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# checks ######################################################################\n\n@test \"'_web_browser --gui' return 1 when \\$BROWSER is set to 'w3m'.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  BROWSER=w3m run \"${_NB}\" helpers _web_browser --gui\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 1  ]]\n\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_web_browser --gui' return 1 when \\$BROWSER is set to 'lynx'.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  BROWSER=lynx run \"${_NB}\" helpers _web_browser --gui\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 1  ]]\n\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_web_browser --gui' return 0 when \\$BROWSER is set to 'firefox'.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  BROWSER=firefox run \"${_NB}\" helpers _web_browser --gui\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'_web_browser --gui' return 0 when \\$BROWSER is set to '<full path>/Google Chrome'.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  BROWSER=\"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\" \\\n    run \"${_NB}\" helpers _web_browser --gui\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n\n  [[ -z \"${output}\"         ]]\n}\n"
  },
  {
    "path": "test/helpers.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `_clear_cache()` ############################################################\n\n@test \"'_clear_cache()' clears the cache.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${NB_DIR}/.cache\"\n\n    echo \"Example\" > \"${NB_DIR}/.cache/example\"\n\n    [[ -e \"${NB_DIR}/.cache\" ]]\n  }\n\n  run \"${_NB}\" notebooks add \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\" -eq 0             ]]\n  [[ -e \"${NB_DIR}/.cache\"            ]]\n  [[ -z \"$(ls -A \"${NB_DIR}/.cache\")\" ]]\n}\n\n# `_file_is_bookmark()` #######################################################\n\n@test \"'_file_is_bookmark()' is true for .bookmark.md file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.bookmark.md\" --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" helpers _file_is_bookmark \"${NB_DIR}/home/example.bookmark.md\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.bookmark.md\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_bookmark()' is true for encrypted .bookmark.md.enc file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.bookmark.md\" \\\n      --content \"<https://example.test>\" --encrypt --password=password\n  }\n\n  run \"${_NB}\" helpers _file_is_bookmark \"${NB_DIR}/home/example.bookmark.md.enc\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.bookmark.md.enc\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_bookmark()' is false for .md file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" helpers _file_is_bookmark \"${NB_DIR}/home/example.md\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.md\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_bookmark()' is false for encrypted non-bookmark .enc file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\" --encrypt --password=password\n  }\n\n  run \"${_NB}\" helpers _file_is_bookmark \"${NB_DIR}/home/example.md.enc\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.md.enc\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_bookmark()' is false for extensionless file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"<https://example.test>\"\n    \"${_NB}\" run mv example.md example\n    \"${_NB}\" index reconcile\n    \"${_NB}\" git checkpoint \"Rename example.\"\n  }\n\n  run \"${_NB}\" helpers _file_is_bookmark \"${NB_DIR}/home/example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n# `_file_is_encrypted()` ######################################################\n\n@test \"'_file_is_encrypted()' is true for encrypted .enc file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" \\\n      --content \"Example\"     \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" helpers file_is_encrypted \"${NB_DIR}/home/example.md.enc\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.md.enc\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_encrypted()' is true for encrypted bookmark.md.enc file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.bookmark.md\"    \\\n      --content \"<https://example.test>\"  \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" helpers file_is_encrypted \"${NB_DIR}/home/example.bookmark.md.enc\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.bookmark.md.enc\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_encrypted()' is true for encrypted .not-valid file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"                                         \\\n      --content \"Lorem ipsum dolor sit amet, consectetur adipiscing.\" \\\n      --encrypt --password=password\n    \"${_NB}\" rename example.md.enc example.not-valid --force\n\n    [[ -f \"${NB_DIR}/home/example.not-valid\" ]]\n  }\n\n  run \"${_NB}\" helpers file_is_encrypted \"${NB_DIR}/home/example.not-valid\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.not-valid\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_encrypted()' is false for .md file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" helpers file_is_encrypted \"${NB_DIR}/home/example.md\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.md\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_encrypted()' is false for extensionless text file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n    \"${_NB}\" run mv example.md example\n    \"${_NB}\" index reconcile\n    \"${_NB}\" git checkpoint \"Rename example.\"\n  }\n\n  run \"${_NB}\" helpers file_is_encrypted \"${NB_DIR}/home/example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_encrypted()' is true for encrypted extensionless file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"                                         \\\n      --content \"Lorem ipsum dolor sit amet, consectetur adipiscing.\" \\\n      --encrypt --password=password\n    \"${_NB}\" run mv example.md.enc example\n    \"${_NB}\" index reconcile\n    \"${_NB}\" git checkpoint \"Rename example.\"\n\n    [[ -f \"${NB_DIR}/home/example\" ]]\n  }\n\n  run \"${_NB}\" helpers file_is_encrypted \"${NB_DIR}/home/example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n# `_file_is_text()` ###########################################################\n\n@test \"'_file_is_text()' is false for encrypted .enc file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"  --encrypt --password=password\n  }\n\n  run \"${_NB}\" helpers file_is_text \"${NB_DIR}/home/example.md.enc\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.md.enc\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_text()' is true for .md file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" helpers file_is_text \"${NB_DIR}/home/example.md\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.md\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_text()' is true for extensionless text file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n    \"${_NB}\" run mv example.md example\n    \"${_NB}\" index reconcile\n    \"${_NB}\" git checkpoint \"Rename example.\"\n  }\n\n  run \"${_NB}\" helpers file_is_text \"${NB_DIR}/home/example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_text()' is false for encrypted .not-valid file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"                                         \\\n      --content \"Lorem ipsum dolor sit amet, consectetur adipiscing.\" \\\n      --encrypt --password=password\n    \"${_NB}\" rename example.md.enc example.not-valid --force\n  }\n\n  run \"${_NB}\" helpers file_is_text \"${NB_DIR}/home/example.not-valid\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example.not-valid\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'_file_is_text()' is false for encrypted extensionless file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"                                         \\\n      --content \"Lorem ipsum dolor sit amet, consectetur adipiscing.\" \\\n      --encrypt --password=password\n    \"${_NB}\" run mv example.md.enc example\n    \"${_NB}\" index reconcile\n    \"${_NB}\" git checkpoint \"Rename example.\"\n\n    [[ -f \"${NB_DIR}/home/example\" ]]\n  }\n\n  run \"${_NB}\" helpers file_is_text \"${NB_DIR}/home/example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  file \"${NB_DIR}/home/example\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n# `_highlight_syntax_if_available()` ####################################################\n\n@test \"'_highlight_syntax_if_available <path>' high lights a file at <path>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"# Example\"\n  }\n\n  run \"${_NB}\" helpers highlight \"${NB_DIR}/home/example.md\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"   -eq 0           ]]\n  [[ -n \"${output:-}\"                 ]]\n  [[    \"${output}\"   !=  \"# Example\" ]]\n}\n\n@test \"'_highlight_syntax_if_available <path> --no-color' skips highlighting.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"# Example _Title_\"\n  }\n\n  run \"${_NB}\" helpers highlight \"${NB_DIR}/home/example.md\" --no-color\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[  \"${status}\" -eq 0                   ]]\n  [[  \"${output}\" ==  \"# Example _Title_\" ]]\n}\n\n@test \"'_highlight_syntax_if_available' highlights piped content.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo \\\"# Example _Title_\\\" | \\\"${_NB}\\\" helpers highlight\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"   -eq 0                   ]]\n  [[ -n \"${output:-}\"                         ]]\n  [[    \"${output}\"   !=  \"# Example _Title_\" ]]\n}\n\n@test \"'_highlight_syntax_if_available() --no-color' skips highlighting piped content.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo \\\"# Example _Title_\\\" | \\\"${_NB}\\\" helpers highlight --no-color\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"# Example _Title_\" ]]\n}\n\n@test \"'_highlight_syntax_if_available <extension>' highlights piped content.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo \\\"# Example _Title_\\\" | \\\"${_NB}\\\" helpers highlight 'md'\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                      ]]\n  [[ -n \"${output:-}\"                     ]]\n  [[ \"${output}\" !=  \"# Example _Title_\"  ]]\n}\n\n@test \"'_highlight_syntax_if_available <extension> --no-color' skips highlighting.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run bash -c \"echo \\\"# Example _Title_\\\" | \\\"${_NB}\\\" helpers highlight 'md' --no-color\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"# Example _Title_\" ]]\n}\n"
  },
  {
    "path": "test/history.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'history' exits with status 0 and prints notebook history.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n  }\n\n  run \"${_NB}\" history --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                        ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md     ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md     ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md    ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md  ]]\n}\n\n@test \"'history <filename>' with existing filename exits with status 0 and prints file history.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n  }\n\n  run \"${_NB}\" history two.md --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                        ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md     ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md     ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md    ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md  ]]\n}\n\n@test \"'history <id>' with existing file exits with status 0 and prints file history.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n  }\n\n  run \"${_NB}\" history 2 --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                        ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md     ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md     ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md    ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md  ]]\n}\n\n@test \"'history <title>' with existing file exits with status 0 and prints file history.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n  }\n\n  run \"${_NB}\" history second --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                        ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md     ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md     ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md    ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md  ]]\n}\n\n@test \"'history <filename>' with deleted filename exits with status 0 and prints file history.\" {\n  skip \"TODO\"\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n  }\n\n  run \"${_NB}\" history one.md --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0                        ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Add:\\ one.md     ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Add:\\ two.md     ]]\n  [[ !  \"${output}\"  =~  \\[nb\\]\\ Edit:\\ two.md    ]]\n  [[    \"${output}\"  =~  \\[nb\\]\\ Delete:\\ one.md  ]]\n}\n\n@test \"'history <filename>' with invalid filename exits with status 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add    \"one.md\" --title \"first\"\n    \"${_NB}\" add    \"two.md\" --title \"second\"\n    \"${_NB}\" edit   \"two.md\" --content \"Edited content.\"\n    \"${_NB}\" delete \"one.md\" --force\n  }\n\n  run \"${_NB}\" history not-valid --git-log\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                     ]]\n  [[    \"${#lines[@]}\"  -eq 1                     ]]\n  [[    \"${lines[0]}\"   =~  Not\\ found:           ]]\n  [[    \"${lines[0]}\"   =~  not-valid             ]]\n}\n"
  },
  {
    "path": "test/import-bookmarks.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# import bookmarks ############################################################\n\n@test \"'import bookmarks <path> <folder>/' imports chrome bookmarks into <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    {\n      cat \"${NB_TEST_BASE_PATH}/fixtures/example-chrome-bookmarks.html\"\n    } | {\n      sed                                                                                     \\\n        -e \"s|https://example.com\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html|g\"  \\\n        -e \"s|https://example.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.org.html|g\"  \\\n        -e \"s|https://example.net\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.net.html|g\"  \\\n        -e \"s|https://example.edu\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.edu.html|g\"\n    } | {\n      cat > \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n    }\n  }\n\n  run \"${_NB}\" import bookmarks                       \\\n    \"${_TMP_DIR}/example-chome-bookmarks-local.html\"  \\\n    Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${#lines[@]}\" -eq 8 ]]\n\n  [[ \"${lines[0]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/toolbar/1.*].*\\ 🔖\\ .*Example\\ Folder/toolbar/20220731185400\\.bookmark\\.md.*\\ \\\"Example\\ Com\\\" ]]\n\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/                            ]]\n  [[ \"${lines[1]}\"  =~ \\\nExample\\ Nested\\ Folder/20220731185404\\.bookmark\\.md.*\\ \\\"Example\\ Org\\\"                                    ]]\n\n  [[ \"${lines[2]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/1.*].*\\ 🔖\\                                  ]]\n  [[ \"${lines[2]}\"  =~ \\\n🔖\\ .*Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/20220731185402\\.bookmark\\.md.*\\ \\\"Example\\ Net\\\"    ]]\n\n  [[ \"${lines[3]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/toolbar/3.*].*\\ 🔖\\ .*Example\\ Folder/toolbar/20220731185602\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\\" ]]\n  [[ \"${lines[4]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/2.*].*\\ 🔖\\ .*Example\\ Folder/20220731190230\\.bookmark\\.md.*\\ \\\"Example\\ Org\\ Other\\\"          ]]\n  [[ \"${lines[5]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/3.*].*\\ 🔖\\ .*Example\\ Folder/20220731190235\\.bookmark\\.md.*\\ \\\"Example\\ Net\\ Other\\\"          ]]\n\n  [[ \"${lines[6]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/Example\\ Folder\\ Other/1.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[6]}\"  =~ \\\n🔖\\ .*Example\\ Folder/Example\\ Folder\\ Other/20220731190222\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\ Other\\\"        ]]\n\n  [[ \"${lines[7]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/1.*].*\\ 🔖\\              ]]\n  [[ \"${lines[7]}\"  =~ \\\n🔖\\ .*Example\\ Folder/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/                                ]]\n  [[ \"${lines[7]}\"  =~ \\\nExample\\ Nested\\ Folder\\ Other/20220731190214\\.bookmark\\.md.*\\ \\\"Example\\ Com\\ Other\\\"                      ]]\n\n  # Adds files.\n\n  [[ -e \"${NB_DIR}/home/Example Folder/toolbar/20220731185400.bookmark.md\"                                                ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/toolbar/Example Bookmark Folder/Example Nested Folder/20220731185404.bookmark.md\"  ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/toolbar/Example Bookmark Folder/20220731185402.bookmark.md\"                        ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/toolbar/20220731185602.bookmark.md\"                                                ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/20220731190230.bookmark.md\"                                                        ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/20220731190235.bookmark.md\"                                                        ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/Example Folder Other/20220731190222.bookmark.md\"                                   ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\"       ]]\n\n  diff                                                                        \\\n    <(cat \"${NB_DIR}/home/Example Folder/toolbar/20220731185400.bookmark.md\") \\\n    <(cat << HEREDOC\n# Example Com\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  diff                                                                                                                  \\\n    <(cat \"${NB_DIR}/home/Example Folder/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\")  \\\n    <(cat << HEREDOC\n# Example Com Other\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#example>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/home/.index\"                               ]]\n\n  diff                                                        \\\n    <(ls -t -r \"${NB_DIR}/home\")                              \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'import bookmarks <folder>/ <path>' imports chrome bookmarks into <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    {\n      cat \"${NB_TEST_BASE_PATH}/fixtures/example-chrome-bookmarks.html\"\n    } | {\n      sed                                                                                     \\\n        -e \"s|https://example.com\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html|g\"  \\\n        -e \"s|https://example.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.org.html|g\"  \\\n        -e \"s|https://example.net\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.net.html|g\"  \\\n        -e \"s|https://example.edu\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.edu.html|g\"\n    } | {\n      cat > \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n    }\n  }\n\n  run \"${_NB}\" import bookmarks \\\n    Example\\ Folder/            \\\n    \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${#lines[@]}\" -eq 8 ]]\n\n  [[ \"${lines[0]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/toolbar/1.*].*\\ 🔖\\ .*Example\\ Folder/toolbar/20220731185400\\.bookmark\\.md.*\\ \\\"Example\\ Com\\\" ]]\n\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/                            ]]\n  [[ \"${lines[1]}\"  =~ \\\nExample\\ Nested\\ Folder/20220731185404\\.bookmark\\.md.*\\ \\\"Example\\ Org\\\"                                    ]]\n\n  [[ \"${lines[2]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/1.*].*\\ 🔖\\                                  ]]\n  [[ \"${lines[2]}\"  =~ \\\n🔖\\ .*Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/20220731185402\\.bookmark\\.md.*\\ \\\"Example\\ Net\\\"    ]]\n\n  [[ \"${lines[3]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/toolbar/3.*].*\\ 🔖\\ .*Example\\ Folder/toolbar/20220731185602\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\\" ]]\n  [[ \"${lines[4]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/2.*].*\\ 🔖\\ .*Example\\ Folder/20220731190230\\.bookmark\\.md.*\\ \\\"Example\\ Org\\ Other\\\"          ]]\n  [[ \"${lines[5]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/3.*].*\\ 🔖\\ .*Example\\ Folder/20220731190235\\.bookmark\\.md.*\\ \\\"Example\\ Net\\ Other\\\"          ]]\n\n  [[ \"${lines[6]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/Example\\ Folder\\ Other/1.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[6]}\"  =~ \\\n🔖\\ .*Example\\ Folder/Example\\ Folder\\ Other/20220731190222\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\ Other\\\"        ]]\n\n  [[ \"${lines[7]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/1.*].*\\ 🔖\\              ]]\n  [[ \"${lines[7]}\"  =~ \\\n🔖\\ .*Example\\ Folder/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/                                ]]\n  [[ \"${lines[7]}\"  =~ \\\nExample\\ Nested\\ Folder\\ Other/20220731190214\\.bookmark\\.md.*\\ \\\"Example\\ Com\\ Other\\\"                      ]]\n\n  # Adds files.\n\n  [[ -e \"${NB_DIR}/home/Example Folder/toolbar/20220731185400.bookmark.md\"                                                ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/toolbar/Example Bookmark Folder/Example Nested Folder/20220731185404.bookmark.md\"  ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/toolbar/Example Bookmark Folder/20220731185402.bookmark.md\"                        ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/toolbar/20220731185602.bookmark.md\"                                                ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/20220731190230.bookmark.md\"                                                        ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/20220731190235.bookmark.md\"                                                        ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/Example Folder Other/20220731190222.bookmark.md\"                                   ]]\n  [[ -e \"${NB_DIR}/home/Example Folder/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\"       ]]\n\n  diff                                                                        \\\n    <(cat \"${NB_DIR}/home/Example Folder/toolbar/20220731185400.bookmark.md\") \\\n    <(cat << HEREDOC\n# Example Com\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  diff                                                                                                                  \\\n    <(cat \"${NB_DIR}/home/Example Folder/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\")  \\\n    <(cat << HEREDOC\n# Example Com Other\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#example>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/home/.index\"                               ]]\n\n  diff                                                        \\\n    <(ls -t -r \"${NB_DIR}/home\")                              \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'import bookmarks <path> <notebook>:<folder>/' imports chrome bookmarks into <notebook>:<folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    {\n      cat \"${NB_TEST_BASE_PATH}/fixtures/example-chrome-bookmarks.html\"\n    } | {\n      sed                                                                                     \\\n        -e \"s|https://example.com\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html|g\"  \\\n        -e \"s|https://example.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.org.html|g\"  \\\n        -e \"s|https://example.net\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.net.html|g\"  \\\n        -e \"s|https://example.edu\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.edu.html|g\"\n    } | {\n      cat > \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n    }\n  }\n\n  run \"${_NB}\" import bookmarks                       \\\n    \"${_TMP_DIR}/example-chome-bookmarks-local.html\"  \\\n    Example\\ Notebook:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${#lines[@]}\" -eq 8 ]]\n\n  [[ \"${lines[0]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/toolbar/1.*].*\\ 🔖\\ .*Example\\ Notebook:Example\\ Folder/toolbar/20220731185400\\.bookmark\\.md.*\\ \\\"Example\\ Com\\\" ]]\n\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/                            ]]\n  [[ \"${lines[1]}\"  =~ \\\nExample\\ Nested\\ Folder/20220731185404\\.bookmark\\.md.*\\ \\\"Example\\ Org\\\"                                                      ]]\n\n  [[ \"${lines[2]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/1.*].*\\ 🔖\\                                  ]]\n  [[ \"${lines[2]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/20220731185402\\.bookmark\\.md.*\\ \\\"Example\\ Net\\\"    ]]\n\n  [[ \"${lines[3]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/toolbar/3.*].*\\ 🔖\\ .*Example\\ Notebook:Example\\ Folder/toolbar/20220731185602\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\\" ]]\n  [[ \"${lines[4]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/2.*].*\\ 🔖\\ .*Example\\ Notebook:Example\\ Folder/20220731190230\\.bookmark\\.md.*\\ \\\"Example\\ Org\\ Other\\\"          ]]\n  [[ \"${lines[5]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/3.*].*\\ 🔖\\ .*Example\\ Notebook:Example\\ Folder/20220731190235\\.bookmark\\.md.*\\ \\\"Example\\ Net\\ Other\\\"          ]]\n\n  [[ \"${lines[6]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/Example\\ Folder\\ Other/1.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[6]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder/Example\\ Folder\\ Other/20220731190222\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\ Other\\\"        ]]\n\n  [[ \"${lines[7]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/1.*].*\\ 🔖\\              ]]\n  [[ \"${lines[7]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/                                ]]\n  [[ \"${lines[7]}\"  =~ \\\nExample\\ Nested\\ Folder\\ Other/20220731190214\\.bookmark\\.md.*\\ \\\"Example\\ Com\\ Other\\\"                                        ]]\n\n  # Adds files.\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/toolbar/20220731185400.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/toolbar/Example Bookmark Folder/Example Nested Folder/20220731185404.bookmark.md\" ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/toolbar/Example Bookmark Folder/20220731185402.bookmark.md\"                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/toolbar/20220731185602.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/20220731190230.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/20220731190235.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/Example Folder Other/20220731190222.bookmark.md\"                                  ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\"      ]]\n\n  diff                                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/toolbar/20220731185400.bookmark.md\") \\\n    <(cat << HEREDOC\n# Example Com\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  diff                                                                                                                              \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\")  \\\n    <(cat << HEREDOC\n# Example Com Other\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#example>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"                               ]]\n\n  diff                                                                    \\\n    <(ls -t -r \"${NB_DIR}/Example Notebook\")                              \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/Example Notebook\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'import bookmarks <notebook>:<folder>/ <path>' imports chrome bookmarks into <notebook>:<folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    {\n      cat \"${NB_TEST_BASE_PATH}/fixtures/example-chrome-bookmarks.html\"\n    } | {\n      sed                                                                                     \\\n        -e \"s|https://example.com\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html|g\"  \\\n        -e \"s|https://example.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.org.html|g\"  \\\n        -e \"s|https://example.net\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.net.html|g\"  \\\n        -e \"s|https://example.edu\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.edu.html|g\"\n    } | {\n      cat > \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n    }\n  }\n\n  run \"${_NB}\" import bookmarks         \\\n    Example\\ Notebook:Example\\ Folder/  \\\n    \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${#lines[@]}\" -eq 8 ]]\n\n  [[ \"${lines[0]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/toolbar/1.*].*\\ 🔖\\ .*Example\\ Notebook:Example\\ Folder/toolbar/20220731185400\\.bookmark\\.md.*\\ \\\"Example\\ Com\\\" ]]\n\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/                            ]]\n  [[ \"${lines[1]}\"  =~ \\\nExample\\ Nested\\ Folder/20220731185404\\.bookmark\\.md.*\\ \\\"Example\\ Org\\\"                                                      ]]\n\n  [[ \"${lines[2]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/1.*].*\\ 🔖\\                                  ]]\n  [[ \"${lines[2]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder/toolbar/Example\\ Bookmark\\ Folder/20220731185402\\.bookmark\\.md.*\\ \\\"Example\\ Net\\\"    ]]\n\n  [[ \"${lines[3]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/toolbar/3.*].*\\ 🔖\\ .*Example\\ Notebook:Example\\ Folder/toolbar/20220731185602\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\\" ]]\n  [[ \"${lines[4]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/2.*].*\\ 🔖\\ .*Example\\ Notebook:Example\\ Folder/20220731190230\\.bookmark\\.md.*\\ \\\"Example\\ Org\\ Other\\\"          ]]\n  [[ \"${lines[5]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/3.*].*\\ 🔖\\ .*Example\\ Notebook:Example\\ Folder/20220731190235\\.bookmark\\.md.*\\ \\\"Example\\ Net\\ Other\\\"          ]]\n\n  [[ \"${lines[6]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/Example\\ Folder\\ Other/1.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[6]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder/Example\\ Folder\\ Other/20220731190222\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\ Other\\\"        ]]\n\n  [[ \"${lines[7]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/1.*].*\\ 🔖\\              ]]\n  [[ \"${lines[7]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/                                ]]\n  [[ \"${lines[7]}\"  =~ \\\nExample\\ Nested\\ Folder\\ Other/20220731190214\\.bookmark\\.md.*\\ \\\"Example\\ Com\\ Other\\\"                                        ]]\n\n  # Adds files.\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/toolbar/20220731185400.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/toolbar/Example Bookmark Folder/Example Nested Folder/20220731185404.bookmark.md\" ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/toolbar/Example Bookmark Folder/20220731185402.bookmark.md\"                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/toolbar/20220731185602.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/20220731190230.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/20220731190235.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/Example Folder Other/20220731190222.bookmark.md\"                                  ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\"      ]]\n\n  diff                                                                                    \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/toolbar/20220731185400.bookmark.md\") \\\n    <(cat << HEREDOC\n# Example Com\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  diff                                                                                                                              \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\")  \\\n    <(cat << HEREDOC\n# Example Com Other\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#example>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"                               ]]\n\n  diff                                                                    \\\n    <(ls -t -r \"${NB_DIR}/Example Notebook\")                              \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/Example Notebook\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'import bookmarks <path> <notebook>:' imports chrome bookmarks into <notebook>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    {\n      cat \"${NB_TEST_BASE_PATH}/fixtures/example-chrome-bookmarks.html\"\n    } | {\n      sed                                                                                     \\\n        -e \"s|https://example.com\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html|g\"  \\\n        -e \"s|https://example.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.org.html|g\"  \\\n        -e \"s|https://example.net\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.net.html|g\"  \\\n        -e \"s|https://example.edu\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.edu.html|g\"\n    } | {\n      cat > \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n    }\n  }\n\n  run \"${_NB}\" import bookmarks                       \\\n    \"${_TMP_DIR}/example-chome-bookmarks-local.html\"  \\\n    Example\\ Notebook:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${#lines[@]}\" -eq 8 ]]\n\n  [[ \"${lines[0]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:toolbar/1.*].*\\ 🔖\\ .*Example\\ Notebook:toolbar/20220731185400\\.bookmark\\.md.*\\ \\\"Example\\ Com\\\" ]]\n\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/                            ]]\n  [[ \"${lines[1]}\"  =~ \\\nExample\\ Nested\\ Folder/20220731185404\\.bookmark\\.md.*\\ \\\"Example\\ Org\\\"                                      ]]\n\n  [[ \"${lines[2]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:toolbar/Example\\ Bookmark\\ Folder/1.*].*\\ 🔖\\                                  ]]\n  [[ \"${lines[2]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:toolbar/Example\\ Bookmark\\ Folder/20220731185402\\.bookmark\\.md.*\\ \\\"Example\\ Net\\\"    ]]\n\n  [[ \"${lines[3]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:toolbar/3.*].*\\ 🔖\\ .*Example\\ Notebook:toolbar/20220731185602\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\\" ]]\n  [[ \"${lines[4]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:2.*].*\\ 🔖\\ .*Example\\ Notebook:20220731190230\\.bookmark\\.md.*\\ \\\"Example\\ Org\\ Other\\\"          ]]\n  [[ \"${lines[5]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:3.*].*\\ 🔖\\ .*Example\\ Notebook:20220731190235\\.bookmark\\.md.*\\ \\\"Example\\ Net\\ Other\\\"          ]]\n\n  [[ \"${lines[6]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder\\ Other/1.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[6]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder\\ Other/20220731190222\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\ Other\\\"        ]]\n\n  [[ \"${lines[7]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/1.*].*\\ 🔖\\              ]]\n  [[ \"${lines[7]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/                                ]]\n  [[ \"${lines[7]}\"  =~ \\\nExample\\ Nested\\ Folder\\ Other/20220731190214\\.bookmark\\.md.*\\ \\\"Example\\ Com\\ Other\\\"                        ]]\n\n  # Adds files.\n\n  [[ -e \"${NB_DIR}/Example Notebook/toolbar/20220731185400.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/Example Notebook/toolbar/Example Bookmark Folder/Example Nested Folder/20220731185404.bookmark.md\" ]]\n  [[ -e \"${NB_DIR}/Example Notebook/toolbar/Example Bookmark Folder/20220731185402.bookmark.md\"                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/toolbar/20220731185602.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/Example Notebook/20220731190230.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/20220731190235.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder Other/20220731190222.bookmark.md\"                                  ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\"      ]]\n\n  diff                                                                      \\\n    <(cat \"${NB_DIR}/Example Notebook/toolbar/20220731185400.bookmark.md\")  \\\n    <(cat << HEREDOC\n# Example Com\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  diff                                                                                                              \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\") \\\n    <(cat << HEREDOC\n# Example Com Other\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#example>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"                               ]]\n\n  diff                                                                    \\\n    <(ls -t -r \"${NB_DIR}/Example Notebook\")                              \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/Example Notebook\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'import bookmarks <notebook>: <path>' imports chrome bookmarks into <notebook>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    {\n      cat \"${NB_TEST_BASE_PATH}/fixtures/example-chrome-bookmarks.html\"\n    } | {\n      sed                                                                                     \\\n        -e \"s|https://example.com\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html|g\"  \\\n        -e \"s|https://example.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.org.html|g\"  \\\n        -e \"s|https://example.net\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.net.html|g\"  \\\n        -e \"s|https://example.edu\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.edu.html|g\"\n    } | {\n      cat > \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n    }\n  }\n\n  run \"${_NB}\" import bookmarks \\\n    Example\\ Notebook:          \\\n    \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${#lines[@]}\" -eq 8 ]]\n\n  [[ \"${lines[0]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:toolbar/1.*].*\\ 🔖\\ .*Example\\ Notebook:toolbar/20220731185400\\.bookmark\\.md.*\\ \\\"Example\\ Com\\\" ]]\n\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/                            ]]\n  [[ \"${lines[1]}\"  =~ \\\nExample\\ Nested\\ Folder/20220731185404\\.bookmark\\.md.*\\ \\\"Example\\ Org\\\"                                      ]]\n\n  [[ \"${lines[2]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:toolbar/Example\\ Bookmark\\ Folder/1.*].*\\ 🔖\\                                  ]]\n  [[ \"${lines[2]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:toolbar/Example\\ Bookmark\\ Folder/20220731185402\\.bookmark\\.md.*\\ \\\"Example\\ Net\\\"    ]]\n\n  [[ \"${lines[3]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:toolbar/3.*].*\\ 🔖\\ .*Example\\ Notebook:toolbar/20220731185602\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\\" ]]\n  [[ \"${lines[4]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:2.*].*\\ 🔖\\ .*Example\\ Notebook:20220731190230\\.bookmark\\.md.*\\ \\\"Example\\ Org\\ Other\\\"          ]]\n  [[ \"${lines[5]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:3.*].*\\ 🔖\\ .*Example\\ Notebook:20220731190235\\.bookmark\\.md.*\\ \\\"Example\\ Net\\ Other\\\"          ]]\n\n  [[ \"${lines[6]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder\\ Other/1.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[6]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder\\ Other/20220731190222\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\ Other\\\"        ]]\n\n  [[ \"${lines[7]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Notebook:Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/1.*].*\\ 🔖\\              ]]\n  [[ \"${lines[7]}\"  =~ \\\n🔖\\ .*Example\\ Notebook:Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/                                ]]\n  [[ \"${lines[7]}\"  =~ \\\nExample\\ Nested\\ Folder\\ Other/20220731190214\\.bookmark\\.md.*\\ \\\"Example\\ Com\\ Other\\\"                        ]]\n\n  # Adds files.\n\n  [[ -e \"${NB_DIR}/Example Notebook/toolbar/20220731185400.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/Example Notebook/toolbar/Example Bookmark Folder/Example Nested Folder/20220731185404.bookmark.md\" ]]\n  [[ -e \"${NB_DIR}/Example Notebook/toolbar/Example Bookmark Folder/20220731185402.bookmark.md\"                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/toolbar/20220731185602.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/Example Notebook/20220731190230.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/20220731190235.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder Other/20220731190222.bookmark.md\"                                  ]]\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\"      ]]\n\n  diff                                                                      \\\n    <(cat \"${NB_DIR}/Example Notebook/toolbar/20220731185400.bookmark.md\")  \\\n    <(cat << HEREDOC\n# Example Com\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  diff                                                                                                              \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\") \\\n    <(cat << HEREDOC\n# Example Com Other\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#example>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"                               ]]\n\n  diff                                                                    \\\n    <(ls -t -r \"${NB_DIR}/Example Notebook\")                              \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/Example Notebook\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'import bookmarks <path>' imports firefox bookmarks.\" {\n  {\n    \"${_NB}\" init\n\n    {\n      cat \"${NB_TEST_BASE_PATH}/fixtures/example-firefox-bookmarks.html\"\n    } | {\n      sed                                                                                             \\\n        -e \"s|https://example.com\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html|g\"          \\\n        -e \"s|https://example.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.org.html|g\"          \\\n        -e \"s|https://example.net\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.net.html|g\"          \\\n        -e \"s|https://example.edu\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.edu.html|g\"          \\\n        -e \"s|https://support.mozilla.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#|g\" \\\n        -e \"s|https://www.mozilla.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#|g\"\n    } | {\n      cat > \"${_TMP_DIR}/example-firefox-bookmarks-local.html\"\n    }\n  }\n\n  run \"${_NB}\" import bookmarks \\\n    \"${_TMP_DIR}/example-firefox-bookmarks-local.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n\n  [[ \"${#lines[@]}\" -eq 17  ]]\n\n  [[ \"${lines[0]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder\\ Menu/Example\\ Nested\\ Folder\\ Menu/1.*].*\\ 🔖\\                                    ]]\n  [[ \"${lines[0]}\"  =~ \\\n🔖\\ .*Example\\ Folder\\ Menu/Example\\ Nested\\ Folder\\ Menu/20220801022006.bookmark.md.*\\ \\\"Example\\ Org\\ Menu\\\"  ]]\n\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder\\ Menu/2.*].*\\ 🔖\\                                        ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*Example\\ Folder\\ Menu/20220801022006.bookmark.md.*\\ \\\"Example\\ Net\\ Menu\\\"      ]]\n\n  [[ \"${lines[2]}\"  =~ \\\nAdded:\\ .*[.*2.*].*\\ 🔖\\ .*20220801022006.bookmark.md.*\\ \\\"Example\\ Edu\\ Menu\\\"       ]]\n\n  [[ \"${lines[3]}\"  =~ \\\nAdded:\\ .*[.*3*].*\\ 🔖\\ .*20220801022006-1.bookmark.md.*\\ \\\"Example\\ Com\\ Menu\\\"      ]]\n\n  [[ \"${lines[4]}\"  =~ \\\nAdded:\\ .*[.*Mozilla\\ Firefox/1.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[4]}\"  =~ \\\n🔖\\ .*Mozilla\\ Firefox/20200819025841.bookmark.md.*\\ \\\"Help\\ and\\ Tutorials\\\"         ]]\n\n  [[ \"${lines[5]}\"  =~ \\\nAdded:\\ .*[.*Mozilla\\ Firefox/2.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[5]}\"  =~ \\\n.*Mozilla\\ Firefox/20200819025841-1.bookmark.md.*\\ \\\"Customize\\ Firefox\\\"             ]]\n\n  [[ \"${lines[6]}\"  =~ \\\nAdded:\\ .*[.*Mozilla\\ Firefox/3.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[6]}\"  =~ \\\n.*Mozilla\\ Firefox/20200819025841-2.bookmark.md.*\\ \\\"Get\\ Involved\\\"                  ]]\n\n  [[ \"${lines[7]}\"  =~ \\\nAdded:\\ .*[.*Mozilla\\ Firefox/4.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[7]}\"  =~ \\\n🔖\\ .*Mozilla\\ Firefox/20200819025841-3.bookmark.md.*\\ \\\"About\\ Us\\\"                  ]]\n\n  [[ \"${lines[8]}\"  =~ \\\nAdded:\\ .*[.*toolbar/1.*].*\\ 🔖\\                                                      ]]\n  [[ \"${lines[8]}\"  =~ \\\n🔖\\ .*toolbar/20200819025841.bookmark.md.*\\ \\\"Getting\\ Started\\\"                      ]]\n\n  [[ \"${lines[9]}\"  =~ \\\nAdded:\\ .*[.*toolbar/Example\\ Folder\\ Toolbar/Example\\ Nested\\ Folder\\ Toolbar/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[9]}\"  =~ \\\n🔖\\ .*toolbar/Example\\ Folder\\ Toolbar/Example\\ Nested\\ Folder\\ Toolbar/                            ]]\n  [[ \"${lines[9]}\"  =~ \\\nExample\\ Nested\\ Folder\\ Toolbar/20220801021734.bookmark.md.*\\ \\\"Example\\ Org\\ Toolbar\\\"            ]]\n\n  [[ \"${lines[10]}\" =~ \\\nAdded:\\ .*[.*toolbar/Example\\ Folder\\ Toolbar/2.*].*\\ 🔖\\                                           ]]\n  [[ \"${lines[10]}\" =~ \\\n🔖\\ .*toolbar/Example\\ Folder\\ Toolbar/                                                             ]]\n  [[ \"${lines[10]}\" =~ \\\n20220801021651.bookmark.md.*\\ \\\"Example\\ Net\\ Toolbar\\\"                                             ]]\n\n  [[ \"${lines[11]}\" =~ \\\nAdded:\\ .*[.*toolbar/3.*].*\\ 🔖\\ .*toolbar/20220801021806.bookmark.md.*\\ \\\"Example\\ Edu\\ Toolbar\\\"  ]]\n\n  [[ \"${lines[12]}\" =~ \\\nAdded:\\ .*[.*toolbar/4.*].*\\ 🔖\\ .*toolbar/20220801021558.bookmark.md.*\\ \\\"Example\\ Com\\ Toolbar\\\"  ]]\n\n  [[ \"${lines[13]}\" =~ \\\nAdded:\\ .*[.*Other\\ Bookmarks/4.*].*\\ 🔖\\                                                           ]]\n  [[ \"${lines[13]}\" =~ \\\n🔖\\ .*Other\\ Bookmarks/20220801022030.bookmark.md.*\\ \\\"Example\\ Com\\ Other\\\"                        ]]\n\n  [[ \"${lines[14]}\" =~ \\\nAdded:\\ .*[.*Other\\ Bookmarks/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/1.*].*\\ 🔖\\                                     ]]\n  [[ \"${lines[14]}\" =~ \\\n🔖\\ .*Other\\ Bookmarks/Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/20220801022010.bookmark.md.*\\ \\\"Example\\ Org\\ Other\\\"  ]]\n\n  [[ \"${lines[15]}\" =~ \\\nAdded:\\ .*[.*Other\\ Bookmarks/Example\\ Folder\\ Other/2.*].*\\ 🔖\\                                    ]]\n  [[ \"${lines[15]}\" =~ \\\n🔖\\ .*Other\\ Bookmarks/Example\\ Folder\\ Other/20220801022010.bookmark.md.*\\ \\\"Example\\ Net\\ Other\\\" ]]\n\n  [[ \"${lines[16]}\" =~ \\\nAdded:\\ .*[.*Other\\ Bookmarks/3.*].*\\ 🔖\\                                                           ]]\n  [[ \"${lines[16]}\" =~ \\\n🔖\\ .*Other\\ Bookmarks/20220801022010.bookmark.md.*\\ \\\"Example\\ Edu\\ Other\\\"                        ]]\n\n  # Adds files.\n\n  [[ -e \"${NB_DIR}/home/Example Folder Menu/Example Nested Folder Menu/20220801022006.bookmark.md\"                    ]]\n  [[ -e \"${NB_DIR}/home/Example Folder Menu/20220801022006.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/home/20220801022006.bookmark.md\"                                                                   ]]\n  [[ -e \"${NB_DIR}/home/20220801022006-1.bookmark.md\"                                                                 ]]\n  [[ -e \"${NB_DIR}/home/Mozilla Firefox/20200819025841.bookmark.md\"                                                   ]]\n  [[ -e \"${NB_DIR}/home/Mozilla Firefox/20200819025841-1.bookmark.md\"                                                 ]]\n  [[ -e \"${NB_DIR}/home/Mozilla Firefox/20200819025841-2.bookmark.md\"                                                 ]]\n  [[ -e \"${NB_DIR}/home/Mozilla Firefox/20200819025841-3.bookmark.md\"                                                 ]]\n  [[ -e \"${NB_DIR}/home/toolbar/20200819025841.bookmark.md\"                                                           ]]\n  [[ -e \"${NB_DIR}/home/toolbar/Example Folder Toolbar/Example Nested Folder Toolbar/20220801021734.bookmark.md\"      ]]\n  [[ -e \"${NB_DIR}/home/toolbar/Example Folder Toolbar/20220801021651.bookmark.md\"                                    ]]\n  [[ -e \"${NB_DIR}/home/toolbar/20220801021806.bookmark.md\"                                                           ]]\n  [[ -e \"${NB_DIR}/home/toolbar/20220801021558.bookmark.md\"                                                           ]]\n  [[ -e \"${NB_DIR}/home/Other Bookmarks/20220801022030.bookmark.md\"                                                   ]]\n  [[ -e \"${NB_DIR}/home/Other Bookmarks/Example Folder Other/Example Nested Folder Other/20220801022010.bookmark.md\"  ]]\n  [[ -e \"${NB_DIR}/home/Other Bookmarks/Example Folder Other/20220801022010.bookmark.md\"                              ]]\n  [[ -e \"${NB_DIR}/home/Other Bookmarks/20220801022010.bookmark.md\"                                                   ]]\n\n  diff                                                                                                    \\\n    <(cat \"${NB_DIR}/home/Example Folder Menu/Example Nested Folder Menu/20220801022006.bookmark.md\")     \\\n    <(cat << HEREDOC\n# Example Org Menu\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.org.html#menu>\n\n## Tags\n\n#tag2 #tag6 #tag7\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  diff                                                                      \\\n    <(cat \"${NB_DIR}/home/Example Folder Menu/20220801022006.bookmark.md\")  \\\n    <(cat << HEREDOC\n# Example Net Menu\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.net.html#menu>\n\n## Tags\n\n#tag1 #tag4 #tag5\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/home/.index\"                               ]]\n\n  diff                                                        \\\n    <(ls -t -r \"${NB_DIR}/home\")                              \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'import bookmarks <path>' imports chrome bookmarks.\" {\n  {\n    \"${_NB}\" init\n\n    {\n      cat \"${NB_TEST_BASE_PATH}/fixtures/example-chrome-bookmarks.html\"\n    } | {\n      sed                                                                                     \\\n        -e \"s|https://example.com\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html|g\"  \\\n        -e \"s|https://example.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.org.html|g\"  \\\n        -e \"s|https://example.net\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.net.html|g\"  \\\n        -e \"s|https://example.edu\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.edu.html|g\"\n    } | {\n      cat > \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n    }\n  }\n\n  run \"${_NB}\" import bookmarks \\\n    \"${_TMP_DIR}/example-chome-bookmarks-local.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${#lines[@]}\" -eq 8 ]]\n\n  [[ \"${lines[0]}\"  =~ \\\nAdded:\\ .*[.*toolbar/1.*].*\\ 🔖\\ .*toolbar/20220731185400\\.bookmark\\.md.*\\ \\\"Example\\ Com\\\" ]]\n\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*[.*toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*toolbar/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/                            ]]\n  [[ \"${lines[1]}\"  =~ \\\nExample\\ Nested\\ Folder/20220731185404\\.bookmark\\.md.*\\ \\\"Example\\ Org\\\"                    ]]\n\n  [[ \"${lines[2]}\"  =~ \\\nAdded:\\ .*[.*toolbar/Example\\ Bookmark\\ Folder/1.*].*\\ 🔖\\                                  ]]\n  [[ \"${lines[2]}\"  =~ \\\n🔖\\ .*toolbar/Example\\ Bookmark\\ Folder/20220731185402\\.bookmark\\.md.*\\ \\\"Example\\ Net\\\"    ]]\n\n  [[ \"${lines[3]}\"  =~ \\\nAdded:\\ .*[.*toolbar/3.*].*\\ 🔖\\ .*toolbar/20220731185602\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\\" ]]\n  [[ \"${lines[4]}\"  =~ \\\nAdded:\\ .*[.*2.*].*\\ 🔖\\ .*20220731190230\\.bookmark\\.md.*\\ \\\"Example\\ Org\\ Other\\\"          ]]\n  [[ \"${lines[5]}\"  =~ \\\nAdded:\\ .*[.*3.*].*\\ 🔖\\ .*20220731190235\\.bookmark\\.md.*\\ \\\"Example\\ Net\\ Other\\\"          ]]\n\n  [[ \"${lines[6]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder\\ Other/1.*].*\\ 🔖\\                                             ]]\n  [[ \"${lines[6]}\"  =~ \\\n🔖\\ .*Example\\ Folder\\ Other/20220731190222\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\ Other\\\"        ]]\n\n  [[ \"${lines[7]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/1.*].*\\ 🔖\\              ]]\n  [[ \"${lines[7]}\"  =~ \\\n🔖\\ .*Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/                                ]]\n  [[ \"${lines[7]}\"  =~ \\\nExample\\ Nested\\ Folder\\ Other/20220731190214\\.bookmark\\.md.*\\ \\\"Example\\ Com\\ Other\\\"      ]]\n\n  # Adds files.\n\n  [[ -e \"${NB_DIR}/home/toolbar/20220731185400.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/home/toolbar/Example Bookmark Folder/Example Nested Folder/20220731185404.bookmark.md\" ]]\n  [[ -e \"${NB_DIR}/home/toolbar/Example Bookmark Folder/20220731185402.bookmark.md\"                       ]]\n  [[ -e \"${NB_DIR}/home/toolbar/20220731185602.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/home/20220731190230.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/home/20220731190235.bookmark.md\"                                                       ]]\n  [[ -e \"${NB_DIR}/home/Example Folder Other/20220731190222.bookmark.md\"                                  ]]\n  [[ -e \"${NB_DIR}/home/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\"      ]]\n\n  diff                                                          \\\n    <(cat \"${NB_DIR}/home/toolbar/20220731185400.bookmark.md\")  \\\n    <(cat << HEREDOC\n# Example Com\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  diff                                                                                                  \\\n    <(cat \"${NB_DIR}/home/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\") \\\n    <(cat << HEREDOC\n# Example Com Other\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#example>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/home/.index\"                               ]]\n\n  diff                                                        \\\n    <(ls -t -r \"${NB_DIR}/home\")                              \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'import bookmarks <path>' imports edge bookmarks.\" {\n  {\n    \"${_NB}\" init\n\n    {\n      cat \"${NB_TEST_BASE_PATH}/fixtures/example-edge-bookmarks.html\"\n    } | {\n      sed                                                                                     \\\n        -e \"s|https://example.com\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.com.html|g\"  \\\n        -e \"s|https://example.org\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.org.html|g\"  \\\n        -e \"s|https://example.net\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.net.html|g\"  \\\n        -e \"s|https://example.edu\\/|file://${NB_TEST_BASE_PATH}/fixtures/example.edu.html|g\"\n    } | {\n      cat > \"${_TMP_DIR}/example-edge-bookmarks-local.html\"\n    }\n  }\n\n  run \"${_NB}\" import bookmarks \\\n    \"${_TMP_DIR}/example-edge-bookmarks-local.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${#lines[@]}\" -eq 8 ]]\n\n  [[ \"${lines[0]}\"  =~ \\\nAdded:\\ .*[.*toolbar/Bookmarks/1.*].*\\ 🔖\\ .*toolbar/Bookmarks/20220731185400\\.bookmark\\.md.*\\ \\\"Example\\ Com\\\" ]]\n\n  [[ \"${lines[1]}\"  =~ \\\nAdded:\\ .*[.*toolbar/Bookmarks/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[1]}\"  =~ \\\n🔖\\ .*toolbar/Bookmarks/Example\\ Bookmark\\ Folder/Example\\ Nested\\ Folder/                            ]]\n  [[ \"${lines[1]}\"  =~ \\\nExample\\ Nested\\ Folder/20220731185404\\.bookmark\\.md.*\\ \\\"Example\\ Org\\\"                              ]]\n\n  [[ \"${lines[2]}\"  =~ \\\nAdded:\\ .*[.*toolbar/Bookmarks/Example\\ Bookmark\\ Folder/1.*].*\\ 🔖\\                                  ]]\n  [[ \"${lines[2]}\"  =~ \\\n🔖\\ .*toolbar/Bookmarks/Example\\ Bookmark\\ Folder/20220731185402\\.bookmark\\.md.*\\ \\\"Example\\ Net\\\"    ]]\n\n  [[ \"${lines[3]}\"  =~ \\\nAdded:\\ .*[.*toolbar/Bookmarks/3.*].*\\ 🔖\\ .*toolbar/Bookmarks/20220731185602\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\\" ]]\n  [[ \"${lines[4]}\"  =~ \\\nAdded:\\ .*[.*2.*].*\\ 🔖\\ .*20220731190230\\.bookmark\\.md.*\\ \\\"Example\\ Org\\ Other\\\"      ]]\n  [[ \"${lines[5]}\"  =~ \\\nAdded:\\ .*[.*3.*].*\\ 🔖\\ .*20220731190235\\.bookmark\\.md.*\\ \\\"Example\\ Net\\ Other\\\"      ]]\n\n  [[ \"${lines[6]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder\\ Other/1.*].*\\ 🔖\\                                         ]]\n  [[ \"${lines[6]}\"  =~ \\\n🔖\\ .*Example\\ Folder\\ Other/20220731190222\\.bookmark\\.md.*\\ \\\"Example\\ Edu\\ Other\\\"    ]]\n\n  [[ \"${lines[7]}\"  =~ \\\nAdded:\\ .*[.*Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/1.*].*\\ 🔖\\          ]]\n  [[ \"${lines[7]}\"  =~ \\\n🔖\\ .*Example\\ Folder\\ Other/Example\\ Nested\\ Folder\\ Other/                            ]]\n  [[ \"${lines[7]}\"  =~ \\\nExample\\ Nested\\ Folder\\ Other/20220731190214\\.bookmark\\.md.*\\ \\\"Example\\ Com\\ Other\\\"  ]]\n\n  # Adds files.\n\n  [[ -e \"${NB_DIR}/home/toolbar/Bookmarks/20220731185400.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/home/toolbar/Bookmarks/Example Bookmark Folder/Example Nested Folder/20220731185404.bookmark.md\" ]]\n  [[ -e \"${NB_DIR}/home/toolbar/Bookmarks/Example Bookmark Folder/20220731185402.bookmark.md\"                       ]]\n  [[ -e \"${NB_DIR}/home/toolbar/Bookmarks/20220731185602.bookmark.md\"                                               ]]\n  [[ -e \"${NB_DIR}/home/20220731190230.bookmark.md\"                                                                 ]]\n  [[ -e \"${NB_DIR}/home/20220731190235.bookmark.md\"                                                                 ]]\n  [[ -e \"${NB_DIR}/home/Example Folder Other/20220731190222.bookmark.md\"                                            ]]\n  [[ -e \"${NB_DIR}/home/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\"                ]]\n\n  diff                                                          \\\n    <(cat \"${NB_DIR}/home/toolbar/Bookmarks/20220731185400.bookmark.md\")  \\\n    <(cat << HEREDOC\n# Example Com\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  diff                                                                                                  \\\n    <(cat \"${NB_DIR}/home/Example Folder Other/Example Nested Folder Other/20220731190214.bookmark.md\") \\\n    <(cat << HEREDOC\n# Example Com Other\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html#example>\n\n## Description\n\nExample description.\n\n## Content\n\n# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ndomain in literature without prior coordination or asking for permission.\n\n[More information\\...](https://www.iana.org/domains/example)\nHEREDOC\n    )\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/home/.index\"                               ]]\n\n  diff                                                        \\\n    <(ls -t -r \"${NB_DIR}/home\")                              \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n"
  },
  {
    "path": "test/import.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# shortcut alias ##############################################################\n\n@test \"'i' with valid <path> argument imports file.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" i \"${NB_TEST_BASE_PATH}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ \\\nImported\\ .*\\[.*1.*\\].*\\ .*example.md.*\\ \\\"Example\\ Title\\\"\\ from\\    ]]\n  [[ \"${lines[0]}\" =~ \\\n \\\"Example\\ Title\\\"\\ from\\ .*${NB_TEST_BASE_PATH}/fixtures/example.md ]]\n\n  # Adds file.\n\n  diff                                                                \\\n    <(cat \"${NB_TEST_BASE_PATH}/fixtures/example.md\")                 \\\n    <(cat \"${NB_DIR}/home/example.md\")\n\n  # Adds to index.\n\n  [[ -e \"${NB_DIR}/home/.index\"                                       ]]\n\n  diff                                                                \\\n    <(ls \"${NB_DIR}/home\")                                            \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Creates git commit.\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\"         ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Import'\n}\n\n# local notebook ##############################################################\n\n@test \"'import <path> <folder>/' with local notebook imports file.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    [[ -d \"${_TMP_DIR}/Local Notebook/Example Folder\"       ]]\n  }\n\n  run \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/example.md\" Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${_TMP_DIR}/Local Notebook/Example Folder/\"))\n\n  [[ \"${#_files[@]}\" -eq 1                                  ]]\n  grep -q '# Example Title' \"${_TMP_DIR}/Local Notebook/Example Folder\"/*\n\n  # Adds to index:\n\n  [[ -e \"${_TMP_DIR}/Local Notebook/Example Folder/.index\"  ]]\n\n  diff                                                      \\\n    <(ls \"${_TMP_DIR}/Local Notebook/Example Folder\")       \\\n    <(cat \"${_TMP_DIR}/Local Notebook/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${_TMP_DIR}/Local Notebook\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\"                   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${lines[0]}\" =~ \\\n\\\"Example\\ Title\\\"\\ from\\ .*${NB_TEST_BASE_PATH}/fixtures/example.md                      ]]\n}\n\n@test \"'import <folder>/ <path>' with local notebook imports file.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" add folder \"Example Folder\"\n\n    [[ -d \"${_TMP_DIR}/Local Notebook/Example Folder\"       ]]\n  }\n\n  run \"${_NB}\" import Example\\ Folder/ \"${NB_TEST_BASE_PATH}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${_TMP_DIR}/Local Notebook/Example Folder/\"))\n\n  [[ \"${#_files[@]}\" -eq 1                                  ]]\n  grep -q '# Example Title' \"${_TMP_DIR}/Local Notebook/Example Folder\"/*\n\n  # Adds to index:\n\n  [[ -e \"${_TMP_DIR}/Local Notebook/Example Folder/.index\"  ]]\n\n  diff                                                      \\\n    <(ls \"${_TMP_DIR}/Local Notebook/Example Folder\")       \\\n    <(cat \"${_TMP_DIR}/Local Notebook/Example Folder/.index\")\n\n  # Creates git commit:\n\n  cd \"${_TMP_DIR}/Local Notebook\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\"                   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${lines[0]}\" =~ \\\n\\\"Example\\ Title\\\"\\ from\\ .*${NB_TEST_BASE_PATH}/fixtures/example.md                      ]]\n}\n\n@test \"'import <path>' with local notebook imports file.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n  }\n\n  run \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${_TMP_DIR}/Local Notebook/\"))\n\n  [[ \"${#_files[@]}\" -eq 1                  ]]\n  grep -q '# Example Title' \"${_TMP_DIR}/Local Notebook\"/*\n\n  # Adds to index:\n\n  [[ -e \"${_TMP_DIR}/Local Notebook/.index\" ]]\n\n  diff                                      \\\n    <(ls \"${_TMP_DIR}/Local Notebook\")      \\\n    <(cat \"${_TMP_DIR}/Local Notebook/.index\")\n\n  # Creates git commit:\n\n  cd \"${_TMP_DIR}/Local Notebook\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nImported\\ .*[.*1.*].*\\ .*example.md.*\\ \\\"Example\\ Title\\\"             ]]\n  [[ \"${lines[0]}\" =~ \\\n\\\"Example\\ Title\\\"\\ from\\ .*${NB_TEST_BASE_PATH}/fixtures/example.md  ]]\n}\n\n# no argument #################################################################\n\n@test \"'import' with no arguments exits with status 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" import\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1            ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\: ]]\n}\n\n@test \"'import' with no arguments does not create git commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" import\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Import'\n}\n\n# destination #################################################################\n\n@test \"'import <path> <notebook>:' imports file into <notebook>:.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"${_TMP_DIR}/fixtures/example.md\" \"Example Notebook:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/example.md\" ]]\n\n  diff                                          \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")    \\\n    <(cat \"${NB_DIR}/Example Notebook/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"     ]]\n\n  diff                                          \\\n    <(ls \"${NB_DIR}/Example Notebook/\")         \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:1.*].*\\ .*example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nexample.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md   ]]\n}\n\n@test \"'import <notebook>: <path>' imports file into <notebook>:.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"Example Notebook:\" \"${_TMP_DIR}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/example.md\" ]]\n\n  diff                                          \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")    \\\n    <(cat \"${NB_DIR}/Example Notebook/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\"     ]]\n\n  diff                                          \\\n    <(ls \"${NB_DIR}/Example Notebook/\")         \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:1.*].*\\ .*example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nexample.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md   ]]\n}\n\n@test \"'import ./* <notebook>:' with valid * (glob) argument copies multiple files and directories into <notebook>:.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import ./* \"Example Notebook:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/Example Notebook/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/Example Notebook/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                         ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Folder\"                   ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/example.md\"        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/example.com.html\"  ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Folder            ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                    ]]\n  [[ -d \"${NB_DIR}/Example Notebook/bin\"                              ]]\n  [[ -f \"${NB_DIR}/Example Notebook/bin/bookmark\"                     ]]\n  [[ -f \"${NB_DIR}/Example Notebook/bin/mock_editor\"                  ]]\n  [[    \"${lines[1]}\" =~ Imported                                     ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:bin                        ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"              ]]\n  [[ -f \"${NB_DIR}/Example Notebook/copy-deprecated.nb-plugin\"        ]]\n  [[    \"${lines[2]}\" =~ Imported                                     ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:copy-deprecated.nb-plugin  ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                    ]]\n  [[ -f \"${NB_DIR}/Example Notebook/example.com-og.html\"              ]]\n  [[    \"${lines[3]}\" =~ Imported                                     ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:example.com-og.html        ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                      \\\n    <(ls \"${NB_DIR}/Example Notebook/\")     \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n}\n\n@test \"'import <notebook>: ./*' with valid * (glob) argument copies multiple files and directories into <notebook>:.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import \"Example Notebook:\" ./*\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/Example Notebook/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/Example Notebook/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                         ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Folder\"                   ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/example.md\"        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/example.com.html\"  ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Folder            ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                    ]]\n  [[ -d \"${NB_DIR}/Example Notebook/bin\"                              ]]\n  [[ -f \"${NB_DIR}/Example Notebook/bin/bookmark\"                     ]]\n  [[ -f \"${NB_DIR}/Example Notebook/bin/mock_editor\"                  ]]\n  [[    \"${lines[1]}\" =~ Imported                                     ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:bin                        ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"              ]]\n  [[ -f \"${NB_DIR}/Example Notebook/copy-deprecated.nb-plugin\"        ]]\n  [[    \"${lines[2]}\" =~ Imported                                     ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:copy-deprecated.nb-plugin  ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                    ]]\n  [[ -f \"${NB_DIR}/Example Notebook/example.com-og.html\"              ]]\n  [[    \"${lines[3]}\" =~ Imported                                     ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:example.com-og.html        ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                      \\\n    <(ls \"${NB_DIR}/Example Notebook/\")     \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n}\n\n@test \"'import ./* <notebook>:<folder>' (no slash) with valid * (glob) argument copies multiple files and directories into <notebook>:<folder>/.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Destination\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import ./* \"Example Notebook:Example Destination\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/Example Notebook/Example Destination/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/Example Notebook/Example Destination/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                                             ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Destination/Example Folder\"                   ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/Example Folder/example.md\"        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/Example Folder/example.com.html\"  ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/Example\\ Folder           ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                                        ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Destination/bin\"                              ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/bin/bookmark\"                     ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/bin/mock_editor\"                  ]]\n  [[    \"${lines[1]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/bin                       ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"                                  ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/copy-deprecated.nb-plugin\"        ]]\n  [[    \"${lines[2]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/copy-deprecated.nb-plugin ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                                        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/example.com-og.html\"              ]]\n  [[    \"${lines[3]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/example.com-og.html       ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Destination/.index\" ]]\n\n  diff                                                      \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Destination/\") \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Destination/.index\")\n}\n\n@test \"'import <notebook>:<folder> ./*' (no slash) with valid * (glob) argument copies multiple files and directories into <notebook>:<folder>/.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Destination\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import \"Example Notebook:Example Destination\" ./*\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/Example Notebook/Example Destination/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/Example Notebook/Example Destination/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                                             ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Destination/Example Folder\"                   ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/Example Folder/example.md\"        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/Example Folder/example.com.html\"  ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/Example\\ Folder           ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                                        ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Destination/bin\"                              ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/bin/bookmark\"                     ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/bin/mock_editor\"                  ]]\n  [[    \"${lines[1]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/bin                       ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"                                  ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/copy-deprecated.nb-plugin\"        ]]\n  [[    \"${lines[2]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/copy-deprecated.nb-plugin ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                                        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/example.com-og.html\"              ]]\n  [[    \"${lines[3]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/example.com-og.html       ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Destination/.index\" ]]\n\n  diff                                                      \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Destination/\") \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Destination/.index\")\n}\n\n@test \"'import ./* <notebook>:<folder>/' (slash) with valid * (glob) argument copies multiple files and directories into <notebook>:<folder>/.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Destination\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import ./* \"Example Notebook:Example Destination/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/Example Notebook/Example Destination/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/Example Notebook/Example Destination/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                                             ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Destination/Example Folder\"                   ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/Example Folder/example.md\"        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/Example Folder/example.com.html\"  ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/Example\\ Folder           ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                                        ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Destination/bin\"                              ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/bin/bookmark\"                     ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/bin/mock_editor\"                  ]]\n  [[    \"${lines[1]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/bin                       ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"                                  ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/copy-deprecated.nb-plugin\"        ]]\n  [[    \"${lines[2]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/copy-deprecated.nb-plugin ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                                        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/example.com-og.html\"              ]]\n  [[    \"${lines[3]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/example.com-og.html       ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Destination/.index\" ]]\n\n  diff                                                      \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Destination/\") \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Destination/.index\")\n}\n\n@test \"'import <notebook>:<folder>/ ./*' (slash) with valid * (glob) argument copies multiple files and directories into <notebook>:<folder>/.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Destination\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import \"Example Notebook:Example Destination/\" ./*\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/Example Notebook/Example Destination/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/Example Notebook/Example Destination/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                                             ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Destination/Example Folder\"                   ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/Example Folder/example.md\"        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/Example Folder/example.com.html\"  ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/Example\\ Folder           ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                                        ]]\n  [[ -d \"${NB_DIR}/Example Notebook/Example Destination/bin\"                              ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/bin/bookmark\"                     ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/bin/mock_editor\"                  ]]\n  [[    \"${lines[1]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/bin                       ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"                                  ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/copy-deprecated.nb-plugin\"        ]]\n  [[    \"${lines[2]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/copy-deprecated.nb-plugin ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                                        ]]\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination/example.com-og.html\"              ]]\n  [[    \"${lines[3]}\" =~ Imported                                                         ]]\n  [[    \"${output}\"   =~ Example\\ Notebook:Example\\ Destination/example.com-og.html       ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Destination/.index\" ]]\n\n  diff                                                      \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Destination/\") \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Destination/.index\")\n}\n\n@test \"'import <notebook>:<filename> <file-path>' imports file to <notebook>:<filename>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import                         \\\n    \"Example Notebook:Example Destination.md\" \\\n    \"${_TMP_DIR}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination.md\" ]]\n\n  diff                                          \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")    \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Destination.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                  \\\n    <(ls \"${NB_DIR}/Example Notebook/\") \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"  ]]\n  [[ \"${output}\" =~ \\\nExample\\ Destination.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md  ]]\n}\n\n@test \"'import <file-path> <notebook>:<filename>' imports file to <notebook>:<filename>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import                 \\\n    \"${_TMP_DIR}/fixtures/example.md\" \\\n    \"Example Notebook:Example Destination.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/Example Destination.md\" ]]\n\n  diff                                          \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")    \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Destination.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                  \\\n    <(ls \"${NB_DIR}/Example Notebook/\") \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"  ]]\n  [[ \"${output}\" =~ \\\nExample\\ Destination.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md  ]]\n}\n\n@test \"'import <file-path> <notebook>:<folder>/<filename>' imports file to <notebook>:<folder>/<filename>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import                 \\\n    \"${_TMP_DIR}/fixtures/example.md\" \\\n    \"Example Notebook:Example Folder/Example Destination.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/Example Destination.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Example Destination.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/.index\"      ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Folder/\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*Example\\ Folder/Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"  ]]\n  [[ \"${output}\" =~ \\\nFolder/Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md           ]]\n}\n\n@test \"'import <notebook>:<folder>/<filename> <file-path>' imports file to <notebook>:<folder>/<filename>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import                                         \\\n    \"Example Notebook:Example Folder/Example Destination.md\"  \\\n    \"${_TMP_DIR}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/Example Destination.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Example Destination.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/.index\"      ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Folder/\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*Example\\ Folder/Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"  ]]\n  [[ \"${output}\" =~ \\\nFolder/Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md           ]]\n}\n\n@test \"'import <path> <notebook>:<folder>/' (slash) imports file to <notebook>:<folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"${_TMP_DIR}/fixtures/example.md\" \"Example Notebook:Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/example.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/.index\"      ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Folder/\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nFolder/example.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md          ]]\n}\n\n@test \"'import <notebook>:<folder>/ <path>' (slash) imports file to <notebook>:<folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"${_TMP_DIR}/fixtures/example.md\" \"Example Notebook:Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/example.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/.index\"      ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Folder/\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nFolder/example.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md          ]]\n}\n\n@test \"'import <path> <notebook>:<folder>' (no slash) imports file to <notebook>:<folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"${_TMP_DIR}/fixtures/example.md\" \"Example Notebook:Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/example.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/.index\"      ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Folder/\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nFolder/example.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md          ]]\n}\n\n@test \"'import <notebook>:<folder> <path>' (no slash) imports file to <notebook>:<folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"Example Notebook:Example Folder\" \"${_TMP_DIR}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/Example Notebook/Example Folder/example.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/.index\"      ]]\n\n  diff                                                  \\\n    <(ls \"${NB_DIR}/Example Notebook/Example Folder/\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nFolder/example.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md          ]]\n}\n\n@test \"'import ./* <folder>' (no slash) with valid * (glob) argument copies multiple files and directories into <folder>/.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Destination\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import ./* \"Example Destination\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/Example Destination/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Destination/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                                   ]]\n  [[ -d \"${NB_DIR}/home/Example Destination/Example Folder\"                     ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/Example Folder/example.md\"          ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/Example Folder/example.com.html\"    ]]\n  [[    \"${output}\"   =~ Example\\ Destination/Example\\ Folder                   ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                              ]]\n  [[ -d \"${NB_DIR}/home/Example Destination/bin\"                                ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/bin/bookmark\"                       ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/bin/mock_editor\"                    ]]\n  [[    \"${lines[1]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/bin                               ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"                        ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/copy-deprecated.nb-plugin\"          ]]\n  [[    \"${lines[2]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/copy-deprecated.nb-plugin         ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                              ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/example.com-og.html\"                ]]\n  [[    \"${lines[3]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/example.com-og.html               ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Destination/.index\" ]]\n\n  diff                                          \\\n    <(ls \"${NB_DIR}/home/Example Destination/\") \\\n    <(cat \"${NB_DIR}/home/Example Destination/.index\")\n}\n\n@test \"'import  <folder> ./*' (no slash) with valid * (glob) argument copies multiple files and directories into <folder>/.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Destination\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import \"Example Destination\" ./*\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/Example Destination/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Destination/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                                   ]]\n  [[ -d \"${NB_DIR}/home/Example Destination/Example Folder\"                     ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/Example Folder/example.md\"          ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/Example Folder/example.com.html\"    ]]\n  [[    \"${output}\"   =~ Example\\ Destination/Example\\ Folder                   ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                              ]]\n  [[ -d \"${NB_DIR}/home/Example Destination/bin\"                                ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/bin/bookmark\"                       ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/bin/mock_editor\"                    ]]\n  [[    \"${lines[1]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/bin                               ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"                        ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/copy-deprecated.nb-plugin\"          ]]\n  [[    \"${lines[2]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/copy-deprecated.nb-plugin         ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                              ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/example.com-og.html\"                ]]\n  [[    \"${lines[3]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/example.com-og.html               ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Destination/.index\" ]]\n\n  diff                                          \\\n    <(ls \"${NB_DIR}/home/Example Destination/\") \\\n    <(cat \"${NB_DIR}/home/Example Destination/.index\")\n}\n\n@test \"'import ./* <folder>/' (slash) with valid * (glob) argument copies multiple files and directories into <folder>/.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Destination\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import ./* \"Example Destination/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/Example Destination/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Destination/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                                   ]]\n  [[ -d \"${NB_DIR}/home/Example Destination/Example Folder\"                     ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/Example Folder/example.md\"          ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/Example Folder/example.com.html\"    ]]\n  [[    \"${output}\"   =~ Example\\ Destination/Example\\ Folder                   ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                              ]]\n  [[ -d \"${NB_DIR}/home/Example Destination/bin\"                                ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/bin/bookmark\"                       ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/bin/mock_editor\"                    ]]\n  [[    \"${lines[1]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/bin                               ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"                        ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/copy-deprecated.nb-plugin\"          ]]\n  [[    \"${lines[2]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/copy-deprecated.nb-plugin         ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                              ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/example.com-og.html\"                ]]\n  [[    \"${lines[3]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/example.com-og.html               ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Destination/.index\" ]]\n\n  diff                                          \\\n    <(ls \"${NB_DIR}/home/Example Destination/\") \\\n    <(cat \"${NB_DIR}/home/Example Destination/.index\")\n}\n\n@test \"'import <folder>/ ./*' (slash) with valid * (glob) argument copies multiple files and directories into <folder>/.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Destination\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import \"Example Destination/\" ./*\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/Example Destination/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\"  -eq 23 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Destination/Example Folder\"/*\n\n  [[ -d \"${_TMP_DIR}/fixtures/Example Folder\"                                   ]]\n  [[ -d \"${NB_DIR}/home/Example Destination/Example Folder\"                     ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/Example Folder/example.md\"          ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/Example Folder/example.com.html\"    ]]\n  [[    \"${output}\"   =~ Example\\ Destination/Example\\ Folder                   ]]\n\n  [[ -d \"${_TMP_DIR}/fixtures/bin\"                                              ]]\n  [[ -d \"${NB_DIR}/home/Example Destination/bin\"                                ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/bin/bookmark\"                       ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/bin/mock_editor\"                    ]]\n  [[    \"${lines[1]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/bin                               ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"                        ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/copy-deprecated.nb-plugin\"          ]]\n  [[    \"${lines[2]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/copy-deprecated.nb-plugin         ]]\n\n  [[ -e \"${_TMP_DIR}/fixtures/example.com-og.html\"                              ]]\n  [[ -f \"${NB_DIR}/home/Example Destination/example.com-og.html\"                ]]\n  [[    \"${lines[3]}\" =~ Imported                                               ]]\n  [[    \"${output}\"   =~ Example\\ Destination/example.com-og.html               ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Destination/.index\" ]]\n\n  diff                                          \\\n    <(ls \"${NB_DIR}/home/Example Destination/\") \\\n    <(cat \"${NB_DIR}/home/Example Destination/.index\")\n}\n\n@test \"'import <file-path> <filename>' imports file to <filename>.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"${_TMP_DIR}/fixtures/example.md\" \"Example Destination.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/home/Example Destination.md\" ]]\n\n  diff                                          \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")    \\\n    <(cat \"${NB_DIR}/home/Example Destination.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                          \\\n    <(ls \"${NB_DIR}/home/\")     \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"  ]]\n  [[ \"${output}\" =~ \\\nExample\\ Destination.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md  ]]\n}\n\n@test \"'import <filename> <file-path>' imports file to <filename>.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"Example Destination.md\" \"${_TMP_DIR}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/home/Example Destination.md\" ]]\n\n  diff                                          \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")    \\\n    <(cat \"${NB_DIR}/home/Example Destination.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                          \\\n    <(ls \"${NB_DIR}/home/\")     \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"  ]]\n  [[ \"${output}\" =~ \\\nExample\\ Destination.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md  ]]\n}\n\n@test \"'import <file-path> <folder>/<filename>' imports file to <folder>/<filename>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"${_TMP_DIR}/fixtures/example.md\" \"Example Folder/Example Destination.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/home/Example Folder/Example Destination.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/home/Example Folder/Example Destination.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"      ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home/Example Folder/\")    \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"  ]]\n  [[ \"${output}\" =~ \\\nFolder/Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md           ]]\n}\n\n@test \"'import <folder>/<filename> <file-path>' imports file to <folder>/<filename>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"Example Folder/Example Destination.md\" \"${_TMP_DIR}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/home/Example Folder/Example Destination.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/home/Example Folder/Example Destination.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"      ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home/Example Folder/\")    \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"  ]]\n  [[ \"${output}\" =~ \\\nFolder/Example\\ Destination.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md           ]]\n}\n\n@test \"'import <path> <folder>/' (slash) imports file to <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"${_TMP_DIR}/fixtures/example.md\" \"Example Folder/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"      ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home/Example Folder/\")    \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nFolder/example.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md          ]]\n}\n\n@test \"'import <folder>/ <path>' (slash) imports file to <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"Example Folder/\" \"${_TMP_DIR}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"      ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home/Example Folder/\")    \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nFolder/example.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md          ]]\n}\n\n@test \"'import <path> <folder>' (no slash) imports file to <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"${_TMP_DIR}/fixtures/example.md\" \"Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"      ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home/Example Folder/\")    \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nFolder/example.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md          ]]\n}\n\n@test \"'import <folder> <path>' (no slash) imports file to <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run \"${_NB}\" import \"Example Folder\" \"${_TMP_DIR}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/home/Example Folder/example.md\"  ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/home/Example Folder/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/Example Folder/.index\"      ]]\n\n  diff                                        \\\n    <(ls \"${NB_DIR}/home/Example Folder/\")    \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/example.md.*\\ \\\"Example\\ Title\\\" ]]\n  [[ \"${output}\" =~ \\\nFolder/example.md.*\\ \\\"Example\\ Title\\\"\\ from\\ .*${_TMP_DIR}/fixtures/example.md          ]]\n}\n\n# piped input #################################################################\n\n@test \"'import' with piped path imports files.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run bash -c \"echo \\\"${_TMP_DIR}/fixtures/example.md\\\" | ${_NB} import\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds file:\n\n  [[ -f \"${NB_DIR}/home/example.md\" ]]\n\n  diff                                        \\\n    <(cat \"${_TMP_DIR}/fixtures/example.md\")  \\\n    <(cat \"${NB_DIR}/home/example.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Imported    ]]\n  [[ \"${output}\" =~ example.md  ]]\n}\n\n@test \"'import' with multiple piped paths imports files.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n  }\n\n  run bash -c \"echo \\\"${_TMP_DIR}/fixtures/example.com\\\"* | ${_NB} import\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds files:\n\n  [[ -f \"${NB_DIR}/home/example.com-og.html\"  ]]\n  [[ -f \"${NB_DIR}/home/example.com.html\"     ]]\n  [[ -f \"${NB_DIR}/home/example.com.md\"       ]]\n\n  diff                                                \\\n    <(cat \"${_TMP_DIR}/fixtures/example.com-og.html\") \\\n    <(cat \"${NB_DIR}/home/example.com-og.html\")\n\n  diff                                                \\\n    <(cat \"${_TMP_DIR}/fixtures/example.com.html\")    \\\n    <(cat \"${NB_DIR}/home/example.com.html\")\n\n  diff                                                \\\n    <(cat \"${_TMP_DIR}/fixtures/example.com.md\")      \\\n    <(cat \"${NB_DIR}/home/example.com.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com-og.html.*\\ from\\ .*${_TMP_DIR}/fixtures/example.com-og.html                            ]]\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com-titles-newlines.html.*\\ from\\ .*${_TMP_DIR}/fixtures/example.com-titles-newlines.html  ]]\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com-titles.html.*\\ from\\ .*${_TMP_DIR}/fixtures/example.com-titles.html                    ]]\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com.html.*\\ from\\ .*${_TMP_DIR}/fixtures/example.com.html                                  ]]\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com.md.*\\ from\\ .*${_TMP_DIR}/fixtures/example.com.md                                      ]]\n}\n\n@test \"'import' with piped \\`ls\\` imports files.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run bash -c \"ls example.com* | ${_NB} import\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Adds files:\n\n  [[ -f \"${NB_DIR}/home/example.com-og.html\"  ]]\n  [[ -f \"${NB_DIR}/home/example.com.html\"     ]]\n  [[ -f \"${NB_DIR}/home/example.com.md\"       ]]\n\n  diff                                                \\\n    <(cat \"${_TMP_DIR}/fixtures/example.com-og.html\") \\\n    <(cat \"${NB_DIR}/home/example.com-og.html\")\n\n  diff                                                \\\n    <(cat \"${_TMP_DIR}/fixtures/example.com.html\")    \\\n    <(cat \"${NB_DIR}/home/example.com.html\")\n\n  diff                                                \\\n    <(cat \"${_TMP_DIR}/fixtures/example.com.md\")      \\\n    <(cat \"${NB_DIR}/home/example.com.md\")\n\n  # Adds to index:\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n\n  diff                      \\\n    <(ls \"${NB_DIR}/home\")  \\\n    <(cat \"${NB_DIR}/home/.index\")\n\n  # Prints output:\n\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com-og.html.*\\ from\\ .*example.com-og.html                           ]]\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com-titles-newlines.html.*\\ from\\ .*example.com-titles-newlines.html ]]\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com-titles.html.*\\ from\\ .*example.com-titles.html                   ]]\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com.html.*\\ from\\ .*example.com.html                                 ]]\n  [[ \"${output}\" =~ \\\nImported\\ .*[.*[0-9].*].*\\ .*example.com.md.*\\ from\\ .*example.com.md                                     ]]\n}\n\n# <path> ######################################################################\n\n@test \"'import' with valid <path> argument creates a new note file.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 1        ]]\n  [[ \"${lines[0]}\" =~ \"Imported\"  ]]\n  grep -q '# Example Title' \"${NB_DIR}/home\"/*\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Imported    ]]\n  [[ \"${output}\" =~ example.md  ]]\n}\n\n@test \"'import' with valid <path> argument creates git commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/example.md\"\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n}\n\n@test \"'import' with valid <path> argument gets a unique filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 2      ]]\n  [[ \"${lines[0]}\" =~ Imported  ]]\n  [[ \"${lines[0]}\" =~ example-1 ]]\n  grep -q '# Example Title' \"${NB_DIR}/home\"/*\n}\n\n# <directory path> ############################################################\n\n@test \"'import' with valid <directory path> argument imports a directory.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\"\n\n  IFS= _files=($(ls -1 \"${NB_DIR}/home/\"))\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n\n  [[ \"${#_files[@]}\" -eq 1 ]]\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n  [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n  [[ -f \"${NB_DIR}/home/Example Folder/example.md\"       ]]\n  [[ -f \"${NB_DIR}/home/Example Folder/example.com.html\" ]]\n  [[ \"${lines[0]}\" =~ \"Imported\" ]]\n\n  # creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Imported        ]]\n  [[ \"${output}\" =~ Example\\ Folder ]]\n}\n\n@test \"'import move' with valid <directory path> argument moves a directory.\" {\n  {\n    \"${_NB}\" init\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\" \"${_TMP_DIR}\"\n    [[ -e \"${_TMP_DIR}/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" import move \"${_TMP_DIR}/Example Folder\"\n\n  IFS= _files=($(ls -1 \"${NB_DIR}/home/\"))\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n\n  [[ ! -e \"${_TMP_DIR}/Example Folder\" ]]\n  [[ \"${#_files[@]}\" -eq 1 ]]\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n  [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n  [[ -f \"${NB_DIR}/home/Example Folder/example.md\"       ]]\n  [[ -f \"${NB_DIR}/home/Example Folder/example.com.html\" ]]\n  [[ \"${lines[0]}\" =~ \"Imported\" ]]\n\n  # creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Imported        ]]\n  [[ \"${output}\" =~ Example\\ Folder ]]\n}\n\n# * (glob) arguments ##########################################################\n\n@test \"'import' with valid * (glob) argument copies multiple files and directories.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import ./*\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\" -eq 23                                   ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  [[    -d \"${_TMP_DIR}/fixtures/Example Folder\"              ]]\n  [[    -d \"${NB_DIR}/home/Example Folder\"                    ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/example.md\"         ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/example.com.html\"   ]]\n  [[    \"${output}\" =~ Example\\ Folder                        ]]\n\n  [[    -d \"${_TMP_DIR}/fixtures/bin\"                         ]]\n  [[    -d \"${NB_DIR}/home/bin\"                               ]]\n  [[    -f \"${NB_DIR}/home/bin/bookmark\"                      ]]\n  [[    -f \"${NB_DIR}/home/bin/mock_editor\"                   ]]\n  [[    \"${lines[1]}\" =~ Imported                             ]]\n  [[    \"${output}\" =~ bin                                    ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\"   ]]\n  [[    -f \"${NB_DIR}/home/copy-deprecated.nb-plugin\"         ]]\n  [[    \"${lines[2]}\" =~ Imported                             ]]\n  [[    \"${output}\" =~ copy-deprecated.nb-plugin              ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.com-og.html\"         ]]\n  [[    -f \"${NB_DIR}/home/example.com-og.html\"               ]]\n  [[    \"${lines[3]}\" =~ Imported                             ]]\n  [[    \"${output}\" =~ example.com-og.html                    ]]\n\n  # creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n}\n\n@test \"'import' with valid *.md (glob) argument copies multiple markdown files.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import ./*.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\" -eq 2                                  ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.com.md\"            ]]\n  [[    -f \"${NB_DIR}/home/example.com.md\"                  ]]\n  [[    \"${output}\" =~ example.com.md                       ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.md\"                ]]\n  [[    -f \"${NB_DIR}/home/example.md\"                      ]]\n  [[    \"${output}\" =~ example.md                           ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/Example Folder\"            ]]\n  [[ !  -d \"${NB_DIR}/home/Example Folder\"                  ]]\n  [[ !  \"${output}\" =~ Example\\ Folder                      ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/bin\"                       ]]\n  [[ !  -d \"${NB_DIR}/home/bin\"                             ]]\n  [[ !  \"${output}\" =~ bin                                  ]]\n\n\n  [[    -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\" ]]\n  [[ !  -f \"${NB_DIR}/home/copy-deprecated.nb-plugin\"       ]]\n  [[ !  \"${output}\" =~ copy-deprecated.nb-plugin            ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.com-og.html\"       ]]\n  [[ !  -f \"${NB_DIR}/home/example.com-og.html\"             ]]\n  [[ !  \"${output}\" =~ example.com-og.html                  ]]\n\n  # creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                      ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n}\n\n@test \"'import' with multiple arguments copies multiple files or directories.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import \"Example Folder\" example.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\" -eq 2                                  ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.com.md\"            ]]\n  [[ !  -f \"${NB_DIR}/home/example.com.md\"                  ]]\n  [[ !  \"${output}\" =~ example.com.md                       ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.md\"                ]]\n  [[    -f \"${NB_DIR}/home/example.md\"                      ]]\n  [[    \"${output}\" =~ example.md                           ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/Example Folder\"            ]]\n  [[    -d \"${NB_DIR}/home/Example Folder\"                  ]]\n  [[    \"${output}\" =~ Example\\ Folder                      ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/bin\"                       ]]\n  [[ !  -d \"${NB_DIR}/home/bin\"                             ]]\n  [[ !  \"${output}\" =~ bin                                  ]]\n\n\n  [[    -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\" ]]\n  [[ !  -f \"${NB_DIR}/home/copy-deprecated.nb-plugin\"       ]]\n  [[ !  \"${output}\" =~ copy-deprecated.nb-plugin            ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.com-og.html\"       ]]\n  [[ !  -f \"${NB_DIR}/home/example.com-og.html\"             ]]\n  [[ !  \"${output}\" =~ example.com-og.html                  ]]\n\n  # creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n}\n\n@test \"'import move' with valid * (glob) argument moves multiple files and directories.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import move ./*\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\" -eq 23                                 ]]\n\n  grep -q '# Example Title' \"${NB_DIR}/home/Example Folder\"/*\n\n  [[ !  -e \"${_TMP_DIR}/fixtures/Example Folder\"            ]]\n  [[    -d \"${NB_DIR}/home/Example Folder\"                  ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/example.md\"       ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/example.com.html\" ]]\n  [[    \"${output}\" =~ Example\\ Folder                      ]]\n\n  [[ !  -e \"${_TMP_DIR}/fixtures/bin\"                       ]]\n  [[    -d \"${NB_DIR}/home/bin\"                             ]]\n  [[    -f \"${NB_DIR}/home/bin/bookmark\"                    ]]\n  [[    -f \"${NB_DIR}/home/bin/mock_editor\"                 ]]\n  [[    \"${lines[1]}\" =~ Imported                           ]]\n  [[    \"${output}\" =~ bin                                  ]]\n\n  [[ !  -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\" ]]\n  [[    -f \"${NB_DIR}/home/copy-deprecated.nb-plugin\"       ]]\n  [[    \"${lines[2]}\" =~ Imported                           ]]\n  [[    \"${output}\" =~ copy-deprecated.nb-plugin            ]]\n\n  [[ !  -e \"${_TMP_DIR}/fixtures/example.com-og.html\"       ]]\n  [[    -f \"${NB_DIR}/home/example.com-og.html\"             ]]\n  [[    \"${lines[3]}\" =~ Imported                           ]]\n  [[    \"${output}\" =~ example.com-og.html                  ]]\n\n  # creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n}\n\n@test \"'import move' with valid *.md (glob) argument moves multiple markdown files.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import move ./*.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\" -eq 2                                  ]]\n\n  [[ !  -e \"${_TMP_DIR}/fixtures/example.com.md\"            ]]\n  [[    -f \"${NB_DIR}/home/example.com.md\"                  ]]\n  [[    \"${output}\" =~ example.com.md                       ]]\n\n  [[ !  -e \"${_TMP_DIR}/fixtures/example.md\"                ]]\n  [[    -f \"${NB_DIR}/home/example.md\"                      ]]\n  [[    \"${output}\" =~ example.md                           ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/Example Folder\"            ]]\n  [[ !  -d \"${NB_DIR}/home/Example Folder\"                  ]]\n  [[ !  \"${output}\" =~ Example\\ Folder                      ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/bin\"                       ]]\n  [[ !  -d \"${NB_DIR}/home/bin\"                             ]]\n  [[ !  \"${output}\" =~ bin                                  ]]\n\n\n  [[    -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\" ]]\n  [[ !  -f \"${NB_DIR}/home/copy-deprecated.nb-plugin\"       ]]\n  [[ !  \"${output}\" =~ copy-deprecated.nb-plugin            ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.com-og.html\"       ]]\n  [[ !  -f \"${NB_DIR}/home/example.com-og.html\"             ]]\n  [[ !  \"${output}\" =~ example.com-og.html                  ]]\n\n  # creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n}\n\n@test \"'import move' with multiple arguments moves multiple files or directories.\" {\n  {\n    \"${_NB}\" init\n\n    cp -R \"${NB_TEST_BASE_PATH}/fixtures\" \"${_TMP_DIR}\"\n\n    [[ -e \"${_TMP_DIR}/fixtures\" ]]\n\n    cd \"${_TMP_DIR}/fixtures\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/fixtures\" ]]\n    [[ -d \"${NB_DIR}/home\"                ]]\n  }\n\n  run \"${_NB}\" import move \"Example Folder\" example.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  IFS=$'\\n' _files=($(ls -1 \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[@]}: '%s'\\\\n\" \"${_files[@]}\"\n  printf \"\\${#_files[@]}: '%s'\\\\n\" \"${#_files[@]}\"\n\n  [[ \"${#_files[@]}\" -eq 2                                  ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.com.md\"            ]]\n  [[ !  -f \"${NB_DIR}/home/example.com.md\"                  ]]\n  [[ !  \"${output}\" =~ example.com.md                       ]]\n\n  [[ !  -e \"${_TMP_DIR}/fixtures/example.md\"                ]]\n  [[    -f \"${NB_DIR}/home/example.md\"                      ]]\n  [[    \"${output}\" =~ example.md                           ]]\n\n  [[ !  -e \"${_TMP_DIR}/fixtures/Example Folder\"            ]]\n  [[    -d \"${NB_DIR}/home/Example Folder\"                  ]]\n  [[    \"${output}\" =~ Example\\ Folder                      ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/bin\"                       ]]\n  [[ !  -d \"${NB_DIR}/home/bin\"                             ]]\n  [[ !  \"${output}\" =~ bin                                  ]]\n\n\n  [[    -e \"${_TMP_DIR}/fixtures/copy-deprecated.nb-plugin\" ]]\n  [[ !  -f \"${NB_DIR}/home/copy-deprecated.nb-plugin\"       ]]\n  [[ !  \"${output}\" =~ copy-deprecated.nb-plugin            ]]\n\n  [[    -e \"${_TMP_DIR}/fixtures/example.com-og.html\"       ]]\n  [[ !  -f \"${NB_DIR}/home/example.com-og.html\"             ]]\n  [[ !  \"${output}\" =~ example.com-og.html                  ]]\n\n  # creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n}\n\n# <url> ######################################################################\n\n@test \"'import' with valid <url> argument creates a new note file.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" import \"file://${NB_TEST_BASE_PATH}/fixtures/example.com.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  grep -q 'Example' \"${NB_DIR}/home\"/*\n\n  [[ \"${output}\" =~ \"Imported\" ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n  git log | grep -q 'Source'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Imported          ]]\n  [[ \"${output}\" =~ example.com.html  ]]\n}\n\n@test \"'import <url> <notebook>:' with valid <url> argument creates a new file in <notebook>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" import \"file://${NB_TEST_BASE_PATH}/fixtures/example.com.html\" \"Example Notebook:\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/Example Notebook/\"))\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  grep -q 'Example' \"${NB_DIR}/Example Notebook\"/*\n\n  [[ \"${output}\" =~ \"Imported\" ]]\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n  git log | grep -q 'Source'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                  \\\n    <(ls \"${NB_DIR}/Example Notebook\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output\n  [[ \"${output}\" =~ Imported            ]]\n  [[ \"${output}\" =~ example.com.html    ]]\n}\n\n@test \"'import <notebook>: <url>' with valid <url> argument creates a new file in <notebook>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" import \"Example Notebook:\" \"file://${NB_TEST_BASE_PATH}/fixtures/example.com.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/Example Notebook/\"))\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  grep -q 'Example' \"${NB_DIR}/Example Notebook\"/*\n\n  [[ \"${output}\" =~ \"Imported\" ]]\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n  git log | grep -q 'Source'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/Example Notebook/.index\" ]]\n\n  diff                                  \\\n    <(ls \"${NB_DIR}/Example Notebook\")  \\\n    <(cat \"${NB_DIR}/Example Notebook/.index\")\n\n  # Prints output\n  [[ \"${output}\" =~ Imported            ]]\n  [[ \"${output}\" =~ example.com.html    ]]\n}\n\n@test \"'import --convert' with valid <url> creates and converts a new note file.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" import \\\n    --convert         \\\n    \"file://${NB_TEST_BASE_PATH}/fixtures/example.com.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  grep -q '# Example Domain' \"${NB_DIR}/home/${_files[0]}\"\n\n  [[ \"${output}\" =~ \"Imported\" ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n  git log | grep -q 'Source'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Imported          ]]\n  [[ \"${output}\" =~ example.com.html  ]]\n}\n\n@test \"'import download' with valid <url> argument creates a new note file.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" import download \"file://${NB_TEST_BASE_PATH}/fixtures/example.com.html\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  [[ \"${#_files[@]}\" -eq 1 ]]\n\n  grep -q 'Example' \"${NB_DIR}/home\"/*\n\n  [[ \"${output}\" =~ \"Imported\" ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Import'\n  git log | grep -q 'Source'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/home/.index\"                                   ]]\n  [[ \"$(ls \"${NB_DIR}/home\")\" == \"$(cat \"${NB_DIR}/home/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Imported          ]]\n  [[ \"${output}\" =~ example.com.html  ]]\n}\n\n# `notebook` ##################################################################\n\n@test \"'import notebook' with valid <path> and <name> imports.\" {\n  \"${_NB}\" init\n\n  run \"${_NB}\" import notebook                      \\\n    \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\"  \\\n    \"example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${NB_DIR}\"\n\n  [[    \"${status}\"         -eq 0       ]]\n  [[ -d \"${NB_DIR}/example\"             ]]\n  [[    \"${lines[0]}\"       =~ Imported ]]\n\n  \"${_NB}\" notebooks | grep -q 'example'\n\n  # Prints output\n  [[ \"${output}\" =~ Imported  ]]\n  [[ \"${output}\" =~ example   ]]\n}\n\n# help ########################################################################\n\n@test \"'help import' returns usage information.\" {\n  run \"${_NB}\" help import\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\:       ]]\n  [[ \"${lines[1]}\" =~ \\ \\ nb\\ import  ]]\n}\n"
  },
  {
    "path": "test/index-rebuild.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2012\n\nload test_helper\n\n# index rebuild ###############################################################\n\n@test \"'index rebuild' skips common temporary files.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    sleep 1\n\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    sleep 1\n\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    sleep 1\n\n    declare _temp_filenames=(\n      \"Example Temp One.md~\"\n      \"#Example Temp Two.md#\"\n      \"Example Temp Three.md.swp\"\n      \"Example Temp Four.md.swap\"\n      \".#Example Temp Five.md\"\n    )\n\n    declare __filename=\n    for     __filename in \"${_temp_filenames[@]:-}\"\n    do\n      \"${_NB}\" run touch \"${__filename:-}\"\n\n      [[ -f \"${NB_DIR}/home/${__filename:-}\" ]]\n    done\n\n    echo \"\" > \"${NB_DIR}/home/.index\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"\" ]]\n  }\n\n  run \"${_NB}\" index rebuild\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls -t -r \"${NB_DIR}/home\"\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  diff                              \\\n    <(cat \"${NB_DIR}/home/.index\")  \\\n    <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nHEREDOC\n    )\n}\n\n@test \"'index rebuild' rebuilds the index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n    \"${_NB}\" add \"second.md\" --title \"two\"\n    \"${_NB}\" add \"third.md\"  --title \"three\"\n\n    \"${_NB}\" edit \"second.md\" --content \"New content.\"\n\n    echo \"\" > \"${NB_DIR}/home/.index\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"\" ]]\n  }\n\n  run \"${_NB}\" index rebuild\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls -t -r \"${NB_DIR}/home\"\n\n  [[ \"${status}\" -eq 0                                                  ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"$(ls -t -r \"${NB_DIR}/home\")\" ]]\n}\n\n@test \"'index rebuild' creates git commit.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n    \"${_NB}\" delete \"${_filename}\" --force\n    \"${_NB}\" add\n  }\n\n  run \"${_NB}\" index rebuild\n\n  cd \"${NB_DIR}/home\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Rebuild Index'\n}\n\n@test \"'index rebuild' with no index creates git commit with operation-specific message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n    \"${_NB}\" use one\n    \"${_NB}\" add --filename \"example.md\"\n\n    [[   -e \"${NB_DIR:?}/one/.index\"      ]]\n    [[   -e \"${NB_DIR:?}/one/example.md\"  ]]\n\n    rm \"${NB_DIR:?}/one/.index\"\n\n    \"${_NB}\" git checkpoint\n\n    [[ ! -e \"${NB_DIR:?}/one/.index\"      ]]\n    [[   -e \"${NB_DIR:?}/one/example.md\"  ]]\n\n    printf \"End setup.\\\\n\"\n  }\n\n  run \"${_NB}\" index rebuild\n\n  [[ \"${status}\" == 0                   ]]\n\n  [[   -e \"${NB_DIR:?}/one/.index\"      ]]\n  [[   -e \"${NB_DIR:?}/one/example.md\"  ]]\n\n  diff <(cat \"${NB_DIR:?}/one/.index\") <(printf \"example.md\\\\n\")\n\n  cd \"${NB_DIR:?}/one\" || return 1\n\n  git log --stat\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Initialize Index'\n}\n"
  },
  {
    "path": "test/index-reconcile.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# reconcile ###################################################################\n\n@test \"'index reconcile' skips common temporary files when .index is not present.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    sleep 1\n\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    sleep 1\n\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    sleep 1\n\n    declare _temp_filenames=(\n      \"Example Temp One.md~\"\n      \"#Example Temp Two.md#\"\n      \"Example Temp Three.md.swp\"\n      \"Example Temp Four.md.swap\"\n      \".#Example Temp Five.md\"\n    )\n\n    declare __filename=\n    for     __filename in \"${_temp_filenames[@]:-}\"\n    do\n      \"${_NB}\" run touch \"${__filename:-}\"\n\n      [[ -f \"${NB_DIR}/home/${__filename:-}\" ]]\n    done\n\n    rm \"${NB_DIR}/home/.index\"\n\n    [[ ! -e \"${NB_DIR}/home/.index\" ]]\n  }\n\n  run \"${_NB}\" index reconcile\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"LS: \\\\n\"\n\n  ls -t -r \"${NB_DIR}/home\"\n\n  printf \"INDEX: \\\\n\"\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  diff                              \\\n    <(cat \"${NB_DIR}/home/.index\")  \\\n    <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nHEREDOC\n    )\n}\n\n@test \"'index reconcile' skips common temporary files when empty .index exists.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    sleep 1\n\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    sleep 1\n\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    sleep 1\n\n    declare _temp_filenames=(\n      \"Example Temp One.md~\"\n      \"#Example Temp Two.md#\"\n      \"Example Temp Three.md.swp\"\n      \"Example Temp Four.md.swap\"\n      \".#Example Temp Five.md\"\n    )\n\n    declare __filename=\n    for     __filename in \"${_temp_filenames[@]:-}\"\n    do\n      \"${_NB}\" run touch \"${__filename:-}\"\n\n      [[ -f \"${NB_DIR}/home/${__filename:-}\" ]]\n    done\n\n    echo \"\" > \"${NB_DIR}/home/.index\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"\" ]]\n  }\n\n  run \"${_NB}\" index reconcile\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"LS: \\\\n\"\n\n  ls -t -r \"${NB_DIR}/home\"\n\n  printf \"INDEX: \\\\n\"\n\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  diff                              \\\n    <(cat \"${NB_DIR}/home/.index\")  \\\n    <(cat <<HEREDOC\n\nFile One.md\nFile Three.md\nFile Two.md\nHEREDOC\n    )\n}\n\n@test \"'index reconcile' does not create a git commit.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n    \"${_NB}\" add \"second.md\" --title \"two\"\n\n    echo \"# Example\" > \"${NB_DIR}/home/example.md\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" != \"$(ls \"${NB_DIR}/home\")\" ]]\n  }\n\n  run \"${_NB}\" index reconcile\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"${status}\" -eq 0                              ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ example.md ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  [[ -n \"$(git status --porcelain)\"                 ]]\n\n  \"${_NB}\" index verify\n}\n\n@test \"'index reconcile' does not modify a valid index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n    \"${_NB}\" add \"second.md\" --title \"two\"\n\n    printf \\\n      \"\\\"\\$(cat \\\"\\${NB_DIR}/home/.index\\\")\\\": '%s'\\\\n\" \\\n      \"$(cat \"${NB_DIR}/home/.index\")\"\n    printf \"\\$(ls -r \\${NB_DIR}/home): '%s'\\\\n\" \"$(ls \"${NB_DIR}/home\")\"\n\n    _existing_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"$(ls \"${NB_DIR}/home\")\" ]]\n  }\n\n  run \"${_NB}\" index reconcile\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" index verify\n\n  [[ \"${status}\" -eq 0                                        ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"${_existing_index}\" ]]\n}\n\n@test \"'index reconcile' updates when file has been deleted.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n    \"${_NB}\" add \"second.md\" --title \"two\"\n\n    printf \"not-a-file\\n\" >> \"${NB_DIR}/home/.index\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" != \"$(ls \"${NB_DIR}/home\")\" ]]\n  }\n\n  run \"${_NB}\" index reconcile\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"${status}\" -eq 0                                ]]\n  [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ not-a-file ]]\n\n  \"${_NB}\" index verify\n}\n\n@test \"'index reconcile' updates when file has been added.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n    \"${_NB}\" add \"second.md\" --title \"two\"\n\n    echo \"# Example\" > \"${NB_DIR}/home/example.md\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" != \"$(ls \"${NB_DIR}/home\")\" ]]\n  }\n\n  run \"${_NB}\" index reconcile\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/.index\"\n\n  [[ \"${status}\" -eq 0                                ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ example.md   ]]\n\n  \"${_NB}\" index verify\n}\n\n@test \"'index reconcile' updates when files have been added and deleted.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n\n    printf \"\\\\n\" >> \"${NB_DIR}/home/.index\"\n    printf \"\\\\n\" >> \"${NB_DIR}/home/.index\"\n\n    \"${_NB}\" add \"second.md\" --title \"two\"\n\n    printf \"not-a-file\\\\n\"    >> \"${NB_DIR}/home/.index\"\n    printf \"also-no-file\\\\n\"  >> \"${NB_DIR}/home/.index\"\n    echo \"# Example\"          > \"${NB_DIR}/home/example.md\"\n    echo \"# Sample\"           > \"${NB_DIR}/home/sample.md\"\n\n    # NOTE: `index get_id` calls `reconcile` when filename is not found.\n    printf \"first.md id: %s\\\\n\"   \"$(\"${_NB}\" index get_id \"first.md\")\"\n    printf \"second.md id: %s\\\\n\"  \"$(\"${_NB}\" index get_id \"second.md\")\"\n\n    if sed --help >/dev/null 2>&1\n    then\n      sed -i -e \"s/^first.md$//g\" \"${NB_DIR}/home/.index\"\n    else\n      sed -i '' -e \"s/^first.md$//g\" \"${NB_DIR}/home/.index\"\n    fi\n\n    printf \".index: '%s'\\\\n\" \"$(cat \"${NB_DIR}/home/.index\")\"\n    printf \"ls: '%s'\\\\n\" \"$(ls \"${NB_DIR}/home\")\"\n\n    [[    \"$(cat \"${NB_DIR}/home/.index\")\"        != \"$(ls \"${NB_DIR}/home\")\" ]]\n    [[ !  \"$(cat \"${NB_DIR}/home/.index\")\"        =~ first.md                 ]]\n    [[ !  \"$(cat \"${NB_DIR}/home/.index\")\"        =~ sample.md                ]]\n    [[ !  \"$(cat \"${NB_DIR}/home/.index\")\"        =~ sample.md                ]]\n    [[    \"$(cat \"${NB_DIR}/home/.index\")\"        =~ not-a-file               ]]\n    [[    \"$(cat \"${NB_DIR}/home/.index\")\"        =~ also-no-file             ]]\n    [[    \"$(\"${_NB}\" index get_id \"second.md\")\"  == '4'                      ]]\n  }\n\n  run \"${_NB}\" index reconcile\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/.index\"\n\n  [[    ${status} -eq 0                                         ]]\n  [[    \"$(cat \"${NB_DIR}/home/.index\")\"        =~ first.md     ]]\n  [[    \"$(cat \"${NB_DIR}/home/.index\")\"        =~ example.md   ]]\n  [[    \"$(cat \"${NB_DIR}/home/.index\")\"        =~ sample.md    ]]\n  [[ !  \"$(cat \"${NB_DIR}/home/.index\")\"        =~ not-a-file   ]]\n  [[ !  \"$(cat \"${NB_DIR}/home/.index\")\"        =~ also-no-file ]]\n  [[    \"$(\"${_NB}\" index get_id \"second.md\")\"  == '4'          ]]\n  [[    \"$(\"${_NB}\" index get_id \"example.md\")\" == '7'          ]]\n  [[    \"$(\"${_NB}\" index get_id \"first.md\")\"   == '8'          ]]\n  [[    \"$(\"${_NB}\" index get_id \"sample.md\")\"  == '9'          ]]\n\n  \"${_NB}\" index verify\n}\n"
  },
  {
    "path": "test/index.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# #############################################################################\n\n@test \"'index' builds an index if one doesn't exist.\" {\n  {\n    \"${_NB}\" init\n\n    rm \"${NB_DIR}/home/.index\"\n\n    [[ ! -e \"${NB_DIR}/home/.index\" ]]\n  }\n\n  run \"${_NB}\" index\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n}\n\n# add #########################################################################\n\n@test \"'index add <filename>' adds an item to the index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n\n    echo \"\" > \"${NB_DIR}/home/.index\"\n\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ ^first.md$ ]]\n  }\n\n  run \"${_NB}\" index add \"$(ls \"${NB_DIR}/home\")\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\$(cat \\${NB_DIR}/home/.index): '%s'\\\\n\" \\\n    \"$(cat \"${NB_DIR}/home/.index\")\"\n  printf \"\\$(ls ${NB_DIR}/home): '%s'\\\\n\" \"$(ls \"${NB_DIR}/home\")\"\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ first.md$ ]]\n}\n\n@test \"'index add' with no argument returns 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n\n    echo \"\" > \"${NB_DIR}/home/.index\"\n\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ ^first.md$ ]]\n  }\n\n  run \"${_NB}\" index add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                           ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\:                   ]]\n  [[ \"${lines[1]}\"  ==  \"  nb index add <filename>\" ]]\n}\n\n@test \"'index add <filename>' with non-file returns 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n\n    echo \"\" > \"${NB_DIR}/home/.index\"\n\n    [[ ! \"$(cat \"${NB_DIR}/home/.index\")\" =~ ^first.md$ ]]\n  }\n\n  run \"${_NB}\" index add 'not-a-file'\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                 ]]\n  [[ \"${lines[0]}\"  =~  File\\ not\\ found  ]]\n}\n\n@test \"'index add <filename>' with existing entry does nothing.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ ^first.md$ ]]\n  }\n\n  run \"${_NB}\" index add \"$(ls \"${NB_DIR}/home\")\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" =~ ^first.md$   ]]\n  [[ -z \"${lines[1]}\"                                 ]]\n}\n\n@test \"'index add <filename>' skips temporary files.\" {\n  {\n    \"${_NB}\" init\n\n    declare _temp_filenames=(\n      \"Example Temp One.md~\"\n      \"#Example Temp Two.md#\"\n      \"Example Temp Three.md.swp\"\n      \"Example Temp Four.md.swap\"\n      \".#Example Temp Five.md\"\n    )\n\n    declare __filename=\n    for     __filename in \"${_temp_filenames[@]:-}\"\n    do\n      \"${_NB}\" run touch \"${__filename:-}\"\n    done\n  }\n\n  declare __filename=\n  for     __filename in \"${_temp_filenames[@]:-}\"\n  do\n    run \"${_NB}\" index add \"${__filename:-}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[    \"${status}\" -eq 0                 ]]\n    [[ -z \"${output}\"                       ]]\n    [[ -z \"$(cat \"${NB_DIR/home/.index}\")\"  ]]\n  done\n}\n\n# get_basename ################################################################\n\n@test \"'index get_basename' with valid index prints the filename for an id.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# one\"\n  }\n\n  run \"${_NB}\" index get_basename 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${lines[0]}\"  =~  20[0-9]+\\.md$ ]]\n}\n\n@test \"'index get_basename' with invalid index prints nothing.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n  }\n\n  run \"${_NB}\" index get_basename 12345\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'index get_basename' with no argument returns 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n  }\n\n  run \"${_NB}\" index get_basename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1         ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\: ]]\n}\n\n# get_id #########################################################################\n\n@test \"'index get_id <filename>' returns the id for <filename>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n  }\n\n  run \"${_NB}\" index get_id \"$(ls \"${NB_DIR}/home\")\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0   ]]\n  [[ \"${output}\"  ==  \"1\" ]]\n}\n\n@test \"'index get_id' with no argument returns 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n  }\n\n  run \"${_NB}\" index get_id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1         ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\: ]]\n}\n\n@test \"'index get_id <filename>' with non-entry returns 1.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n  }\n\n  run \"${_NB}\" index get_id 'not-an-entry'\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n# get_max_id ##################################################################\n\n@test \"'index get_max_id' returns the max id number.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"    --title \"one\"\n    \"${_NB}\" add \"second.md\"   --title \"two\"\n    \"${_NB}\" add \"third.md\"    --title \"three\"\n  }\n\n  run \"${_NB}\" index get_max_id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${lines[0]}\"  ==  \"3\" ]]\n}\n\n@test \"'index get_max_id' with empty notebook returns 0.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" index get_max_id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${lines[0]}\"  ==  \"0\" ]]\n}\n\n# delete ######################################################################\n\n@test \"'index delete <filename>' deletes an item from the index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n  }\n\n  run \"${_NB}\" index delete \"$(ls \"${NB_DIR}/home\")\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                      ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"\" ]]\n}\n\n@test \"'index delete <filename>' with brackets and spaces in filename deletes an item from the index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"[ ] first.md\"  --title \"one\"\n  }\n\n  run \"${_NB}\" index delete \"$(ls \"${NB_DIR}/home\")\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                      ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"\" ]]\n}\n\n@test \"'index delete' with no argument returns 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n  }\n\n  run \"${_NB}\" index delete\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1         ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\: ]]\n}\n\n@test \"'index delete <filename>' with non-file returns 1 and prints nothing.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n  }\n\n  run \"${_NB}\" index delete 'not-a-file'\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 1 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n# show ########################################################################\n\n@test \"'index show' prints index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# one\"\n  }\n\n  run \"${_NB}\" index show\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                                 ]]\n  [[ \"${output}\" ==   \"$(cat \"${NB_DIR}/home/.index\")\"  ]]\n}\n\n# update ######################################################################\n\n@test \"'index update <old> <new>' updates the index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# one\"\n  }\n\n  run \"${_NB}\" index update \"$(ls \"${NB_DIR}/home\")\" \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \\\n    \"$(cat \\\"\\$\\{NB_DIR\\}/home/.index\\\"): '%s'\\\\n\" \\\n    \"$(cat \"${NB_DIR}/home/.index\")\"\n\n  [[ \"${status}\" -eq 0                                ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"example.md\" ]]\n}\n\n@test \"'index update <old> <new>' with brackets and spaces in <old> filename updates the index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"[ ] first.md\" --title \"# one\"\n  }\n\n  run \"${_NB}\" index update \"$(ls \"${NB_DIR}/home\")\" \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \\\n    \"$(cat \\\"\\$\\{NB_DIR\\}/home/.index\\\"): '%s'\\\\n\" \\\n    \"$(cat \"${NB_DIR}/home/.index\")\"\n\n  [[ \"${status}\" -eq 0                                ]]\n  [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"example.md\" ]]\n}\n\n@test \"'index update' with no arguments returns 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# one\"\n  }\n\n  run \"${_NB}\" index update\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1         ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\: ]]\n}\n\n@test \"'index update' with first argument returns 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# one\"\n  }\n\n  run \"${_NB}\" index update \"$(ls \"${NB_DIR}/home\")\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1         ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\: ]]\n}\n\n# verify ######################################################################\n\n@test \"'index verify' verifies a valid index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n    \"${_NB}\" add \"second.md\" --title \"two\"\n\n    printf \\\n      \"\\\"\\$(cat \\\"\\${NB_DIR}/home/.index\\\")\\\": '%s'\\\\n\" \\\n      \"$(cat \"${NB_DIR}/home/.index\")\"\n    printf \"\\$(ls \\${NB_DIR}/home): '%s'\\\\n\" \"$(ls \"${NB_DIR}/home\")\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" == \"$(ls \"${NB_DIR}/home\")\" ]]\n  }\n\n  run \"${_NB}\" index verify\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n@test \"'index verify' returns 1 with an invalid index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n    \"${_NB}\" add \"second.md\" --title \"two\"\n\n    printf \"not-a-file\\\\n\" >> \"${NB_DIR}/home/.index\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" != \"$(ls \"${NB_DIR}/home\")\" ]]\n  }\n\n  run \"${_NB}\" index verify\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                       ]]\n  [[ \"${lines[0]}\"  =~  !.*\\ Index\\ corrupted\\.\\ To\\ fix,\\ run: ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ index\\ reconcile                ]]\n}\n\n@test \"'index verify' returns 1 with a duplicates.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"first.md\"  --title \"one\"\n    \"${_NB}\" add \"second.md\" --title \"two\"\n\n    printf \"second.md\\\\n\" >> \"${NB_DIR}/home/.index\"\n\n    [[ \"$(cat \"${NB_DIR}/home/.index\")\" != \"$(ls \"${NB_DIR}/home\")\" ]]\n  }\n\n  run \"${_NB}\" index verify\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                       ]]\n  [[ \"${lines[0]}\"  =~  !.*\\ Index\\ corrupted\\.\\ To\\ fix,\\ run: ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ index\\ reconcile                ]]\n}\n\n@test \"'index verify' skips common temporary files.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"File Two.md\" --content \"Example content two.\"\n\n    declare _temp_filenames=(\n      \"Example Temp One.md~\"\n      \"#Example Temp Two.md#\"\n      \"Example Temp Three.md.swp\"\n      \"Example Temp Four.md.swap\"\n      \".#Example Temp Five.md\"\n    )\n\n    declare __filename=\n    for     __filename in \"${_temp_filenames[@]:-}\"\n    do\n      touch \"${NB_DIR}/home/${__filename:-}\"\n    done\n\n    diff                              \\\n      <(cat \"${NB_DIR}/home/.index\")  \\\n      <(cat <<HEREDOC\nFile One.md\nFile Two.md\nHEREDOC\n      )\n  }\n\n  run \"${_NB}\" index verify\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0 ]]\n  [[ -z \"${output}\"       ]]\n}\n\n# help ########################################################################\n\n@test \"'help index' exits with status 0.\" {\n  run \"${_NB}\" help index\n\n  [[ ${status} -eq 0 ]]\n}\n\n@test \"'help index' prints help information.\" {\n  run \"${_NB}\" help index\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Usage.*\\:                   ]]\n  [[ \"${lines[1]}\" == \"  nb index add <filename>\" ]]\n}\n"
  },
  {
    "path": "test/init.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# _GIT_ENABLED ################################################################\n\n@test \"_GIT_ENABLED=0 'init' exits with status 0 and creates notebook directory without .git.\" {\n  _GIT_ENABLED=0 run \"${_NB}\" init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls -la \"${NB_DIR}/home\"\n\n  [[        \"${status}\" == 0      ]]\n\n  [[    -d  \"${NB_DIR}/home\"      ]]\n  [[ !  -e  \"${NB_DIR}/home/.git\" ]]\n}\n\n# remote ######################################################################\n\n@test \"'init <remote-url> <branch>' creates a clone in '\\$NB_NOTEBOOK_PATH' / '\\$NB_DIR/home'.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n\n    mv \"${NB_DIR}\" \"${NB_DIR}.bak\"\n\n    [[ ! -e \"${NB_DIR}\" ]]\n  }\n\n  run \"${_NB}\" init \"${_GIT_REMOTE_URL}\" \"example-branch\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  diff                                                            \\\n    <(cd \"${NB_DIR}/home\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                            \\\n    <(cd \"${NB_DIR}/home\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"example-branch\\\\n\")\n\n  [[ -f \"${NB_DIR}/home/Example File One.md\" ]]\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n}\n\n@test \"'init <remote-url>' creates a clone in '\\$NB_NOTEBOOK_PATH' / '\\$NB_DIR/home'.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n\n    mv \"${NB_DIR}\" \"${NB_DIR}.bak\"\n\n    [[ ! -e \"${NB_DIR}\" ]]\n  }\n\n  run \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  diff                                                            \\\n    <(cd \"${NB_DIR}/home\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                            \\\n    <(cd \"${NB_DIR}/home\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"master\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ master                                ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/HEAD\\ \\-\\>\\ origin/master  ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/master                     ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  example-branch                            ]]\n}\n\n# config ######################################################################\n\n@test \"'init --author' displays config prompt and sets email and name.\" {\n  run \"${_NB}\" init --author \\\n    <<< \"y${_NEWLINE}local@example.test${_NEWLINE}Example Local Name${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 18  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\"  ]]\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\"  ]]\n\n  declare _global_email=\n  _global_email=\"$(\n    git -C \"${NB_DIR}/home\" config --global user.email \\\n      || git config user.email\n  )\"\n\n  declare _global_name=\n  _global_name=\"$(\n    git -C \"${NB_DIR}/home\" config --global user.name \\\n      || git config user.name\n  )\"\n\n  [[ \"${lines[8]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  [[ \"${lines[12]}\" =~ \\\nEnter\\ a\\ new\\ value,\\ .*unset.*\\ to\\ use\\ the\\ global\\ value,                ]]\n  [[ \"${lines[13]}\" =~ or\\ leave\\ blank\\ to\\ keep\\ the\\ current\\ value\\.      ]]\n\n  [[ \"${lines[14]}\" =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[15]}\" =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[16]}\" =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[17]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n# --email and --name ##########################################################\n\n@test \"'init --email <email> --name <name>' sets the local email and name.\" {\n  run \"${_NB}\" init               \\\n    --email \"local@example.test\"  \\\n    --name  \"Example Local Name\"  \\\n    <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 20  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(\n    git -C \"${NB_DIR}/home\" config --global user.email \\\n      || git config user.email\n  )\"\n\n  declare _global_name=\n  _global_name=\"$(\n    git -C \"${NB_DIR}/home\" config --global user.name \\\n      || git config user.name\n  )\"\n\n  [[ \"${lines[8]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[12]}\" =~ Update:                                                ]]\n  [[ \"${lines[13]}\" =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[14]}\" =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[15]}\" =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[16]}\" =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[17]}\" =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[18]}\" =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[19]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n@test \"'init --email <email>' sets the local email.\" {\n  run \"${_NB}\"  init              \\\n    --email \"local@example.test\"  \\\n    <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 19  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(\n    git -C \"${NB_DIR}/home\" config --global user.email \\\n      || git config user.email\n  )\"\n\n  declare _global_name=\n  _global_name=\"$(\n    git -C \"${NB_DIR}/home\" config --global user.name \\\n      || git config user.name\n  )\"\n\n  [[ \"${lines[8]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[12]}\" =~ Update:                                                ]]\n  [[ \"${lines[13]}\" =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[14]}\" =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[15]}\" =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[16]}\" =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[17]}\" =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[18]}\" =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: %s <local@example.test>\\\\n\" \"${_global_name}\")\n}\n\n@test \"'init --name <name>' sets the local name.\" {\n  run \"${_NB}\" init               \\\n    --name \"Example Local Name\"   \\\n    <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 19  ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(\n    git -C \"${NB_DIR}/home\" config --global user.email \\\n      || git config user.email\n  )\"\n\n  declare _global_name=\n  _global_name=\"$(\n    git -C \"${NB_DIR}/home\" config --global user.name \\\n      || git config user.name\n  )\"\n\n  [[ \"${lines[8]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[12]}\" =~ Update:                                                ]]\n  [[ \"${lines[13]}\" =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[14]}\" =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[15]}\" =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[16]}\" =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[17]}\" =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[18]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <%s>\\\\n\" \"${_global_email}\")\n}\n\n# `init` ######################################################################\n\n@test \"'init' exits with status 0.\" {\n  run \"${_NB}\" init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n}\n\n@test \"'init' exits with status 1 when '\\$NB_DIR' exists as a file.\" {\n  {\n    touch \"${NB_DIR}\"\n\n    [[ -e \"${NB_DIR}\" ]]\n  }\n\n  run \"${_NB}\" init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 1 ]]\n}\n\n@test \"'init' exits with status 1 a prints error output when '\\$NB_NOTEBOOK_PATH' / '\\$NB_DIR/home' exists.\" {\n  {\n    mkdir -p \"${NB_DIR}/home\"\n\n    [[ -e \"${NB_DIR}/home\" ]]\n  }\n\n  run \"${_NB}\" init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 1 ]]\n\n  [[ \"${lines[0]}\" =~  \\!.*nb.*already\\ initialized.\\ To\\ initialize\\ a\\ local\\ notebook,\\ use: ]]\n  [[ \"${lines[1]}\" =~  nb\\ notebooks\\ init  ]]\n  [[ \"${lines[2]}\" =~  More\\ Information:   ]]\n  [[ \"${lines[3]}\" =~  nb\\ help\\ notebooks  ]]\n}\n\n@test \"'init' creates '\\$NB_DIR' and '\\$NB_NOTEBOOK_PATH' / '\\$NB_DIR/home' directories.\" {\n  run \"${_NB}\" init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ -d \"${NB_DIR}\"       ]]\n  [[ -d \"${NB_DIR}/home\"  ]]\n}\n\n@test \"'init' creates a git directory in '\\$NB_NOTEBOOK_PATH' / '\\$NB_DIR/home'.\" {\n  run \"${_NB}\" init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ -d \"${NB_DIR}/home/.git\" ]]\n}\n\n@test \"'init' creates an .index '\\$NB_NOTEBOOK_PATH' / '\\$NB_DIR/home'.\" {\n  run \"${_NB}\" init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ -e \"${NB_DIR}/home/.index\" ]]\n}\n\n@test \"'init' exits with status 0 when '\\$NBRC_PATH' exists.\" {\n  {\n    touch \"${NBRC_PATH}\"\n\n    [[ -e \"${NBRC_PATH}\" ]]\n  }\n\n  run \"${_NB}\" init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n}\n\n@test \"'init' creates a .nbrc file at '\\$NBRC_PATH'.\" {\n  {\n    [[ ! -e \"${NBRC_PATH}\" ]]\n  }\n\n  run \"${_NB}\" init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"%s\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[ -e \"${NBRC_PATH}\" ]]\n\n  grep -q \"Configuration file for \\`nb\\`\"  \"${NBRC_PATH}\"\n  grep -q \"NB_ENCRYPTION_TOOL\"             \"${NBRC_PATH}\"\n}\n\n@test \"'init' creates git commit.\" {\n  run \"${_NB}\" init\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Initialize'\n}\n\n# help ########################################################################\n\n@test \"'help init' exits with status 0.\" {\n  run \"${_NB}\" help init\n\n  [[ \"${status}\" -eq 0 ]]\n}\n\n@test \"'help init' prints help information.\" {\n  run \"${_NB}\" help init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Usage.*:      ]]\n  [[ \"${lines[1]}\" =~ \\ \\ nb\\ init  ]]\n}\n"
  },
  {
    "path": "test/list-pagination.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --per-page <lmit> ###########################################################\n\n@test \"'list --per-page <limit> [--page <number>]' paginates list.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n  }\n\n  # --per-page 3, first page\n\n  run \"${_NB}\" list --per-page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 4                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  7\\ omitted.\\ 10\\ total.   ]]\n\n  run \"${_NB}\" list --per-page 3 --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" list --per-page 3 --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  # --per-page 3 --page 2+\n\n  run \"${_NB}\" list --per-page 3 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" list --per-page 3 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" list --per-page 3 --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  # --per-page 5\n\n  run \"${_NB}\" list --per-page 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 6                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[5]}\"  =~  5\\ omitted.\\ 10\\ total.   ]]\n\n  run \"${_NB}\" list --per-page 5 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" list --per-page 5 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n# --<limit> ###################################################################\n\n@test \"'list --<limit> [--page <number>]' paginates list.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n  }\n\n  # --3, first page\n\n  run \"${_NB}\" list --3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 4                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  7\\ omitted.\\ 10\\ total.   ]]\n\n  run \"${_NB}\" list --3 --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" list --3 --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  # --3 --page 2+\n\n  run \"${_NB}\" list --3 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" list --3 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" list --3 --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  # --5\n\n  run \"${_NB}\" list --5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 6                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[5]}\"  =~  5\\ omitted.\\ 10\\ total.   ]]\n\n  run \"${_NB}\" list --5 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" list --5 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n# -p / --page #################################################################\n\n@test \"'list -p <number>' paginates list using value from \\$NB_LIMIT.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set limit 3\n  }\n\n  run \"${_NB}\" list -p 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" list -p 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" list -p 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" list -p 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" list -p 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" list -p 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n\n  {\n    \"${_NB}\" set limit 5\n  }\n\n  run \"${_NB}\" list -p 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" list -p 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" list -p 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" list -p 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n@test \"'list --page <number>' paginates list using value from \\$NB_LIMIT.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set limit 3\n  }\n\n  run \"${_NB}\" list --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" list --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" list --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" list --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" list --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" list --page 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n\n  {\n    \"${_NB}\" set limit 5\n  }\n\n  run \"${_NB}\" list --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" list --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" list --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" list --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n# --limit ##################################################################\n\n@test \"'list --limit <limit> [--page <number>]' paginates list.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n  }\n\n  # --limit 3, first page\n\n  run \"${_NB}\" list --limit 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 4                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  7\\ omitted.\\ 10\\ total.   ]]\n\n  run \"${_NB}\" list --limit 3 --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" list --limit 3 --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  # --limit 3 --page 2+\n\n  run \"${_NB}\" list --limit 3 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" list --limit 3 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" list --limit 3 --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  # --limit 5\n\n  run \"${_NB}\" list --limit 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 6                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[5]}\"  =~  5\\ omitted.\\ 10\\ total.   ]]\n\n  run \"${_NB}\" list --limit 5 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" list --limit 5 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n"
  },
  {
    "path": "test/list.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# folders first ###############################################################\n\n@test \"'list --folders-first' prints folders first while preserving pinning.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" folder add \"Folder One\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" folder add \"Folder Two\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Example content four.\"\n    \"${_NB}\" folder add \"Folder Three\"\n\n    \"${_NB}\" pin \"Folder Two\"\n    \"${_NB}\" pin \"File Three.md\"\n  }\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 7 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📌\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ 📌\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*7.*].*\\ 📂\\ Folder\\ Three                                      ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*6.*].*\\ File\\ Four\\.md\\ \\·\\ \\\"Example\\ content\\ four\\.\\\"       ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"         ]]\n  [[ \"${lines[5]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                        ]]\n  [[ \"${lines[6]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"         ]]\n\n  run \"${_NB}\" list --folders-first --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 7 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📌\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ 📌\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*7.*].*\\ 📂\\ Folder\\ Three                                      ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                        ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*6.*].*\\ File\\ Four\\.md\\ \\·\\ \\\"Example\\ content\\ four\\.\\\"       ]]\n  [[ \"${lines[5]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"         ]]\n\n  [[ \"${lines[6]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"         ]]\n}\n\n@test \"'list --folders-first' prints folders first.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" folder add \"Folder One\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" folder add \"Folder Two\"\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n\n  run \"${_NB}\" list --folders-first\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n}\n\n@test \"'list --ff' prints folders first.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" folder add \"Folder One\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" folder add \"Folder Two\"\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n\n  run \"${_NB}\" list --ff\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n}\n\n@test \"'NB_FOLDERS_FIRST=1 list' has no effect.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" folder add \"Folder One\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" folder add \"Folder Two\"\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n\n  NB_FOLDERS_FIRST=1 run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n}\n\n# filename handling ###########################################################\n\n@test \"'list' prints normally with uncommon filenames.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File [] One.md\"   --title \"Title One\"\n    \"${_NB}\" add \"File [Two].md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File [ Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File ] Four.md\"   --title \"Title Four\"\n    \"${_NB}\" add \"File () Five.md\"  --title \"Title Five\"\n    \"${_NB}\" add \"File (Six).md\"    --title \"Title Six\"\n    \"${_NB}\" add \"File ( Seven.md\"  --title \"Title Seven\"\n    \"${_NB}\" add \"File ) Eight.md\"  --title \"Title Eight\"\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 8                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*8.*].*\\ Title\\ Eight  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*7.*].*\\ Title\\ Seven  ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*6.*].*\\ Title\\ Six    ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*5.*].*\\ Title\\ Five   ]]\n  [[ \"${lines[4]}\"  =~  \\.*[.*4.*].*\\ Title\\ Four   ]]\n  [[ \"${lines[5]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[6]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[7]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n}\n\n# temporary files #############################################################\n\n@test \"'list' ignores common temporary files.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"File Two.md\" --content \"Example content two.\"\n\n    \"${_NB}\" run touch \"Example Temp One.md~\"\n    \"${_NB}\" run touch \"#Example Temp Two.md#\"\n    \"${_NB}\" run touch \"Example Temp Three.md.swp\"\n    \"${_NB}\" run touch \"Example Temp Four.md.swap\"\n    \"${_NB}\" run touch \".#Example Temp Five.md\"\n    \"${_NB}\" run touch \"Example Temp Six_ltex.json\"\n\n    \"${_NB}\" add \"File Three.md\" --content \"Example content three.\"\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 3 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*2.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n}\n\n# list content (title, filename, first line) ##################################\n\n@test \"'list' includes titles when present, otherwise filenames with first lines.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"$(cat <<HEREDOC\n# Example Title One\n\nExample first line one.\n\nExample second line one.\nHEREDOC\n)\"\n    \"${_NB}\" add \"File Two.md\"    --content \"$(cat <<HEREDOC\nExample first line two.\n\nExample second line two.\nHEREDOC\n)\"\n    \"${_NB}\" add \"File Three.md\"  --content \"$(cat <<HEREDOC\n${_BT}${_BT}${_BT}html\n# Example Code Block Title Three\n${_BT}${_BT}${_BT}\n\nExample first line three.\n\nExample second line three.\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*\\[.*3.*\\].*\\ File\\ Three\\.md\\ ·\\ \\\"Example\\ first\\ line\\ three\\.\\\"  ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*\\[.*2.*\\].*\\ File\\ Two\\.md\\ ·\\ \\\"Example\\ first\\ line\\ two\\.\\\"      ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Example\\ \\Title\\ One                                   ]]\n}\n\n# notebook: selectors #########################################################\n\n@test \"'list --notebook-selectors' includes notebook selectors when listing the root level of the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list --notebook-selectors\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${lines[0]}\"  =~  .*\\[.*home:3.*\\].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  .*\\[.*home:2.*\\].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  .*\\[.*home:1.*\\].*\\ Title\\ One    ]]\n}\n\n@test \"'list --notebook-selectors' includes notebook selectors when listing a nested folder in the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list Example\\ Folder/ --notebook-selectors\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  .*\\[.*Example\\ Folder/3.*\\].*\\ Title\\ Three ]]\n  [[ \"${lines[1]}\"  =~  .*\\[.*Example\\ Folder/2.*\\].*\\ Title\\ Two   ]]\n  [[ \"${lines[2]}\"  =~  .*\\[.*Example\\ Folder/1.*\\].*\\ Title\\ One   ]]\n}\n\n@test \"'list --notebook-selectors' includes notebook selectors when listing root level of a selected notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Notebook:File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Notebook:File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list Example\\ Notebook: --notebook-selectors\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  .*\\[.*Example\\ Notebook:3.*\\].*\\ Title\\ Three ]]\n  [[ \"${lines[1]}\"  =~  .*\\[.*Example\\ Notebook:2.*\\].*\\ Title\\ Two   ]]\n  [[ \"${lines[2]}\"  =~  .*\\[.*Example\\ Notebook:1.*\\].*\\ Title\\ One   ]]\n}\n\n@test \"'list --notebook-selectors' includes notebook selectors when listing a nested folder of a selected notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Sample Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list Example\\ Notebook:Sample\\ Folder/ --notebook-selectors\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Sample\\ Folder/3.*\\].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Sample\\ Folder/2.*\\].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Sample\\ Folder/1.*\\].*\\ Title\\ One    ]]\n}\n\n@test \"'list' does not use notebook selectors when listing the root level of the current notebook by default.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n\n  [[ \"${lines[0]}\"  =~  .*\\[.*3.*\\].*\\ Title\\ Three ]]\n  [[ \"${lines[1]}\"  =~  .*\\[.*2.*\\].*\\ Title\\ Two   ]]\n  [[ \"${lines[2]}\"  =~  .*\\[.*1.*\\].*\\ Title\\ One   ]]\n}\n\n@test \"'list' does not use notebook selectors when listing a nested folder in the current notebook by default.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  .*\\[.*Example\\ Folder/3.*\\].*\\ Title\\ Three ]]\n  [[ \"${lines[1]}\"  =~  .*\\[.*Example\\ Folder/2.*\\].*\\ Title\\ Two   ]]\n  [[ \"${lines[2]}\"  =~  .*\\[.*Example\\ Folder/1.*\\].*\\ Title\\ One   ]]\n}\n\n@test \"'list' includes notebook selectors when listing root level of a selected notebook by default.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Notebook:File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Notebook:File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list Example\\ Notebook:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  .*\\[.*Example\\ Notebook:3.*\\].*\\ Title\\ Three ]]\n  [[ \"${lines[1]}\"  =~  .*\\[.*Example\\ Notebook:2.*\\].*\\ Title\\ Two   ]]\n  [[ \"${lines[2]}\"  =~  .*\\[.*Example\\ Notebook:1.*\\].*\\ Title\\ One   ]]\n}\n\n@test \"'list' includes notebook selectors when listing a nested folder of a selected notebook by default.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Sample Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list Example\\ Notebook:Sample\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Sample\\ Folder/3.*\\].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Sample\\ Folder/2.*\\].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Sample\\ Folder/1.*\\].*\\ Title\\ One    ]]\n}\n\n# .index ######################################################################\n\n@test \"'list' reconciles ancestor .index files with incomplete nested .index file.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${NB_DIR}/home/Example/Sample/Demo\"\n\n    printf \"# Title\" > \"${NB_DIR}/home/Example/Sample/Demo/File.md\"\n\n    touch \"${NB_DIR}/home/Example/Sample/Demo/.index\"\n\n    git -C \"${NB_DIR}/home\" add --all\n    git -C \"${NB_DIR}/home\" commit -am \"Example commit message.\"\n\n    [[ !  -e \"${NB_DIR}/home/Example/.index\"              ]]\n    [[ !  -e \"${NB_DIR}/home/Example/Sample/.index\"       ]]\n    [[    -e \"${NB_DIR}/home/Example/Sample/Demo/.index\"  ]]\n    [[    -e \"${NB_DIR}/home/Example/Sample/Demo/File.md\" ]]\n\n    git -C \"${NB_DIR}/home\" status\n\n    [[ -z \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  }\n\n  run \"${_NB}\" list \"Example/Sample/Demo/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                       ]]\n  [[ \"${#lines[@]}\" -eq 1                                       ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example/Sample/Demo/1.*].*\\ Title ]]\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example/.index\")              \\\n    <(printf \"Sample\\\\n\")\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example/Sample/.index\")       \\\n    <(printf \"Demo\\\\n\")\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example/Sample/Demo/.index\")  \\\n    <(printf \"File.md\\\\n\")\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  git -C \"${NB_DIR}/home\" status\n  git -C \"${NB_DIR}/home\" log\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Reconcile Index'\n}\n\n@test \"'list' reconciles ancestor .index files with missing nested .index file.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${NB_DIR}/home/Example/Sample/Demo\"\n\n    printf \"# Title\" > \"${NB_DIR}/home/Example/Sample/Demo/File.md\"\n\n    git -C \"${NB_DIR}/home\" add --all\n    git -C \"${NB_DIR}/home\" commit -am \"Example commit message.\"\n\n    [[ !  -e \"${NB_DIR}/home/Example/.index\"              ]]\n    [[ !  -e \"${NB_DIR}/home/Example/Sample/.index\"       ]]\n    [[ !  -e \"${NB_DIR}/home/Example/Sample/Demo/.index\"  ]]\n    [[    -e \"${NB_DIR}/home/Example/Sample/Demo/File.md\" ]]\n\n    git -C \"${NB_DIR}/home\" status\n\n    [[ -z \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  }\n\n  run \"${_NB}\" list \"Example/Sample/Demo/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                       ]]\n  [[ \"${#lines[@]}\" -eq 1                                       ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example/Sample/Demo/1.*].*\\ Title ]]\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example/.index\")              \\\n    <(printf \"Sample\\\\n\")\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example/Sample/.index\")       \\\n    <(printf \"Demo\\\\n\")\n\n  diff                                                  \\\n    <(cat \"${NB_DIR}/home/Example/Sample/Demo/.index\")  \\\n    <(printf \"File.md\\\\n\")\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  git -C \"${NB_DIR}/home\" status\n  git -C \"${NB_DIR}/home\" log\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Reconcile Index'\n}\n\n@test \"'list' reconciles root-level .index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    printf \"# Title Four\" > \"${NB_DIR}/home/File Four.md\"\n\n    \"${_NB}\" git -C \"${NB_DIR}/home\" add --all\n    \"${_NB}\" git -C \"${NB_DIR}/home\" commit -am \"Example commit message.\"\n\n    git -C \"${NB_DIR}/home\" status\n\n    [[ -z \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n\n    diff                              \\\n      <(cat \"${NB_DIR}/home/.index\")  \\\n      <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nHEREDOC\n)\n\n    [[  -e \"${NB_DIR}/home/File One.md\"    ]]\n    [[  -e \"${NB_DIR}/home/File Two.md\"    ]]\n    [[  -e \"${NB_DIR}/home/File Three.md\"  ]]\n    [[  -e \"${NB_DIR}/home/File Four.md\"   ]]\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 4                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*4.*].*\\ Title\\ Four   ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n\n  diff                              \\\n    <(cat \"${NB_DIR}/home/.index\")  \\\n    <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nFile Four.md\nHEREDOC\n)\n\n  git -C \"${NB_DIR}/home\" log\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Reconcile Index'\n}\n\n@test \"'list' reconciles nested .index.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    printf \"# Title Four\" > \"${NB_DIR}/home/Example Folder/File Four.md\"\n\n    diff                                            \\\n      <(cat \"${NB_DIR}/home/Example Folder/.index\") \\\n      <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nHEREDOC\n)\n\n    [[  -e \"${NB_DIR}/home/Example Folder/File One.md\"    ]]\n    [[  -e \"${NB_DIR}/home/Example Folder/File Two.md\"    ]]\n    [[  -e \"${NB_DIR}/home/Example Folder/File Three.md\"  ]]\n    [[  -e \"${NB_DIR}/home/Example Folder/File Four.md\"   ]]\n  }\n\n  run \"${_NB}\" list Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n  [[ \"${#lines[@]}\" -eq 4                                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Folder/4.*].*\\ Title\\ Four     ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Folder/3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ Title\\ One      ]]\n\n  diff                                            \\\n    <(cat \"${NB_DIR}/home/Example Folder/.index\") \\\n    <(cat <<HEREDOC\nFile One.md\nFile Two.md\nFile Three.md\nFile Four.md\nHEREDOC\n)\n\n  git -C \"${NB_DIR}/home\" log\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Reconcile Index'\n}\n\n# pinning #####################################################################\n\n@test \"'list --with-pinned' reconciles .pindex when file is deleted and deletes .pindex when empty.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"Example Folder/File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin Example\\ Folder/3\n\n    diff                                          \\\n      <(printf \"File Three.md\\\\n\")                \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n\n    rm \"${NB_DIR}/home/Example Folder/File Three.md\"\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/File Three.md\" ]]\n\n    diff                                          \\\n      <(printf \"File Three.md\\\\n\")                \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n  [[ \"${#lines[@]}\" -eq 3                                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Folder/4.*].*\\ Title\\ Four     ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ Title\\ One      ]]\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/.pindex\"                     ]]\n}\n\n@test \"'list --with-pinned' reconciles .pindex when folder is deleted.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"   --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"   --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/Folder Three\"  --type  folder\n    \"${_NB}\" add \"Example Folder/File Four.md\"  --title \"Title Four\"\n\n    \"${_NB}\" pin Example\\ Folder/1\n    \"${_NB}\" pin Example\\ Folder/3\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFolder Three\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n\n    rm -r \"${NB_DIR}/home/Example Folder/Folder Three\"\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Folder Three\" ]]\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFolder Three\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n  [[ \"${#lines[@]}\" -eq 3                                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Folder/4.*].*\\ Title\\ Four     ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n\n  diff                                            \\\n    <(printf \"File One.md\\\\n\")                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n}\n\n@test \"'list --with-pinned' reconciles .pindex when file is deleted.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"Example Folder/File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin Example\\ Folder/1\n    \"${_NB}\" pin Example\\ Folder/3\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Three.md\\\\n\")  \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n\n    rm \"${NB_DIR}/home/Example Folder/File Three.md\"\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/File Three.md\" ]]\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Three.md\\\\n\")  \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n  [[ \"${#lines[@]}\" -eq 3                                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Folder/4.*].*\\ Title\\ Four     ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n\n  diff                                            \\\n    <(printf \"File One.md\\\\n\")  \\\n    <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n}\n\n@test \"'list --with-pinned' prints list with items pinned.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"   --content \"#pinned\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin 1\n    \"${_NB}\" pin 4\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Four.md\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 4                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*4.*].*\\ 📌\\ Title\\ Four ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n}\n\n# `list` edge cases ###########################################################\n\n@test \"'list' ignores --ar, --archived, --unar, and --unarchived options.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list --ar\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 3             ]]\n  [[ \"${lines[0]}\"  =~  Title\\ Three  ]]\n\n  run \"${_NB}\" list --archived\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 3             ]]\n  [[ \"${lines[0]}\"  =~  Title\\ Three  ]]\n\n  run \"${_NB}\" list --unar\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 3             ]]\n  [[ \"${lines[0]}\"  =~  Title\\ Three  ]]\n\n  run \"${_NB}\" list --unarchived\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 3             ]]\n  [[ \"${lines[0]}\"  =~  Title\\ Three  ]]\n}\n\n@test \"'list <id> <no-match>' exits with 0 and lists matching file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list not-valid 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${lines[0]}\"  =~  Title\\ One    ]]\n\n  run \"${_NB}\" list 2 -x\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${lines[0]}\"  =~  Title\\ Two    ]]\n\n  run \"${_NB}\" list 3 non-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${lines[0]}\"  =~  Title\\ Three  ]]\n}\n\n# `list` not found message ####################################################\n\n@test \"'list <no-match>' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                       ]]\n  [[ \"${#lines[@]}\" -eq 1                       ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found:\\ .*no-match ]]\n}\n\n@test \"'list <not-valid> <no-match>' exits with 1 and prints message with both.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list not-valid no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                 ]]\n  [[ \"${#lines[@]}\" -eq 1                                 ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found:\\ .*not-valid|no-match ]]\n}\n\n@test \"'list <not-valid-selector> <no-match>' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list 123:x\\ y\\ z/not-valid.md no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                                ]]\n  [[    \"${#lines[@]}\" -eq 1                                                ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*123:x\\ y\\ z/not-valid.md|no-match ]]\n}\n\n@test \"'list <not-valid-selector> <match>' exits with 0 and prints match.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list 123:x\\ y\\ z/not-valid.md three\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0            ]]\n  [[    \"${#lines[@]}\" -eq 1            ]]\n  [[    \"${lines[0]}\"  =~  Title\\ Three ]]\n}\n\n@test \"'list <folder>/ <no-match>' (slash) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list Example\\ Folder/ no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                              ]]\n  [[    \"${#lines[@]}\" -eq 1                                              ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*Example\\ Folder/.*\\ .*no-match  ]]\n}\n\n@test \"'list <folder> <no-match>' (no slash) exits with 0 and lists folder match.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n  }\n\n  run \"${_NB}\" list Example\\ Folder no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                          ]]\n  [[    \"${#lines[@]}\" -eq 1                          ]]\n  [[    \"${lines[0]}\"  =~  1.*\\ 📂\\ .*Example\\ Folder ]]\n}\n\n@test \"'list <notebook>:<no-match>' (no space) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" list home:no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                              ]]\n  [[    \"${#lines[@]}\" -eq 1                                              ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*home:.*\\ .*no-match  ]]\n}\n\n@test \"'list <notebook>: <no-match>' (space) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" list home: no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                              ]]\n  [[    \"${#lines[@]}\" -eq 1                                              ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*home:.*\\ .*no-match  ]]\n}\n\n@test \"'list <notebook>:<not-valid-path> <match>' exits with 0 and lists match.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Root File One.md\"    --title \"Root Title One\"\n    \"${_NB}\" add \"Root File Two.md\"    --title \"Root Title Two\"\n    \"${_NB}\" add \"Root File Three.md\"  --title \"Root Title Three\"\n\n    \"${_NB}\" add \"Example Folder/Nested File One.md\"    --title \"Nested Title One\"\n    \"${_NB}\" add \"Example Folder/Nested File Two.md\"    --title \"Nested Title Two\"\n    \"${_NB}\" add \"Example Folder/Nested File Three.md\"  --title \"Nested Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" list home:Not Valid/not-valid.md three\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                    ]]\n  [[    \"${#lines[@]}\" -eq 1                    ]]\n  [[    \"${lines[0]}\"  =~  Root\\ Title\\ Three   ]]\n}\n\n@test \"'list <notebook>:<folder>/<not-valid-item> <match>' exits with 0 and lists nested match.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Root File One.md\"    --title \"Root Title One\"\n    \"${_NB}\" add \"Root File Two.md\"    --title \"Root Title Two\"\n    \"${_NB}\" add \"Root File Three.md\"  --title \"Root Title Three\"\n\n    \"${_NB}\" add \"Example Folder/Nested File One.md\"    --title \"Nested Title One\"\n    \"${_NB}\" add \"Example Folder/Nested File Two.md\"    --title \"Nested Title Two\"\n    \"${_NB}\" add \"Example Folder/Nested File Three.md\"  --title \"Nested Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" list home:Example\\ Folder/not-valid.md three\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                    ]]\n  [[    \"${#lines[@]}\" -eq 1                    ]]\n  [[    \"${lines[0]}\"  =~  Nested\\ Title\\ Three ]]\n}\n\n@test \"'list <notebook>:<folder>/<no-match>' (slash, no space) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" list home:Example\\ Folder/no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                                    ]]\n  [[    \"${#lines[@]}\" -eq 1                                                    ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*home:.*Example\\ Folder/.*\\ .*no-match ]]\n}\n\n@test \"'list <notebook>:<folder>/ <no-match>' (slash, space) exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" list home:Example\\ Folder/ no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                                                    ]]\n  [[    \"${#lines[@]}\" -eq 1                                                    ]]\n  [[    \"${lines[0]}\"  =~  Not\\ found:\\ .*home:.*Example\\ Folder/.*\\ .*no-match ]]\n}\n\n@test \"'list <notebook>:<folder> <no-match>' (no slash) exits with 0 and lists folder match.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" list home:Example\\ Folder no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                          ]]\n  [[    \"${#lines[@]}\" -eq 1                          ]]\n  [[    \"${lines[0]}\"  =~  1.*\\ 📂\\ .*Example\\ Folder ]]\n}\n\n# `list` (empty) ##############################################################\n\n@test \"'list' (empty) exits with 0 and lists files.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"0 items.\n\nAdd a note:\n  $(_color_primary 'nb add')\nAdd a bookmark:\n  $(_color_primary \"nb <url>\")\nAdd a todo:\n  $(_color_primary \"nb todo add <title>\")\nImport a file:\n  $(_color_primary \"nb import (<path> | <url>)\")\nHelp information:\n  $(_color_primary 'nb help')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n# `list` ######################################################################\n\n@test \"'list' exits with 0 and lists files in reverse order.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"one.md\"   --title \"one\"\n    \"${_NB}\" add \"two.md\"   --title \"two\"\n    \"${_NB}\" add \"three.md\" --title \"three\"\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${lines[0]}\"  =~  three ]]\n  [[ \"${lines[1]}\"  =~  two   ]]\n  [[ \"${lines[2]}\"  =~  one   ]]\n}\n\n@test \"'list' includes indicators.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"one.bookmark.md\"      \\\n      --content \"<https://example.com>\"\n\n    \"${_NB}\" add \"two.md\"               \\\n      --content \"Example Content.\"\n\n    \"${_NB}\" add \"three.md\"             \\\n      --title \"Three\" --encrypt --password=example\n\n    \"${_NB}\" add \"four.todo.md\"         \\\n      --content \"# [ ] Example undone todo.\"\n\n    \"${_NB}\" add \"Five.todo.md\"         \\\n      --content \"# [x] Example done todo.\"\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\[.*5.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ done\\ todo\\. ]]\n  [[ \"${lines[1]}\"  =~  \\[.*4.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ undone\\ todo\\.  ]]\n  [[ \"${lines[2]}\"  =~  \\[.*3.*\\].*\\ 🔒\\ three.md.enc                         ]]\n  [[ \"${lines[3]}\"  =~  \\[.*2.*\\].*\\ two.md                                   ]]\n  [[ \"${lines[4]}\"  =~  \\[.*1.*\\].*\\ 🔖\\ one.bookmark.md                      ]]\n\n  run \"${_NB}\" list --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\[5\\]\\ ✅\\ \\[x\\]\\ Example\\ done\\ todo\\.     ]]\n  [[ \"${lines[1]}\"  =~  \\[4\\]\\ ✔️\\ \\ \\[\\ \\]\\ Example\\ undone\\ todo\\.  ]]\n  [[ \"${lines[2]}\"  =~  \\[3\\]\\ 🔒\\ three.md.enc                     ]]\n  [[ \"${lines[3]}\"  =~  \\[2\\]\\ two.md                               ]]\n  [[ \"${lines[4]}\"  =~  \\[1\\]\\ 🔖\\ one.bookmark.md                  ]]\n}\n\n@test \"'list' indicators are configurable with environment variables.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"one.bookmark.md\" --content \"<https://example.com>\"\n    \"${_NB}\" add \"two.md\" --content \"Example Content.\"\n    \"${_NB}\" add \"three.md\" --title \"Three\" --encrypt --password=example\n  }\n\n  NB_INDICATOR_ENCRYPTED=🔐 NB_INDICATOR_BOOKMARK=🏷 run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${lines[0]}\"  =~  \\[.*3.*\\].*\\ 🔐\\ three.md.enc     ]]\n  [[ \"${lines[1]}\"  =~  \\[.*2.*\\].*\\ two.md               ]]\n  [[ \"${lines[2]}\"  =~  \\[.*1.*\\].*\\ 🏷\\ one.bookmark.md  ]]\n\n  NB_INDICATOR_ENCRYPTED=🔐 NB_INDICATOR_BOOKMARK=🏷 run \"${_NB}\" list --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${lines[0]}\"  =~  \\[3\\]\\ 🔐\\ three.md.enc           ]]\n  [[ \"${lines[1]}\"  =~  \\[2\\]\\ two.md                     ]]\n  [[ \"${lines[2]}\"  =~  \\[1\\]\\ 🏷\\ one.bookmark.md        ]]\n}\n\n@test \"'list' indicator padding is hidden when indicator icons are set to blank.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"one.bookmark.md\" --content \"<https://example.com>\"\n    \"${_NB}\" add \"two.md\" --content \"Example Content.\"\n    \"${_NB}\" add \"three.md\" --title \"Three\" --encrypt --password=example\n  }\n\n  NB_INDICATOR_ENCRYPTED=\"\" NB_INDICATOR_BOOKMARK=\"\" run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${lines[0]}\"  =~  \\[.*3.*\\].*\\ three.md.enc         ]]\n  [[ \"${lines[1]}\"  =~  \\[.*2.*\\].*\\ two.md               ]]\n  [[ \"${lines[2]}\"  =~  \\[.*1.*\\].*\\ one.bookmark.md      ]]\n\n  NB_INDICATOR_ENCRYPTED=\"\" NB_INDICATOR_BOOKMARK=\"\" run \"${_NB}\" list --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${lines[0]}\"  =~  \\[3\\]\\ three.md.enc               ]]\n  [[ \"${lines[1]}\"  =~  \\[2\\]\\ two.md                     ]]\n  [[ \"${lines[2]}\"  =~  \\[1\\]\\ one.bookmark.md            ]]\n}\n\n@test \"'list' includes ids.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"one.md\"   --title \"one\"\n    \"${_NB}\" add \"two.md\"   --title \"two\"\n    \"${_NB}\" add \"three.md\" --title \"three\"\n    \"${_NB}\" add \"four.md\"  --title \"four\"\n    \"${_NB}\" add \"five.md\"  --title \"five\"\n\n    \"${_NB}\" delete \"one.md\"  --force\n    \"${_NB}\" delete \"four.md\" --force\n  }\n\n  run \"${_NB}\" list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0     ]]\n\n  [[    \"${lines[0]}\"   =~ five   ]]\n  [[    \"${lines[0]}\"   =~ 5      ]]\n  [[    \"${lines[1]}\"   =~ three  ]]\n  [[    \"${lines[1]}\"   =~ 3      ]]\n  [[    \"${lines[2]}\"   =~ two    ]]\n  [[    \"${lines[2]}\"   =~ 2      ]]\n  [[ -z \"${lines[3]:-}\"           ]]\n}\n\n# `list --no-id` ##############################################################\n\n@test \"'list --no-id' exits with 0 and lists files in reverse order.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"one.md\"   --title \"one\"\n    \"${_NB}\" add \"two.md\"   --title \"two\"\n    \"${_NB}\" add \"three.md\" --title \"three\"\n  }\n\n  run \"${_NB}\" list --no-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${lines[0]}\"  =~  three ]]\n  [[ \"${lines[1]}\"  =~  two   ]]\n  [[ \"${lines[2]}\"  =~  one   ]]\n}\n\n# `list --no-color` ###########################################################\n\n@test \"'list --no-color' exits with 0 and lists files in reverse order.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"one.md\"   --title \"one\"\n    \"${_NB}\" add \"two.md\"   --title \"two\"\n    \"${_NB}\" add \"three.md\" --title \"three\"\n  }\n\n  run \"${_NB}\" list --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n  [[ \"${lines[0]}\"  =~  three ]]\n  [[ \"${lines[1]}\"  =~  two   ]]\n  [[ \"${lines[2]}\"  =~  one   ]]\n}\n\n# `list (-e | --excerpt)` #####################################################\n\n_setup_list_excerpt() {\n  \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"one.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"two.md\"\n# two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"three.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n}\n\n@test \"'list -e' with todos prints line matching visible listing length.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" todos add \"Example todo one.\"\n    \"${_NB}\" todos add \"Example todo two.\"\n\n    \"${_NB}\" \"do\" 2\n  }\n\n  run \"${_NB}\" list -e\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${lines[2]}:   '%s'\\\\n\" \"${lines[2]}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 6 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*2.*].*\\ ✅\\ .*[.*x.*].*\\ Example\\ todo\\ two\\.  ]]\n  [[ \"${lines[1]}\"  =~  \\\n[^-]----------------------------[^-]                ]]\n\n\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*1.*].*\\ ✔️\\ \\ .*[\\ ].*\\ Example\\ todo\\ one\\.    ]]\n  [[ \"${lines[4]}\"  =~  \\\n[^-]----------------------------[^-]                ]]\n}\n\n@test \"'list -e' exits with 0 and displays 5 line list items.\" {\n  {\n    _setup_list_excerpt\n  }\n\n  run \"${_NB}\" list -e\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 15  ]]\n}\n\n@test \"'list -e 2' exits with 0 and displays 4 line list items.\" {\n  {\n    _setup_list_excerpt\n  }\n\n  run \"${_NB}\" list -e 2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n}\n\n@test \"'list -e 0' exits with 0 and displays 1 line list items.\" {\n  {\n    _setup_list_excerpt\n  }\n\n  run \"${_NB}\" list -e 0\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                   ]]\n  [[ \"${#lines[@]}\" -eq 6                   ]]\n  [[ \"${lines[0]}\"  =~  .*[.*3.*].*\\ three  ]]\n  [[ \"${lines[1]}\"  =~   [^-]---------[^-]  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ two    ]]\n  [[ \"${lines[3]}\"  =~   [^-]-------[^-]    ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ one    ]]\n  [[ \"${lines[5]}\"  =~   [^-]-------[^-]    ]]\n}\n\n@test \"'list --excerpt' exits with 0 and displays 5 line list items.\" {\n  {\n    _setup_list_excerpt\n  }\n\n  run \"${_NB}\" list --excerpt\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 15  ]]\n}\n\n@test \"'list --excerpt 2' exits with 0 and displays 4 line list items.\" {\n  {\n    _setup_list_excerpt\n  }\n\n  run \"${_NB}\" list --excerpt 2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n}\n\n@test \"'list --excerpt 0' exits with 0 and displays list item with line.\" {\n  {\n    _setup_list_excerpt\n  }\n\n  run \"${_NB}\" list --excerpt 0\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                   ]]\n  [[ \"${#lines[@]}\" -eq 6                   ]]\n  [[ \"${lines[0]}\"  =~  .*[.*3.*].*\\ three  ]]\n  [[ \"${lines[1]}\"  =~   [^-]---------[^-]  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ two    ]]\n  [[ \"${lines[3]}\"  =~   [^-]-------[^-]    ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ one    ]]\n  [[ \"${lines[5]}\"  =~   [^-]-------[^-]    ]]\n}\n\n# `list -n <limit>` ###########################################################\n\n_setup_list_limit() {\n  \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"one.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"two.md\"\n# two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"three.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n}\n\n@test \"'list -n' exits with 0 and displays full list.\" {\n  {\n    _setup_list_limit\n  }\n\n  run \"${_NB}\" list -n\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 3 ]]\n}\n\n@test \"'list -n 2' exits with 0 and displays list with 2 items.\" {\n  {\n    _setup_list_limit\n  }\n\n  run \"${_NB}\" list -n 2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n  [[ \"${lines[2]}\"  =~  1\\ omitted\\.\\ 3\\ total\\.  ]]\n}\n\n@test \"'list --limit 2' exits with 0 and displays list with 2 items.\" {\n  {\n    _setup_list_limit\n  }\n\n  run \"${_NB}\" list --limit 2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n  [[ \"${lines[2]}\"  =~  1\\ omitted\\.\\ 3\\ total\\.  ]]\n}\n\n@test \"'list -<limit>' exits with 0 and displays list with 2 items.\" {\n  {\n    _setup_list_limit\n  }\n\n  run \"${_NB}\" list -2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n  [[ \"${lines[2]}\"  =~  1\\ omitted\\.\\ 3\\ total\\.  ]]\n}\n\n@test \"'list -<limit>' exits with 0 and displays list with 11 items.\" {\n  {\n    \"${_NB}\" init\n\n    declare _numbers=(\n      One Two Three Four Five Six Seven Eight Nine Ten\n      Eleven Twelve Thirteen Fourteen Fifteen Sixteen\n      Seventeen Eighteen Nineteen Twenty\n    )\n\n    declare __number=\n    for   __number in \"${_numbers[@]}\"\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n  }\n\n  run \"${_NB}\" list -13\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                               ]]\n  [[ \"${#lines[@]}\" -eq 14                              ]]\n  [[ \"${lines[12]}\"  =~  .*\\[.*8.*\\].*\\ \\ Title\\ Eight  ]]\n  [[ \"${lines[13]}\"  =~  7\\ omitted\\.\\ 20\\ total\\.      ]]\n}\n\n@test \"'list --<limit>' exits with 0 and displays list with 2 items.\" {\n  {\n    _setup_list_limit\n  }\n\n  run \"${_NB}\" list --2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n  [[ \"${lines[2]}\"  =~  1\\ omitted\\.\\ 3\\ total\\.  ]]\n}\n\n@test \"'list <query> --limit <limit>' exits with 0 and includes message when matches are greater than limit.\" {\n  {\n    \"${_NB}\" init\n      cat <<HEREDOC | \"${_NB}\" add \"one.md\"\n# Example One\nline two\nline three\nline four\nHEREDOC\n      cat <<HEREDOC | \"${_NB}\" add \"two.md\"\n# Example Two\nline two\nline three\nline four\nHEREDOC\n      cat <<HEREDOC | \"${_NB}\" add \"three.md\"\n# Example Three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list example --limit 2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n\n  [[    \"${#lines[@]}\"  -eq 3                               ]]\n  [[    \"${lines[0]}\"   =~  3.*Example\\ Three               ]]\n  [[    \"${lines[1]}\"   =~  2.*Example\\ Two                 ]]\n  [[    \"${lines[2]}\"   =~  1\\ match\\ omitted\\.\\ 3\\ total\\. ]]\n  [[ !  \"${output}\"     =~  1.*Example\\ Two                 ]]\n}\n\n@test \"'list <query> --limit <limit>' exits with 0 and does not include message when matches are below limit.\" {\n  {\n    \"${_NB}\" init\n      cat <<HEREDOC | \"${_NB}\" add \"one.md\"\n# Example One\nline two\nline three\nline four\nHEREDOC\n      cat <<HEREDOC | \"${_NB}\" add \"two.md\"\n# Example Two\nline two\nline three\nline four\nHEREDOC\n      cat <<HEREDOC | \"${_NB}\" add \"three.md\"\n# Example Three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list example --limit 10\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                 ]]\n\n  [[    \"${#lines[@]}\"  -eq 3                 ]]\n  [[    \"${lines[0]}\"   =~  3.*Example\\ Three ]]\n  [[    \"${lines[1]}\"   =~  2.*Example\\ Two   ]]\n  [[    \"${lines[2]}\"   =~  1.*Example\\ One   ]]\n  [[ !  \"${output}\"     =~  omitted           ]]\n}\n\n@test \"'list <query> --limit <limit>' exits with 0 and does not include message when matching one.\" {\n  {\n    \"${_NB}\" init\n      for __number in One Two Three Four Five Six Seven Eight Nine Ten Eleven\n      do\n        \"${_NB}\" add                          \\\n          --filename  \"File ${__number}.md\"   \\\n          --title     \"Example ${__number}\"   \\\n          --content   \"Content ${__number}.\"\n      done\n  }\n\n  run \"${_NB}\" list two --limit 10\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                 ]]\n\n  [[    \"${#lines[@]}\"  -eq 1                 ]]\n  [[    \"${lines[0]}\"   =~  2.*Example\\ Two   ]]\n\n  [[ !  \"${output}\"     =~  3.*Example\\ Three ]]\n  [[ !  \"${output}\"     =~  1.*Example\\ One   ]]\n  [[ !  \"${output}\"     =~  omitted           ]]\n}\n\n@test \"'list <id> --limit <limit>' exits with 0 and does not include message when matching one.\" {\n  {\n    \"${_NB}\" init\n      for __number in One Two Three Four Five Six Seven Eight Nine Ten Eleven\n      do\n        \"${_NB}\" add                          \\\n          --filename  \"File ${__number}.md\"   \\\n          --title     \"Example ${__number}\"   \\\n          --content   \"Content ${__number}.\"\n      done\n  }\n\n  run \"${_NB}\" list 2 --limit 10\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                 ]]\n\n  [[    \"${#lines[@]}\"  -eq 1                 ]]\n  [[    \"${lines[0]}\"   =~  2.*Example\\ Two   ]]\n\n  [[ !  \"${output}\"     =~  3.*Example\\ Three ]]\n  [[ !  \"${output}\"     =~  1.*Example\\ One   ]]\n  [[ !  \"${output}\"     =~  omitted           ]]\n}\n\n# `list --titles` #############################################################\n\n@test \"'list --titles' exits with 0 and displays a list of titles.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --titles\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${lines[0]}:   '%s'\\\\n\" \"${lines[0]}\"\n  printf \"\\${lines[1]}:   '%s'\\\\n\" \"${lines[1]}\"\n  printf \"\\${lines[2]}:   '%s'\\\\n\" \"${lines[2]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${lines[0]}\"  =~  3.*three      ]]\n  [[ \"${lines[1]}\"  =~  3.*second.md  ]]\n  [[ \"${lines[2]}\"  =~  3.*one        ]]\n}\n\n# `list --filenames` ##########################################################\n\n@test \"'list --filenames' exits with 0 and displays a list of filenames.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --filenames\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${lines[0]}\"  =~  3*third.md  ]]\n  [[ \"${lines[1]}\"  =~  2*second.md ]]\n  [[ \"${lines[2]}\"  =~  1*first.md  ]]\n}\n\n# `list --paths` ##############################################################\n\n@test \"'list --paths' exits with 0 and displays a list of paths.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --paths\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${NB_DIR}:     '%s'\\\\n\" \"${NB_DIR}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n\n  [[ \"${lines[0]}\"  =~  3*${NB_DIR}/home/third.md   ]]\n  [[ \"${lines[1]}\"  =~  2*${NB_DIR}/home/second.md  ]]\n  [[ \"${lines[2]}\"  =~  1*${NB_DIR}/home/first.md   ]]\n}\n\n# `ls -s` / `ls --sort` / `ls -r` / `ls --reverse` ############################\n\n@test \"'list --sort' sorts items.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first-home.md\"\n# title one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second-home.md\"\n# title two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third-example.md\"\n# title three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --sort\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -eq 3             ]]\n  [[ \"${lines[0]}\"  =~  title\\ one    ]]\n  [[ \"${lines[0]}\"  =~  [*1*]         ]]\n  [[ \"${lines[1]}\"  =~  title\\ two    ]]\n  [[ \"${lines[1]}\"  =~  [*2*]         ]]\n  [[ \"${lines[2]}\"  =~  title\\ three  ]]\n  [[ \"${lines[2]}\"  =~  [*3*]         ]]\n}\n\n@test \"'list --sort --reverse' reverse sorts items.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first-home.md\"\n# title one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second-home.md\"\n# title two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third-example.md\"\n# title three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --sort --reverse\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -eq 3             ]]\n  [[ \"${lines[0]}\"  =~  title\\ three  ]]\n  [[ \"${lines[0]}\"  =~  [*3*]         ]]\n  [[ \"${lines[1]}\"  =~  title\\ two    ]]\n  [[ \"${lines[1]}\"  =~  [*2*]         ]]\n  [[ \"${lines[2]}\"  =~  title\\ one    ]]\n  [[ \"${lines[2]}\"  =~  [*1*]         ]]\n\n}\n\n@test \"'list --sort' is not affected by NB_LIMIT.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first-home.md\"\n# title one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second-home.md\"\n# title two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third-example.md\"\n# title three\nline two\nline three\nline four\nHEREDOC\n\n    \"${_NB}\" set limit 2\n  }\n\n  run \"${_NB}\" list --sort\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -eq 3             ]]\n  [[ \"${lines[0]}\"  =~  title\\ one    ]]\n  [[ \"${lines[0]}\"  =~  [*1*]         ]]\n  [[ \"${lines[1]}\"  =~  title\\ two    ]]\n  [[ \"${lines[1]}\"  =~  [*2*]         ]]\n  [[ \"${lines[2]}\"  =~  title\\ three  ]]\n  [[ \"${lines[2]}\"  =~  [*3*]         ]]\n}\n\n# `list --bookmarks` ##########################################################\n\n@test \"'list --bookmarks' exits with 0 and displays a list of bookmarks.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"second.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" add \"fourth.bookmark.md\" -c \"<${_BOOKMARK_URL}>\"\n    cat <<HEREDOC | \"${_NB}\" add \"fifth.md\"\n# fifth\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --bookmarks\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${lines[0]}\"  =~  [*4*]*fourth.bookmark.md  ]]\n  [[ \"${lines[1]}\"  =~  [*2*]*second.bookmark.md  ]]\n}\n\n# `list --type` ###############################################################\n\n@test \"'list --type todo' without todos prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"Example File Two.md\" --content \"Example content two.\"\n  }\n\n  run \"${_NB}\" list --type todo\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"0 todos.\n\nAdd a todo:\n  $(_color_primary 'nb todo add <title>')\nHelp information:\n  $(_color_primary 'nb help todo')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n@test \"'list --type todo' with container without todos prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add folder \"Example Notebook:Example Folder\"\n  }\n\n  run \"${_NB}\" list Example\\ Notebook:Example\\ Folder/ --type todo\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"0 todos.\n\nAdd a todo:\n  $(_color_primary 'nb todo add Example\\ Notebook:1/ <title>')\nHelp information:\n  $(_color_primary 'nb help todo')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n@test \"'list --type todo' with todos lists todos.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"Example File Two.md\" --content \"Example content two.\"\n\n    \"${_NB}\" add \"Example Todo One.todo.md\" --content \"# [ ] Example not done todo.\"\n    \"${_NB}\" add \"Example Todo Two.todo.md\" --content \"# [x] Example done todo.\"\n  }\n\n  run \"${_NB}\" list --type todo\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"    -eq 0                                 ]]\n  [[   \"${lines[0]}\"  =~  \\\n.*\\[.*4.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ done\\ todo\\.     ]]\n  [[   \"${lines[1]}\"  =~  \\\n.*\\[.*3.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ not\\ done\\ todo\\.  ]]\n\n  [[ ! \"${lines[0]}\"  =~  \\ \\[x\\]\\                          ]]\n  [[ ! \"${lines[1]}\"  =~  \\ \\[\\ \\]\\                         ]]\n}\n\n@test \"'list --document' exits with 0 and displays a list of documents.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --document\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${#lines[@]}\" ==  1           ]]\n  [[ \"${lines[0]}\"  =~  second.doc  ]]\n  [[ \"${lines[0]}\"  =~  2           ]]\n}\n\n@test \"'list --documents' exits with 0 and displays a list of documents.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --documents\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${#lines[@]}\" ==  1           ]]\n  [[ \"${lines[0]}\"  =~  second.doc  ]]\n  [[ \"${lines[0]}\"  =~  2           ]]\n}\n\n@test \"'list --document' exits with 0 and displays empty list.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --document\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                     ]]\n  [[ \"${#lines[@]}\" ==  5                     ]]\n  [[ \"${lines[0]}\"  =~  0\\ document\\ items\\.  ]]\n}\n\n\n@test \"'list --documents' exits with 0 and displays empty list.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --documents\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                     ]]\n  [[ \"${#lines[@]}\" ==  5                     ]]\n  [[ \"${lines[0]}\"  =~  0\\ document\\ items\\.  ]]\n}\n\n@test \"'list --js' exits with 0, displays empty list, and retains trailing 's'.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list --js\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${#lines[@]}\" ==  5               ]]\n  [[ \"${lines[0]}\"  =~  0\\ js\\ items\\.  ]]\n}\n\n@test \"'list <selector> --type' filters by type.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"example.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list example --document\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${#lines[@]}\" ==  1           ]]\n  [[ \"${lines[0]}\"  =~  example.doc ]]\n  [[ \"${lines[0]}\"  =~  3           ]]\n}\n\n@test \"'list <selector> --<invalid>' prints message.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"example.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list example --not-valid\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 1           ]]\n\n  [[ \"${#lines[@]}\" ==  1           ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found  ]]\n  [[ \"${lines[0]}\"  =~  example     ]]\n  [[ \"${lines[0]}\"  =~  Type        ]]\n  [[ \"${lines[0]}\"  =~  not-valid   ]]\n}\n\n@test \"'list <selector> --documents' with no matches prints message.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"example.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list matchless-query --document\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 1               ]]\n\n  [[ \"${#lines[@]}\" ==  1               ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found      ]]\n  [[ \"${lines[0]}\"  =~  matchless-query ]]\n  [[ \"${lines[0]}\"  =~  Type            ]]\n  [[ \"${lines[0]}\"  =~  document        ]]\n}\n\n# `list <selector>` ###########################################################\n\n@test \"'list <selector>' exits with 0 and displays the selector.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\n# two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list 1 --filenames\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -eq 1             ]]\n  [[ \"${lines[0]}\"  =~  first.md      ]]\n  [[ \"${lines[0]}\"  =~  [*1*]         ]]\n}\n\n@test \"'list <query selector>' exits with 0 and displays the selectors.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list 'r' --filenames\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${#lines[@]}\" -eq 2        ]]\n  [[ \"${lines[0]}\"  =~  third.md ]]\n  [[ \"${lines[0]}\"  =~  [*3*]    ]]\n  [[ \"${lines[1]}\"  =~  first.md ]]\n  [[ \"${lines[1]}\"  =~  [*1*]    ]]\n}\n\n@test \"'list <query selector> --limit' exits with 0 and displays results and singular omitted message.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list 'r' --filenames --limit 1\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                               ]]\n\n  [[ \"${#lines[@]}\" -eq 2                               ]]\n  [[ \"${lines[0]}\"  =~  third.md                        ]]\n  [[ \"${lines[0]}\"  =~  [*3*]                           ]]\n  [[ \"${lines[1]}\"  =~  1\\ match\\ omitted\\.\\ 2\\ total\\. ]]\n}\n\n@test \"'list <query selector> --limit' exits with 0 and displays results and plural omitted message.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# three\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'fourth.md'\n# four\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list 'r' --filenames --limit 1\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n\n  [[ \"${#lines[@]}\" -eq 2                                 ]]\n  [[ \"${lines[0]}\"  =~  fourth.md                         ]]\n  [[ \"${lines[0]}\"  =~  [*4*]                             ]]\n  [[ \"${lines[1]}\"  =~  2\\ matches\\ omitted\\.\\ 3\\ total\\. ]]\n}\n\n@test \"'list <multi-word selector>' successfully filters list.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# example plum\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# example pluot\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# sample pear\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'fourth.md'\n# sample plum\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list 'example plum' --filenames\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${#lines[@]}\" -eq 1         ]]\n  [[ \"${lines[0]}\"  =~  first.md  ]]\n  [[ \"${lines[0]}\"  =~  [*1*]     ]]\n}\n\n@test \"'list <multiple> <selectors>' successfully filters list.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# example plum\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# example pluot\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# sample pear\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'fourth.md'\n# sample plum\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list example plum --filenames\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${#lines[@]}\" -eq 3         ]]\n  [[ \"${lines[0]}\"  =~  fourth.md ]]\n  [[ \"${lines[0]}\"  =~  [*4*]     ]]\n  [[ \"${lines[1]}\"  =~  second.md ]]\n  [[ \"${lines[1]}\"  =~  [*2*]     ]]\n  [[ \"${lines[2]}\"  =~  first.md  ]]\n  [[ \"${lines[2]}\"  =~  [*1*]     ]]\n}\n\n@test \"'list <multiple> <selectors>' with exact match also includes filtered results.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# plum\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# example pluot\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# sample pear\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'fourth.md'\n# example apple\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" list plum example --filenames\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${#lines[@]}\" -eq 3         ]]\n  [[ \"${lines[0]}\"  =~  fourth.md ]]\n  [[ \"${lines[0]}\"  =~  [*4*]     ]]\n  [[ \"${lines[1]}\"  =~  second.md ]]\n  [[ \"${lines[1]}\"  =~  [*2*]     ]]\n  [[ \"${lines[2]}\"  =~  first.md  ]]\n  [[ \"${lines[2]}\"  =~  [*1*]     ]]\n}\n\n@test \"'list <invalid-selector>' exits with 1 and displays a message.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add\n# one\nline two\nline three\nline four\nHEREDOC\n    sleep 1\n  }\n\n  run \"${_NB}\" list invalid\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 1             ]]\n\n  [[ \"${#lines[@]}\" -eq 1             ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found\\:  ]]\n  [[ \"${lines[0]}\"  =~  invalid       ]]\n}\n\n# `scoped:list` ###############################################################\n\n@test \"'scoped:list' exits with 0 and lists files in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"one\"\n\n    \"${_NB}\" one:add \"one.md\"   --title \"one\"\n    \"${_NB}\" one:add \"two.md\"   --title \"two\"\n    \"${_NB}\" one:add \"three.md\" --title \"three\"\n  }\n\n  run \"${_NB}\" one:list\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n\n  [[ \"${lines[0]}\"  =~  one:3   ]]\n  [[ \"${lines[0]}\"  =~  three   ]]\n  [[ \"${lines[1]}\"  =~  one:2   ]]\n  [[ \"${lines[1]}\"  =~  two     ]]\n  [[ \"${lines[2]}\"  =~  one:1   ]]\n  [[ \"${lines[2]}\"  =~  one     ]]\n}\n\n@test \"'scoped:list' with empty notebook prints help info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n  }\n\n  run \"${_NB}\" one:list\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  _expected=\"0 items.\n\nAdd a note:\n  $(_color_primary 'nb add one:')\nAdd a bookmark:\n  $(_color_primary 'nb one: <url>')\nAdd a todo:\n  $(_color_primary 'nb todo add one: <title>')\nImport a file:\n  $(_color_primary 'nb import (<path> | <url>) one:')\nHelp information:\n  $(_color_primary 'nb help')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n@test \"'scoped:list' escapes multi-word notebook name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"multi word\"\n  }\n\n  run \"${_NB}\" multi\\ word:list\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  _expected=\"0 items.\n\nAdd a note:\n  $(_color_primary 'nb add multi\\ word:')\nAdd a bookmark:\n  $(_color_primary 'nb multi\\ word: <url>')\nAdd a todo:\n  $(_color_primary 'nb todo add multi\\ word: <title>')\nImport a file:\n  $(_color_primary 'nb import (<path> | <url>) multi\\ word:')\nHelp information:\n  $(_color_primary 'nb help')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n@test \"'scoped:list --bookmarks' with empty notebook prints help info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n  }\n\n  run \"${_NB}\" one:list --bookmarks\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  _expected=\"0 bookmarks.\n\nAdd a bookmark:\n  $(_color_primary 'nb one: <url>')\nHelp information:\n  $(_color_primary 'nb help bookmark')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n@test \"'scoped:list --documents' with empty notebook prints help info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n  }\n\n  run \"${_NB}\" one:list --documents\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  _expected=\"0 document items.\n\nImport a file:\n  $(_color_primary 'nb import (<path> | <url>) one:')\nHelp information:\n  $(_color_primary 'nb help import')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n# `list --error-on-empty` #####################################################\n\n@test \"'list --error-on-empty' with empty notebook returns 1.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n  }\n\n  run \"${_NB}\" one:list\n\n  [[ \"${status}\" -eq 0 ]]\n\n  run \"${_NB}\" one:list --error-on-empty\n\n  [[ \"${status}\" -eq 1 ]]\n\n  \"${_NB}\" one:add \"one.md\" --title \"one\"\n\n  run \"${_NB}\" one:list --error-on-empty\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\" -eq 0 ]]\n}\n\n# `list <notebook>` ###########################################################\n\n@test \"'list <notebook>' (no colon) exits with 1 and prints not found.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"example\"\n\n    \"${_NB}\" example:add \"one.md\"   --title \"one\"\n    \"${_NB}\" example:add \"two.md\"   --title \"two\"\n    \"${_NB}\" example:add \"three.md\" --title \"three\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"home\" ]]\n  }\n\n  run \"${_NB}\" list example\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 1           ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found  ]]\n  [[ \"${lines[0]}\"  =~  example     ]]\n}\n\n@test \"'list <notebook>:' (colon) exits with 0 and lists files in <notebook> in reverse order.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"example\"\n\n    \"${_NB}\" example:add \"one.md\"   --title \"one\"\n    \"${_NB}\" example:add \"two.md\"   --title \"two\"\n    \"${_NB}\" example:add \"three.md\" --title \"three\"\n  }\n\n  run \"${_NB}\" list example:\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n  [[ \"${lines[0]}\"  =~  example:3 ]]\n  [[ \"${lines[0]}\"  =~  three     ]]\n  [[ \"${lines[1]}\"  =~  example:2 ]]\n  [[ \"${lines[1]}\"  =~  two       ]]\n  [[ \"${lines[2]}\"  =~  example:1 ]]\n  [[ \"${lines[2]}\"  =~  one       ]]\n}\n\n# help ########################################################################\n\n@test \"'help list' exits with status 0.\" {\n  run \"${_NB}\" help list\n\n  [[ \"${status}\" -eq 0 ]]\n}\n\n@test \"'help list' prints help information.\" {\n  run \"${_NB}\" help list\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${lines[0]}\" =~ Usage.*\\: ]]\n  [[ \"${lines[1]}\" =~ nb\\ list  ]]\n}\n"
  },
  {
    "path": "test/ls-pagination.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --per-page ##################################################################\n\n@test \"'nb --per-page <limit> [--page <number>]' paginates list.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set footer 0\n  }\n\n  # --per-page 3, first page\n\n  run \"${_NB}\" --per-page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 6                         ]]\n\n  [[ \"${lines[0]}\"  =~  home                      ]]\n  [[ \"${lines[1]}\"  =~  -----------------         ]]\n  [[ \"${lines[2]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[4]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[5]}\"  =~  7\\ omitted\\.\\ 10\\ total\\. ]]\n\n  run \"${_NB}\" --per-page 3 --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" --per-page 3 --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  # --per-page 3 --page 2+\n\n  run \"${_NB}\" --per-page 3 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" --per-page 3 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" --per-page 3 --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  # --per-page 5\n\n  run \"${_NB}\" --per-page 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 8                         ]]\n\n  [[ \"${lines[0]}\"  =~  home                      ]]\n  [[ \"${lines[1]}\"  =~  -----------------         ]]\n  [[ \"${lines[2]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[4]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[5]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[6]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[7]}\"  =~  5\\ omitted\\.\\ 10\\ total\\. ]]\n\n  run \"${_NB}\" --per-page 5 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" --per-page 5 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n# --<limit> ###################################################################\n\n@test \"'nb --<limit> [--page <number>]' paginates list.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set footer 0\n  }\n\n  # --3, first page\n\n  run \"${_NB}\" --3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 6                         ]]\n\n  [[ \"${lines[0]}\"  =~  home                      ]]\n  [[ \"${lines[1]}\"  =~  -----------------         ]]\n  [[ \"${lines[2]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[4]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[5]}\"  =~  7\\ omitted\\.\\ 10\\ total\\. ]]\n\n  run \"${_NB}\" --3 --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" --3 --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  # --3 --page 2+\n\n  run \"${_NB}\" --3 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" --3 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" --3 --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  # --5\n\n  run \"${_NB}\" --5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 8                         ]]\n\n  [[ \"${lines[0]}\"  =~  home                      ]]\n  [[ \"${lines[1]}\"  =~  -----------------         ]]\n  [[ \"${lines[2]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[4]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[5]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[6]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[7]}\"  =~  5\\ omitted\\.\\ 10\\ total\\. ]]\n\n  run \"${_NB}\" --5 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" --5 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n# `nb ls` #####################################################################\n\n@test \"'ls -p <number>' paginates list using value from \\$NB_LIMIT.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set limit 3\n  }\n\n  run \"${_NB}\" ls -p 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" ls -p 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" ls -p 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" ls -p 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" ls -p 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" ls -p 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n\n  {\n    \"${_NB}\" set limit 5\n  }\n\n  run \"${_NB}\" ls -p 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" ls -p 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" ls -p 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" ls -p 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n@test \"'ls --page <number>' paginates list using value from \\$NB_LIMIT.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set limit 3\n  }\n\n  run \"${_NB}\" ls --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" ls --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" ls --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" ls --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" ls --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" ls --page 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n\n  {\n    \"${_NB}\" set limit 5\n  }\n\n  run \"${_NB}\" ls --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" ls --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" ls --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" ls --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n@test \"'ls --limit <limit> [--page <number>]' paginates list.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set footer 0\n  }\n\n  # --limit 3, first page\n\n  run \"${_NB}\" ls --limit 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 6                         ]]\n\n  [[ \"${lines[0]}\"  =~  home                      ]]\n  [[ \"${lines[1]}\"  =~  ------------------------  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[4]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[5]}\"  =~  7\\ omitted\\.\\ 10\\ total\\. ]]\n\n  run \"${_NB}\" ls --limit 3 --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" ls --limit 3 --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  # --limit 3 --page 2+\n\n  run \"${_NB}\" ls --limit 3 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" ls --limit 3 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" ls --limit 3 --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  # --limit 5\n\n  run \"${_NB}\" ls --limit 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 8                         ]]\n\n  [[ \"${lines[0]}\"  =~  home                      ]]\n  [[ \"${lines[1]}\"  =~  ------------------------  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[4]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[5]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[6]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[7]}\"  =~  5\\ omitted\\.\\ 10\\ total\\. ]]\n\n  run \"${_NB}\" ls --limit 5 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" ls --limit 5 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n# `nb` ########################################################################\n\n@test \"'nb -p <number>' paginates list using value from \\$NB_LIMIT.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set limit 3\n  }\n\n  run \"${_NB}\" -p 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" -p 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" -p 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" -p 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" -p 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" -p 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n\n  {\n    \"${_NB}\" set limit 5\n  }\n\n  run \"${_NB}\" -p 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" -p 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" -p 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" -p 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n@test \"'nb --page <number>' paginates list using value from \\$NB_LIMIT.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set limit 3\n  }\n\n  run \"${_NB}\" --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" --page 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n\n  {\n    \"${_NB}\" set limit 5\n  }\n\n  run \"${_NB}\" --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[3]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[4]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n\n  run \"${_NB}\" --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n\n@test \"'nb --limit <limit> [--page <number>]' paginates list.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set footer 0\n  }\n\n  # --limit 3, first page\n\n  run \"${_NB}\" --limit 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 6                         ]]\n\n  [[ \"${lines[0]}\"  =~  home                      ]]\n  [[ \"${lines[1]}\"  =~  ------------------------  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[4]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[5]}\"  =~  7\\ omitted\\.\\ 10\\ total\\. ]]\n\n  run \"${_NB}\" --limit 3 --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  run \"${_NB}\" --limit 3 --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n\n  # --limit 3 --page 2+\n\n  run \"${_NB}\" --limit 3 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n\n  run \"${_NB}\" --limit 3 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" --limit 3 --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  # --limit 5\n\n  run \"${_NB}\" --limit 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -le 8                         ]]\n\n  [[ \"${lines[0]}\"  =~  home                      ]]\n  [[ \"${lines[1]}\"  =~  ------------------------  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[4]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[5]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[6]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[7]}\"  =~  5\\ omitted\\.\\ 10\\ total\\. ]]\n\n  run \"${_NB}\" --limit 5 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[1]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[3]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" --limit 5 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n"
  },
  {
    "path": "test/ls.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031\n\nload test_helper\n\n_setup_ls() {\n  \"${_NB}\" init\n\n  cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n  cat <<HEREDOC | \"${_NB}\" add \"second.md\"\n# two\nline two\nline three\nline four\nHEREDOC\n  cat <<HEREDOC | \"${_NB}\" add \"third.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n}\n\n# folders first ###############################################################\n\n@test \"'ls --folders-first' prints folders first while preserving pinning.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" folder add \"Folder One\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" folder add \"Folder Two\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Example content four.\"\n    \"${_NB}\" folder add \"Folder Three\"\n\n    \"${_NB}\" pin \"Folder Two\"\n    \"${_NB}\" pin \"File Three.md\"\n\n    export NB_FOOTER=0\n    export NB_HEADER=0\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 7 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📌\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ 📌\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*7.*].*\\ 📂\\ Folder\\ Three                                      ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*6.*].*\\ File\\ Four\\.md\\ \\·\\ \\\"Example\\ content\\ four\\.\\\"       ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"         ]]\n  [[ \"${lines[5]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                        ]]\n  [[ \"${lines[6]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"         ]]\n\n  run \"${_NB}\" ls --folders-first\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 7 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📌\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ 📌\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*7.*].*\\ 📂\\ Folder\\ Three                                      ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                        ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*6.*].*\\ File\\ Four\\.md\\ \\·\\ \\\"Example\\ content\\ four\\.\\\"       ]]\n  [[ \"${lines[5]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"         ]]\n\n  [[ \"${lines[6]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"         ]]\n}\n\n@test \"'ls --folders-first' prints folders first.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" folder add \"Folder One\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" folder add \"Folder Two\"\n\n    export NB_FOOTER=0\n    export NB_HEADER=0\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n\n  run \"${_NB}\" ls --folders-first\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n}\n\n@test \"'NB_FOLDERS_FIRST=1 ls' prints folders first.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" folder add \"Folder One\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" folder add \"Folder Two\"\n\n    export NB_FOOTER=0\n    export NB_HEADER=0\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n\n  NB_FOLDERS_FIRST=1 run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n}\n\n@test \"'NB_FOLDERS_FIRST=1 ls --no-folders-first' prints without folders first.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" folder add \"Folder One\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" folder add \"Folder Two\"\n\n    export NB_FOOTER=0\n    export NB_HEADER=0\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n\n  NB_FOLDERS_FIRST=1 run \"${_NB}\" ls --no-folders-first\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[.*5.*].*\\ 📂\\ Folder\\ Two                                    ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*[.*4.*].*\\ File\\ Three\\.md\\ \\·\\ \\\"Example\\ content\\ three\\.\\\" ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Two\\.md\\ \\·\\ \\\"Example\\ content\\ two\\.\\\"     ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*2.*].*\\ 📂\\ Folder\\ One                                    ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*1.*].*\\ File\\ One\\.md\\ \\·\\ \\\"Example\\ content\\ one\\.\\\"     ]]\n}\n\n# tags ########################################################################\n\n@test \"'--tags' exits with status 0 and prints tags in the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 #tag4 four. #tag5\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five.\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag3 #tag1\"\n    \"${_NB}\" add \"File Eight.md\"  --content \"#tag6 #tag7\"\n    \"${_NB}\" add \"тестовый.md\"    --content \"#тест\"\n  }\n\n  run \"${_NB}\" --tags\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}:   '%s'\\\\n\" \"${lines[0]}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0     ]]\n  [[    \"${#lines[@]}\"  -eq 8     ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"\\#tag1\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"\\#tag2\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"\\#tag3\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"\\#tag5\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"\\#tag5\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"\\#tag6\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"\\#tag7\"\n  printf \"%s\\\\n\" \"${output}\" | grep -q \"\\#тест\"\n}\n\n@test \"'--tag tag1,'#tag2' exits with status 0 and prints matches as an AND query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five.\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag3 #tag1\"\n    \"${_NB}\" add \"тестовый.md\"    --content \"#тест\"\n  }\n\n  run \"${_NB}\" --tag tag1,'#tag2'\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                             ]]\n  [[    \"${#lines[@]}\"  -eq 2                                             ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ #tag1\\ four.\\ #tag2\\\"          ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*[.*7.*].*\\ File\\ Seven.md\\ \\·\\ \\\"Content\\ #tag2\\ Seven.\\ #tag3\\ #tag1\\\" ]]\n}\n\n@test \"'ls \\#tag1 '#tag2' exits with status 0 and prints matches as an AND query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five.\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag3 #tag1\"\n    \"${_NB}\" add \"тестовый.md\"    --content \"#тест\"\n  }\n\n  run \"${_NB}\" \\#tag1 \"#tag2\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                             ]]\n  [[    \"${#lines[@]}\"  -eq 2                                             ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ #tag1\\ four.\\ #tag2\\\"          ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*[.*7.*].*\\ File\\ Seven.md\\ \\·\\ \\\"Content\\ #tag2\\ Seven.\\ #tag3\\ #tag1\\\" ]]\n}\n\n# pinning #####################################################################\n\n@test \"'ls --reverse' prints list without pinning.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"   --content \"#pinned\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin 1\n    \"${_NB}\" pin 4\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Four.md\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  run \"${_NB}\" ls --reverse\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*4.*].*\\ Title\\ Four   ]]\n}\n\n@test \"'ls -r' prints list without pinning.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"   --content \"#pinned\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin 1\n    \"${_NB}\" pin 4\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Four.md\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  run \"${_NB}\" ls -r\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*4.*].*\\ Title\\ Four   ]]\n}\n\n@test \"'ls --sort' prints list without pinning.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"   --content \"#pinned\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin 1\n    \"${_NB}\" pin 4\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Four.md\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  run \"${_NB}\" ls --sort\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*4.*].*\\ Title\\ Four   ]]\n}\n\n@test \"'ls -s' prints list without pinning.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"   --content \"#pinned\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin 1\n    \"${_NB}\" pin 4\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Four.md\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  run \"${_NB}\" ls -s\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*4.*].*\\ Title\\ Four   ]]\n}\n\n@test \"'ls' reconciles .pindex when file is deleted and deletes .pindex when empty.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"Example Folder/File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin Example\\ Folder/3\n\n    diff                                          \\\n      <(printf \"File Three.md\\\\n\")                \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n\n    rm \"${NB_DIR}/home/Example Folder/File Three.md\"\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/File Three.md\" ]]\n\n    diff                                          \\\n      <(printf \"File Three.md\\\\n\")                \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" ls Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  .*home.*                                      ]]\n  [[ \"${lines[1]}\"  =~  --------                                      ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/4.*].*\\ Title\\ Four     ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n  [[ \"${lines[4]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ Title\\ One      ]]\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/.pindex\"                     ]]\n}\n\n@test \"'ls' reconciles .pindex when folder is deleted.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"   --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"   --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/Folder Three\"  --type  folder\n    \"${_NB}\" add \"Example Folder/File Four.md\"  --title \"Title Four\"\n\n    \"${_NB}\" pin Example\\ Folder/1\n    \"${_NB}\" pin Example\\ Folder/3\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFolder Three\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n\n    rm -r \"${NB_DIR}/home/Example Folder/Folder Three\"\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/Folder Three\" ]]\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFolder Three\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" ls Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  .*home.*                                      ]]\n  [[ \"${lines[1]}\"  =~  --------                                      ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*Example\\ Folder/4.*].*\\ Title\\ Four     ]]\n  [[ \"${lines[4]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n\n  diff                                            \\\n    <(printf \"File One.md\\\\n\")                    \\\n    <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n}\n\n@test \"'ls' reconciles .pindex when file is deleted.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"Example Folder/File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin Example\\ Folder/1\n    \"${_NB}\" pin Example\\ Folder/3\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Three.md\\\\n\")  \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n\n    rm \"${NB_DIR}/home/Example Folder/File Three.md\"\n\n    [[ ! -e \"${NB_DIR}/home/Example Folder/File Three.md\" ]]\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Three.md\\\\n\")  \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" ls Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  .*home.*                                      ]]\n  [[ \"${lines[1]}\"  =~  --------                                      ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*Example\\ Folder/4.*].*\\ Title\\ Four     ]]\n  [[ \"${lines[4]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n\n  diff                                            \\\n    <(printf \"File One.md\\\\n\")  \\\n    <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n}\n\n@test \"'ls' prints list with items pinned.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"\n    \"${_NB}\" add \"File Five.md\"   --title \"Title Five\" --content \"#pinned\"\n\n    \"${_NB}\" pin 1\n    \"${_NB}\" pin 4\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Four.md\\\\n\")   \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n\n  [[ \"${lines[0]}\"  =~  .*home.*                      ]]\n  [[ \"${lines[1]}\"  =~  --------                      ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*4.*].*\\ 📌\\ Title\\ Four ]]\n  [[ \"${lines[4]}\"  =~  \\.*[.*5.*].*\\ 📌\\ Title\\ Five ]]\n  [[ \"${lines[5]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[6]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n}\n\n# edge cases ##################################################################\n\n@test \"'ls <query>' with partial notebook name match prints 'not found' message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n  }\n\n  run \"${_NB}\" ls notebook\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1                              ]]\n  [[    \"${#lines[@]}\" -eq 1                              ]]\n\n  [[    \"${output}\"    =~  \\!.*\\ Not\\ found:\\ .*notebook  ]]\n}\n\n# --archived / --unarchived ###################################################\n\n@test \"'ls' delegates --ar, --archived, --unar, and --unarchived options to 'notebooks'.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" archive \"Sample Notebook\"\n    \"${_NB}\" archive \"Test Notebook\"\n  }\n\n  run \"${_NB}\" ls --ar\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                              ]]\n  [[    \"${#lines[@]}\" -eq 2                              ]]\n\n  [[ !  \"${output}\"    =~  home                           ]]\n  [[ !  \"${output}\"    =~  Example\\ Notebook              ]]\n  [[    \"${output}\"    =~  Sample\\ Notebook\\ \\(archived\\) ]]\n  [[ !  \"${output}\"    =~  Demo\\ Notebook                 ]]\n  [[    \"${output}\"    =~  Test\\ Notebook\\ \\(archived\\)   ]]\n\n  run \"${_NB}\" ls --archived\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                              ]]\n  [[    \"${#lines[@]}\" -eq 2                              ]]\n\n  [[ !  \"${output}\"    =~  home                           ]]\n  [[ !  \"${output}\"    =~  Example\\ Notebook              ]]\n  [[    \"${output}\"    =~  Sample\\ Notebook\\ \\(archived\\) ]]\n  [[ !  \"${output}\"    =~  Demo\\ Notebook                 ]]\n  [[    \"${output}\"    =~  Test\\ Notebook\\ \\(archived\\)   ]]\n\n  run \"${_NB}\" ls --unar\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                              ]]\n  [[    \"${#lines[@]}\" -eq 3                              ]]\n\n  [[    \"${output}\"    =~  home                           ]]\n  [[    \"${output}\"    =~  Example\\ Notebook              ]]\n  [[ !  \"${output}\"    =~  Sample\\ Notebook               ]]\n  [[    \"${output}\"    =~  Demo\\ Notebook                 ]]\n  [[ !  \"${output}\"    =~  Test\\ Notebook                 ]]\n\n  run \"${_NB}\" ls --unarchived\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                              ]]\n  [[    \"${#lines[@]}\" -eq 3                              ]]\n\n  [[    \"${output}\"    =~  home                           ]]\n  [[    \"${output}\"    =~  Example\\ Notebook              ]]\n  [[ !  \"${output}\"    =~  Sample\\ Notebook               ]]\n  [[    \"${output}\"    =~  Demo\\ Notebook                 ]]\n  [[ !  \"${output}\"    =~  Test\\ Notebook                 ]]\n}\n\n# `ls --type` #################################################################\n\n@test \"'ls --document' exits with 0 and displays a list of documents.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls --document\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${#lines[@]}\" ==  1           ]]\n  [[ \"${lines[0]}\"  =~  second.doc  ]]\n  [[ \"${lines[0]}\"  =~  2           ]]\n}\n\n@test \"'ls --documents' exits with 0 and displays a list of documents.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls --documents\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${#lines[@]}\" ==  1           ]]\n  [[ \"${lines[0]}\"  =~  second.doc  ]]\n  [[ \"${lines[0]}\"  =~  2           ]]\n}\n\n@test \"'ls --document' exits with 0 and displays empty list.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set footer 0\n\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls --document\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                     ]]\n\n  [[ \"${#lines[@]}\" ==  7                     ]]\n  [[ \"${lines[2]}\"  =~  0\\ document\\ items\\.  ]]\n}\n\n@test \"'ls --documents' exits with 0 and displays empty list.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set footer 0\n\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls --documents\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                     ]]\n\n  [[ \"${#lines[@]}\" ==  7                     ]]\n  [[ \"${lines[2]}\"  =~  0\\ document\\ items\\.  ]]\n}\n\n@test \"'ls --js' exits with 0, displays empty list, and retains trailing 's'.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set footer 0\n\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls --js\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n\n  [[ \"${#lines[@]}\" ==  7               ]]\n  [[ \"${lines[2]}\"  =~  0\\ js\\ items\\.  ]]\n}\n\n@test \"'ls <selection> --type' filters by type.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"example.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls example --document\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${#lines[@]}\" ==  1           ]]\n  [[ \"${lines[0]}\"  =~  example.doc ]]\n  [[ \"${lines[0]}\"  =~  3           ]]\n}\n\n@test \"'ls <selection> --<invalid>' prints message.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"example.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls example --not-valid\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 1           ]]\n\n  [[ \"${#lines[@]}\" ==  1           ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found  ]]\n  [[ \"${lines[0]}\"  =~  example     ]]\n  [[ \"${lines[0]}\"  =~  Type        ]]\n  [[ \"${lines[0]}\"  =~  not-valid   ]]\n}\n\n@test \"'ls <selection> --documents' with no matches prints message.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"example.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"sample.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls matchless-query --document\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 1               ]]\n\n  [[ \"${#lines[@]}\" ==  1               ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found      ]]\n  [[ \"${lines[0]}\"  =~  matchless-query ]]\n  [[ \"${lines[0]}\"  =~  Type            ]]\n  [[ \"${lines[0]}\"  =~  document        ]]\n}\n\n@test \"'<notebook>: <selection> --documents' with no matches prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n    cat <<HEREDOC | \"${_NB}\" example:add \"example.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" example:add \"sample.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" example:add \"example.doc\"\nline one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" example:add \"sample.md\"\nline one\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" example: matchless-query --document\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 1                                                                 ]]\n  [[ \"${#lines[@]}\" ==  1                                                                 ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found:\\ .*example:.*\\ .*matchless-query.*\\ Type:\\ .*document ]]\n}\n\n# subcommand delegation #######################################################\n\n@test \"'ls <selector> --added' exits with status 0 and prints the added timestamp using _show().\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" ls 1 --added\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                 ]]\n  [[ \"${output}\" =~   [0-9]{4}-[0-9]{2} ]]\n}\n\n@test \"'ls <selector> --updated' exits with status 0 and prints the updated timestamp using _show().\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" ls 1 --updated\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                 ]]\n  [[ \"${output}\" =~   [0-9]{4}-[0-9]{2} ]]\n}\n\n@test \"'ls --title' with no argument exits with 0 and lists files.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls --title\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n  [[ \"${lines[0]}\"  =~  home  ]]\n  [[ \"${lines[1]}\"  =~  ----  ]]\n  [[ \"${lines[2]}\"  =~  three ]]\n  [[ \"${lines[3]}\"  =~  two   ]]\n  [[ \"${lines[4]}\"  =~  one   ]]\n}\n\n@test \"'ls --content <content>' creates new note with <content> using _add().\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls --content \"Example content:more/example/content.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls \"${NB_DIR}/home/\"\n\n  [[    \"${status}\" -eq 0      ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  _filename=\"${_files[0]:-}\"\n\n  [[ -f \"${NB_DIR}/home/${_filename}\" ]]\n\n  cat \"${NB_DIR}/home/${_filename}\"\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/${_filename}\")  \\\n    <(printf \"Example content:more/example/content.md\\\\n\")\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'ls --content' with no argument exits with 0 and lists files.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls --title\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n  [[ \"${lines[0]}\"  =~  home  ]]\n  [[ \"${lines[1]}\"  =~  ----  ]]\n  [[ \"${lines[2]}\"  =~  three ]]\n  [[ \"${lines[3]}\"  =~  two   ]]\n  [[ \"${lines[4]}\"  =~  one   ]]\n}\n\n@test \"'ls --title <title>' creates new note with <title> using _add().\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls --title \\\n    \"Example Title: A*string•with/a\\\\bunch|of?invalid<filename\\\"characters>\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls \"${NB_DIR}/home/\"\n\n  [[    \"${status}\" -eq 0      ]]\n\n  _filename=\"example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md\"\n\n  [[ -f \"${NB_DIR}/home/${_filename}\" ]]\n\n\n  cat \"${NB_DIR}/home/${_filename}\"\n\n  [[ \"$(cat \"${NB_DIR}/home/${_filename}\")\" =~ \\\n        \\#\\ Example\\ Title\\:\\ A\\*string•with\\/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\> ]]\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Add'\n}\n\n# header and footer ###########################################################\n\n@test \"'ls --type' hides header and footer when results are displayed.\" {\n  {\n    _setup_ls\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" ls --type md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0               ]]\n  [[    \"${#lines[@]}\"  -eq 3               ]]\n\n  [[ !  \"${lines[0]}\"   =~  home            ]]\n  [[ !  \"${lines[1]}\"   =~  ---             ]]\n\n  [[    \"${lines[0]}\"   =~ [.*3.*].*\\ three ]]\n  [[    \"${lines[1]}\"   =~ [.*2.*].*\\ two   ]]\n  [[    \"${lines[2]}\"   =~ [.*1.*].*\\ one   ]]\n}\n\n@test \"'ls <query> --type' hides header and footer when no results are found.\" {\n  {\n    _setup_ls\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" ls not-valid --type example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                                             ]]\n  [[    \"${#lines[@]}\"  -eq 1                                             ]]\n\n  [[ !  \"${lines[0]}\"   =~  home                                          ]]\n  [[ !  \"${lines[1]}\"   =~  ---                                           ]]\n\n  [[    \"${lines[0]}\"   =~  Not\\ found:\\ .*not-valid.*\\ Type:\\ .*example  ]]\n}\n\n@test \"'ls <folder>/ <query> --type' hides header and footer when no results are found.\" {\n  {\n    _setup_ls\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" ls Example\\ Folder/ not-valid --type example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                                                 ]]\n  [[    \"${#lines[@]}\"  -eq 1                                                 ]]\n\n  [[ !  \"${lines[0]}\"   =~  home                                              ]]\n  [[ !  \"${lines[1]}\"   =~  ---                                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          Not\\ found:\\ .*Example\\ Folder/.*\\ .*not-valid.*\\ Type:\\ .*example  ]]\n}\n\n@test \"'ls <notebook>: <query> --type' hides header and footer when no results are found.\" {\n  {\n    _setup_ls\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" ls Example\\ Notebook: not-valid --type example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                                                   ]]\n  [[    \"${#lines[@]}\"  -eq 1                                                   ]]\n\n  [[ !  \"${lines[0]}\"   =~  home                                                ]]\n  [[ !  \"${lines[1]}\"   =~  ---                                                 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          Not\\ found:\\ .*Example\\ Notebook:.*\\ .*not-valid.*\\ Type:\\ .*example  ]]\n}\n\n@test \"'ls <notebook>:<folder>/ <query> --type' hides header and footer when no results are found.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add \"Example Notebook:Example Folder\" --type folder\n\n    [[ -d \"${NB_DIR}/Example Notebook/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" ls Example\\ Notebook:Example\\ Folder/ not-valid --type example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                                                   ]]\n  [[    \"${#lines[@]}\"  -eq 1                                                   ]]\n\n  [[ !  \"${lines[0]}\"   =~  home                                                ]]\n  [[ !  \"${lines[1]}\"   =~  ---                                                 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          Not\\ found:\\ .*Example\\ Notebook:.*Example\\ Folder\\/.*\\ .*not-valid.*\\ Type:\\ .*example  ]]\n}\n\n@test \"'ls --type' shows header and footer when empty.\" {\n  {\n    _setup_ls\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" ls --type not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -ge 10                                  ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Notebook.*\\ .*·.*\\ .*home  ]]\n  [[    \"${lines[1]}\"   =~  ---                                 ]]\n\n  [[    \"${lines[2]}\"   =~  0\\ not-valid\\ items.                ]]\n\n  [[    \"${lines[7]}\"   =~  ---                                 ]]\n  [[    \"${lines[8]}\"   =~  nb\\ add                             ]]\n}\n\n@test \"'ls <notebook>: --type' shows header and footer when empty.\" {\n  {\n    _setup_ls\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" ls Example\\ Notebook: --type not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -ge 10                                  ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ Notebook.*\\ .*·.*\\ .*home  ]]\n  [[    \"${lines[1]}\"   =~  ---                                 ]]\n\n  [[    \"${lines[2]}\"   =~  0\\ not-valid\\ items.                ]]\n\n  [[    \"${lines[7]}\"   =~  ---                                 ]]\n  [[    \"${lines[8]}\"   =~  nb\\ add\\ Example\\\\\\ Notebook:       ]]\n}\n\n# header ######################################################################\n\n@test \"'ls' includes header.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n  [[ \"${lines[0]}\"  =~  home  ]]\n}\n\n@test \"'NB_HEADER=0 ls' does not include header.\" {\n  {\n    _setup_ls\n  }\n\n  NB_HEADER=0 run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0     ]]\n  [[ !  \"${lines[0]}\" =~  home  ]]\n}\n\n@test \"'ls' header does not escape multi-word notebook names.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" notebooks add \"example\"\n    \"${_NB}\" use example\n    \"${_NB}\" notebooks rename home \"multi word\"\n\n    _notebooks=(\n      \"example\"\n      \"multi word\"\n    )\n\n    diff                                      \\\n      <(\"${_NB}\" notebooks --no-color)        \\\n      <(printf \"%s\\\\n\" \"${_notebooks[@]:-}\")\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"example\" ]]\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${lines[0]}\"  =~  example     ]]\n  [[ \"${lines[0]}\"  =~  multi\\ word ]]\n}\n\n@test \"'ls' header shows added and deleted notebook.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0       ]]\n\n  [[ !  \"${lines[0]}\" =~  example ]]\n  [[    \"${lines[0]}\" =~  home    ]]\n\n  run \"${_NB}\" notebooks add example\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n\n  [[ \"${lines[0]}\"  =~  example ]]\n  [[ \"${lines[0]}\"  =~  home    ]]\n\n  run \"${_NB}\" notebooks delete home --force\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0       ]]\n\n  [[    \"${lines[0]}\" =~  example ]]\n  [[ !  \"${lines[0]}\" =~  home    ]]\n}\n\n@test \"'ls' header shows externally added and deleted notebook.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0       ]]\n\n  [[ !  \"${lines[0]}\" =~  example ]]\n  [[    \"${lines[0]}\" =~  home    ]]\n\n  mkdir \"${NB_DIR}/example\"\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n\n  [[ \"${lines[0]}\"  =~  example ]]\n  [[ \"${lines[0]}\"  =~  home    ]]\n\n  mv \"${NB_DIR}/example\" \"${_TMP_DIR}/\"\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0       ]]\n\n  [[ !  \"${lines[0]}\" =~  example ]]\n  [[    \"${lines[0]}\" =~  home    ]]\n}\n\n# footer ######################################################################\n\n@test \"'ls' includes footer.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${lines[6]}\"  =~  ❯ ]]\n}\n\n@test \"'NB_FOOTER=0 ls' does not include footer.\" {\n  {\n    _setup_ls\n  }\n\n  NB_FOOTER=0 run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n  [[ !  \"${lines[6]}\" =~  ❯ ]]\n}\n\n@test \"'ls' footer uses expected spacing and escaping.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add  \"Example Notebook:Example Folder/Example File.md\" \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" ls --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                     ]]\n\n  [[ \"${lines[6]}\"  =~  ❯                     ]]\n  [[ \"${lines[6]}\"  =~  nb\\ add               ]]\n  [[ \"${lines[6]}\"  =~  nb\\ \\<url\\>           ]]\n  [[ \"${lines[6]}\"  =~  nb\\ edit\\ \\<id\\>      ]]\n\n  [[ \"${output}\"    =~  nb\\ browse\\ \\·        ]] ||\n    [[ \"${output}\"  =~  nb\\ browse${_NEWLINE} ]]\n\n  [[ \"${output}\"    =~  nb\\ search\\ \\<query\\> ]]\n\n  run \"${_NB}\" ls Example\\ Notebook:Example\\ Folder/ --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[4]}\"  =~  ❯                                             ]]\n  [[ \"${lines[4]}\"  =~  nb\\ add\\ Example\\\\\\ Notebook:1/               ]]\n\n  [[ \"${output}\"    =~  nb\\ Example\\\\\\ Notebook:1/\\ \\<url\\>           ]]\n  [[ \"${output}\"    =~  nb\\ edit\\ Example\\\\\\ Notebook:1/\\<id\\>        ]]\n\n  [[ \"${output}\"    =~  nb\\ browse\\ Example\\\\\\ Notebook:1/\\ \\·        ]] ||\n    [[ \"${output}\"  =~  nb\\ browse\\ Example\\\\\\ Notebook:1/${_NEWLINE} ]]\n\n  [[ \"${output}\"    =~  nb\\ search\\ Example\\\\\\ Notebook:1/\\ \\<query\\> ]]\n}\n\n@test \"'ls' footer includes command names.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                 ]]\n\n  [[ \"${lines[6]}\"  =~  ❯                 ]]\n  [[ \"${lines[6]}\"  =~  nb\\ add           ]]\n  [[ \"${lines[6]}\"  =~  nb\\ \\<url\\>       ]]\n  [[ \"${lines[6]}\"  =~  nb\\ edit\\ \\<id\\>  ]]\n}\n\n@test \"'ls' footer scopes command names to a selected notebook.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" notebooks add \"example\"\n    \"${_NB}\" use example\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"example\" ]]\n  }\n\n  run \"${_NB}\" home:ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                     ]]\n\n  [[ \"${lines[6]}\"  =~  ❯                     ]]\n  [[ \"${lines[6]}\"  =~  nb\\ add\\ home:        ]]\n  [[ \"${lines[6]}\"  =~  nb\\ home:\\ \\<url\\>    ]]\n  [[ \"${lines[6]}\"  =~  nb\\ edit\\ home:\\<id\\> ]]\n}\n\n@test \"'ls' footer escapes multi-word selected notebook names.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" notebooks add \"example\"\n    \"${_NB}\" use example\n    \"${_NB}\" notebooks rename home \"multi word\"\n\n    _notebooks=(\n      \"example\"\n      \"multi word\"\n    )\n\n    diff                                      \\\n      <(\"${_NB}\" notebooks --no-color)        \\\n      <(printf \"%s\\\\n\" \"${_notebooks[@]:-}\")\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"example\" ]]\n  }\n\n  run \"${_NB}\" multi\\ word:ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                               ]]\n\n  [[ \"${lines[6]}\"  =~  ❯                               ]]\n  [[ \"${lines[6]}\"  =~  nb\\ add\\ multi\\\\\\ word:         ]]\n  [[ \"${lines[6]}\"  =~  nb\\ multi\\\\\\ word:\\ \\<url\\>     ]] ||\n    [[ \"${lines[7]}\"  =~  nb\\ multi\\\\\\ word:\\ \\<url\\>     ]]\n  [[ \"${lines[6]}\"  =~  nb\\ edit\\ multi\\\\\\ word:\\<id\\>  ]] ||\n    [[ \"${lines[7]}\"  =~  nb\\ edit\\ multi\\\\\\ word:\\<id\\>  ]]\n}\n\n# --no-header / --no-footer ###################################################\n\n@test \"'ls --no-header' does not include header.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" notebooks add \"example-notebook\"\n  }\n\n  run \"${_NB}\" ls --no-header\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq   0                 ]]\n\n  [[    \"${output}\"   =~    two               ]]\n  [[ !  \"${output}\"   =~    example-notebook  ]]\n  [[    \"${output}\"   =~    ❯                 ]]\n}\n\n@test \"'ls --no-footer' does not include footer.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" notebooks add \"example-notebook\"\n  }\n\n  run \"${_NB}\" ls --no-footer\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq   0                 ]]\n\n  [[    \"${output}\"   =~    two               ]]\n  [[    \"${output}\"   =~    example-notebook  ]]\n  [[ !  \"${output}\"   =~    ❯                 ]]\n}\n\n# `scoped:ls` #################################################################\n\n@test \"'scoped:ls' exits with 0 and lists files in reverse order.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"one.md\" --title \"one\"\n    \"${_NB}\" one:add \"two.md\" --title \"two\"\n    \"${_NB}\" one:add \"three.md\" --title \"three\"\n  }\n\n  NB_FOOTER=0 NB_HEADER=0 run \"${_NB}\" one:ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${lines[0]}\"  =~  one:3 ]]\n  [[ \"${lines[0]}\"  =~  three ]]\n  [[ \"${lines[1]}\"  =~  one:2 ]]\n  [[ \"${lines[1]}\"  =~  two   ]]\n  [[ \"${lines[2]}\"  =~  one:1 ]]\n  [[ \"${lines[2]}\"  =~  one   ]]\n}\n\n@test \"'scoped:ls' with empty notebook prints help info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n  }\n\n  NB_FOOTER=0 NB_HEADER=0 run \"${_NB}\" one:ls\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"0 items.\n\nAdd a note:\n  $(_color_primary 'nb add one:')\nAdd a bookmark:\n  $(_color_primary 'nb one: <url>')\nAdd a todo:\n  $(_color_primary 'nb todo add one: <title>')\nImport a file:\n  $(_color_primary 'nb import (<path> | <url>) one:')\nHelp information:\n  $(_color_primary 'nb help')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n@test \"'scoped:ls' escapes multi-word notebook name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"multi word\"\n  }\n\n  NB_FOOTER=0 NB_HEADER=0 run \"${_NB}\" multi\\ word:ls\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"0 items.\n\nAdd a note:\n  $(_color_primary 'nb add multi\\ word:')\nAdd a bookmark:\n  $(_color_primary 'nb multi\\ word: <url>')\nAdd a todo:\n  $(_color_primary 'nb todo add multi\\ word: <title>')\nImport a file:\n  $(_color_primary 'nb import (<path> | <url>) multi\\ word:')\nHelp information:\n  $(_color_primary 'nb help')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n@test \"'scoped:ls --bookmarks' with empty notebook prints help info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n  }\n\n  NB_FOOTER=0 NB_HEADER=0 run \"${_NB}\" one:ls --bookmarks\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"0 bookmarks.\n\nAdd a bookmark:\n  $(_color_primary 'nb one: <url>')\nHelp information:\n  $(_color_primary 'nb help bookmark')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n@test \"'scoped:ls --documents' with empty notebook prints help info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n  }\n\n  NB_FOOTER=0 NB_HEADER=0 run \"${_NB}\" one:ls --documents\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"0 document items.\n\nImport a file:\n  $(_color_primary 'nb import (<path> | <url>) one:')\nHelp information:\n  $(_color_primary 'nb help import')\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${_expected}\" ==  \"${output}\" ]]\n}\n\n# `ls` ########################################################################\n\n@test \"'ls' exits with 0 and lists files.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n  [[ \"${lines[0]}\"  =~  home  ]]\n  [[ \"${lines[1]}\"  =~  ----  ]]\n  [[ \"${lines[2]}\"  =~  three ]]\n  [[ \"${lines[3]}\"  =~  two   ]]\n  [[ \"${lines[4]}\"  =~  one   ]]\n}\n\n@test \"'ls' exits with 0 and includes archive count.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" notebooks add one\n    \"${_NB}\" one:notebook archive\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                   ]]\n  [[ \"${lines[0]}\"  =~  home                ]]\n  [[ \"${lines[0]}\"  =~  .\\ \\[1\\ archived\\]  ]]\n  [[ \"${lines[1]}\"  =~  ------------------- ]]\n  [[ \"${lines[2]}\"  =~  three               ]]\n  [[ \"${lines[3]}\"  =~  two                 ]]\n  [[ \"${lines[4]}\"  =~  one                 ]]\n}\n\n@test \"'ls' with local includes it in notebook list.\" {\n  {\n    _setup_ls\n\n    mkdir -p \"${_TMP_DIR}/example\"\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${lines[0]}\"  =~  local         ]]\n  [[ \"${lines[0]}\"  =~  home          ]]\n  [[ \"${lines[1]}\"  =~  ------------  ]]\n  [[ \"${lines[2]}\"  =~  0\\ items\\.    ]]\n}\n\n# `ls -e [<excerpt length>]` ##################################################\n\n@test \"'ls -e <excerpt length>' exits with 0 and displays excerpts.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls -e 5\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 18  ]]\n}\n\n# `ls -n <number>`, ls --limit <number>, ls --<number> ########################\n\n@test \"'ls --limit' with no argument exits with 1 and prints message.\" {\n  {\n    _setup_ls\n  }\n\n  run \"${_NB}\" ls --limit\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 1                                                 ]]\n  [[ \"${#lines[@]}\" -eq 1                                                 ]]\n\n  [[ \"${lines[0]}\"  =~  \\!.*\\ .*--limit.*\\ requires\\ a\\ valid\\ argument\\. ]]\n}\n\n@test \"'ls -n 0' exits with 0 and lists 0 files.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls -n 0\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n  [[ \"${lines[2]}\"  =~  3\\ omitted\\.\\ 3\\ total\\.  ]]\n}\n\n@test \"'ls -n 1' exits with 0 and lists 1 file.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls -n 1\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n\n  [[ \"${#lines[@]}\" -eq 4                         ]]\n  [[ \"${lines[2]}\"  =~  three                     ]]\n  [[ \"${lines[3]}\"  =~  2\\ omitted\\.\\ 3\\ total\\.  ]]\n}\n\n@test \"'ls -n 2' exits with 0 and lists 2 files.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls -n 2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n  [[ \"${lines[2]}\"  =~  three                     ]]\n  [[ \"${lines[3]}\"  =~  two                       ]]\n  [[ \"${lines[4]}\"  =~  1\\ omitted\\.\\ 3\\ total\\.  ]]\n}\n\n@test \"'ls -n 3' exits with 0 and lists 3 files.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls -n 3\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${#lines[@]}\" -eq 5     ]]\n  [[ \"${lines[2]}\"  =~  three ]]\n  [[ \"${lines[3]}\"  =~  two   ]]\n  [[ \"${lines[4]}\"  =~  one   ]]\n}\n\n@test \"'ls --limit 3' exits with 0 and lists 3 files.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls -n 3\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${#lines[@]}\" -eq 5     ]]\n  [[ \"${lines[2]}\"  =~  three ]]\n  [[ \"${lines[3]}\"  =~  two   ]]\n  [[ \"${lines[4]}\"  =~  one   ]]\n}\n\n@test \"'ls -<limit>' exits with 0 and lists limited files.\" {\n  {\n    \"${_NB}\" init\n\n    declare _numbers=(\n      One Two Three Four Five Six Seven Eight Nine Ten\n      Eleven Twelve Thirteen Fourteen Fifteen Sixteen\n      Seventeen Eighteen Nineteen Twenty\n    )\n\n    declare __number=\n    for   __number in \"${_numbers[@]}\"\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls -2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n  [[ \"${#lines[@]}\" -eq 5         ]]\n  [[ \"${lines[2]}\"  =~  Twenty    ]]\n  [[ \"${lines[3]}\"  =~  Nineteen  ]]\n\n  run \"${_NB}\" ls -13\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n  [[ \"${#lines[@]}\" -eq 16        ]]\n  [[ \"${lines[2]}\"  =~  Twenty    ]]\n  [[ \"${lines[3]}\"  =~  Nineteen  ]]\n}\n\n@test \"'-<limit>' (no ls) exits with 0 and lists limited files.\" {\n  {\n    \"${_NB}\" init\n\n    declare _numbers=(\n      One Two Three Four Five Six Seven Eight Nine Ten\n      Eleven Twelve Thirteen Fourteen Fifteen Sixteen\n      Seventeen Eighteen Nineteen Twenty\n    )\n\n    declare __number=\n    for   __number in \"${_numbers[@]}\"\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" -2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n  [[ \"${#lines[@]}\" -eq 5         ]]\n  [[ \"${lines[2]}\"  =~  Twenty    ]]\n  [[ \"${lines[3]}\"  =~  Nineteen  ]]\n\n  run \"${_NB}\" -13\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n  [[ \"${#lines[@]}\" -eq 16        ]]\n  [[ \"${lines[2]}\"  =~  Twenty    ]]\n  [[ \"${lines[3]}\"  =~  Nineteen  ]]\n}\n\n@test \"'ls --<limit>' exits with 0 and lists limited files.\" {\n  {\n    _setup_ls\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls --2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n  [[ \"${#lines[@]}\" -eq 5     ]]\n  [[ \"${lines[2]}\"  =~  three ]]\n  [[ \"${lines[3]}\"  =~  two   ]]\n\n  run \"${_NB}\" ls --3\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n  [[ \"${#lines[@]}\" -eq 5     ]]\n  [[ \"${lines[2]}\"  =~  three ]]\n  [[ \"${lines[3]}\"  =~  two   ]]\n  [[ \"${lines[4]}\"  =~  one   ]]\n}\n\n# `ls -s` / `ls --sort` / `ls -r` / `ls --reverse` ############################\n\n@test \"'ls --sort' sorts items.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first-home.md\"\n# title one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second-home.md\"\n# title two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third-example.md\"\n# title three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls --sort\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -eq 3             ]]\n  [[ \"${lines[0]}\"  =~  title\\ one    ]]\n  [[ \"${lines[0]}\"  =~  [*1*]         ]]\n  [[ \"${lines[1]}\"  =~  title\\ two    ]]\n  [[ \"${lines[1]}\"  =~  [*2*]         ]]\n  [[ \"${lines[2]}\"  =~  title\\ three  ]]\n  [[ \"${lines[2]}\"  =~  [*3*]         ]]\n}\n\n@test \"'ls --sort --reverse' reverse sorts items.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first-home.md\"\n# title one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second-home.md\"\n# title two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third-example.md\"\n# title three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls --sort --reverse\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -eq 3             ]]\n  [[ \"${lines[0]}\"  =~  title\\ three  ]]\n  [[ \"${lines[0]}\"  =~  [*3*]         ]]\n  [[ \"${lines[1]}\"  =~  title\\ two    ]]\n  [[ \"${lines[1]}\"  =~  [*2*]         ]]\n  [[ \"${lines[2]}\"  =~  title\\ one    ]]\n  [[ \"${lines[2]}\"  =~  [*1*]         ]]\n}\n\n@test \"'ls --sort' retains limit.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first-home.md\"\n# title one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second-home.md\"\n# title two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third-example.md\"\n# title three\nline two\nline three\nline four\nHEREDOC\n\n  \"${_NB}\" set limit 2\n  }\n\n  run \"${_NB}\" ls --sort\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0                     ]]\n\n  [[ \"${#lines[@]}\" -eq 3                     ]]\n  [[ \"${lines[0]}\"  =~  title\\ one            ]]\n  [[ \"${lines[0]}\"  =~  [*1*]                 ]]\n  [[ \"${lines[1]}\"  =~  title\\ two            ]]\n  [[ \"${lines[1]}\"  =~  [*2*]                 ]]\n  [[ \"${lines[2]}\"  ==  \"1 omitted. 3 total.\" ]]\n}\n\n# `ls -a` / `ls --all` ########################################################\n\n_setup_ls_all() {\n  \"${_NB}\" init\n\n  for (( _i=1; _i<31; _i++ ))\n  do\n    cat <<HEREDOC | \"${_NB}\" add \"${_i}.md\"\n# ${_i}\nline two\nline three\nline four\nHEREDOC\n  done\n}\n\n@test \"'ls --2' exits with 0 and lists 2 items.\" {\n  {\n    _setup_ls_all\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls --2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${#lines[@]}\" -eq 5     ]]\n  [[ \"${lines[2]}\"  =~  '30'  ]]\n  [[ \"${lines[3]}\"  =~  '29'  ]]\n}\n\n@test \"'ls' exits with 0 and lists 15 items.\" {\n  {\n    _setup_ls_all\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${#lines[@]}\" -eq 18        ]]\n  [[ \"${lines[2]}\"  =~  '30'      ]]\n  [[ \"${lines[3]}\"  =~  '29'      ]]\n  [[ \"${lines[16]}\" =~  '16'      ]]\n  [[ \"${lines[17]}\" =~  'omitted' ]]\n}\n\n@test \"'ls -a' exits with 0 and lists all items.\" {\n  {\n    _setup_ls_all\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls -a\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${#lines[@]}\" -eq 32    ]]\n  [[ \"${lines[2]}\"  =~  '30'  ]]\n  [[ \"${lines[3]}\"  =~  '29'  ]]\n  [[ \"${lines[21]}\" =~  '11'  ]]\n  [[ \"${lines[22]}\" =~  '10'  ]]\n}\n\n@test \"'ls --all' exits with 0 and lists all items.\" {\n  {\n    _setup_ls_all\n\n    \"${_NB}\" set footer 0\n  }\n\n  run \"${_NB}\" ls --all\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${#lines[@]}\" -eq 32    ]]\n  [[ \"${lines[2]}\"  =~  '30'  ]]\n  [[ \"${lines[3]}\"  =~  '29'  ]]\n  [[ \"${lines[21]}\" =~  '11'  ]]\n  [[ \"${lines[22]}\" =~  '10'  ]]\n}\n\n# `ls <selector>` #############################################################\n\n@test \"'ls <selector>' exits with 0 and displays the selected item.\" {\n  {\n    \"${_NB}\" init\n\n    cat <<HEREDOC | \"${_NB}\" add \"first.md\"\n# one\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second.md\"\n# two\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"third.md\"\n# three\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls 1 --filenames\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${#lines[@]}\" -eq 1         ]]\n  [[ \"${lines[0]}\"  =~  first.md  ]]\n  [[ \"${lines[0]}\"  =~  [*1*]     ]]\n}\n\n@test \"'ls <query selector>' exits with 0 and displays selected items.\" {\n  {\n    _setup_ls\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" ls 'r' --filenames\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -eq 2             ]]\n  [[ \"${lines[0]}\"  =~  third.md      ]]\n  [[ \"${lines[0]}\"  =~  [*3*]         ]]\n  [[ \"${lines[0]}\"  =~  ${_files[2]}  ]]\n  [[ \"${lines[1]}\"  =~  first.md      ]]\n  [[ \"${lines[1]}\"  =~  [*1*]         ]]\n  [[ \"${lines[1]}\"  =~  ${_files[0]}  ]]\n}\n\n@test \"'ls <multi-word selector>' successfully filters list.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# example plum\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# example pluot\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# sample pear\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'fourth.md'\n# sample plum\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls 'example plum' --filenames\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${#lines[@]}\" -eq 1         ]]\n  [[ \"${lines[0]}\"  =~  first.md  ]]\n  [[ \"${lines[0]}\"  =~  [*1*]     ]]\n}\n\n@test \"'ls <multiple> <selectors>' successfully filters list.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# example plum\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# example pluot\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# sample pear\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'fourth.md'\n# sample plum\nline two\nline three\nline four\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\"))\n  }\n\n  run \"${_NB}\" ls example plum --filenames\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0         ]]\n\n  [[ \"${#lines[@]}\" -eq 3         ]]\n  [[ \"${lines[0]}\"  =~  fourth.md ]]\n  [[ \"${lines[0]}\"  =~  [*4*]     ]]\n  [[ \"${lines[1]}\"  =~  second.md ]]\n  [[ \"${lines[1]}\"  =~  [*2*]     ]]\n  [[ \"${lines[2]}\"  =~  first.md  ]]\n  [[ \"${lines[2]}\"  =~  [*1*]     ]]\n}\n\n@test \"'ls <invalid-selector>' exits with 1 and displays a message.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add\n# one\nline two\nline three\nline four\nHEREDOC\n    sleep 1\n  }\n\n  run \"${_NB}\" ls not-valid\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 1             ]]\n\n  [[ \"${#lines[@]}\" -eq 1             ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found\\:  ]]\n  [[ \"${lines[0]}\"  =~  not-valid     ]]\n}\n\n@test \"'ls <notebook>' exits with 0 and runs ls in the notebook.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first-home.md\"\n# one home\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second-home.md\"\n# two home\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" notebooks add example\n    cat <<HEREDOC | \"${_NB}\" example:add \"first-example.md\"\n# one example\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" example:add \"second-example.md\"\n# two example\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls example\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -ge 7             ]]\n  [[ \"${lines[3]}\"  =~  one\\ example  ]]\n  [[ \"${lines[3]}\"  =~  [*1*]         ]]\n}\n\n@test \"'ls <notebook>:' (with colon) exits with 0 and runs ls in the notebook.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first-home.md\"\n# one home\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second-home.md\"\n# two home\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" notebooks add example\n    cat <<HEREDOC | \"${_NB}\" example:add \"first-example.md\"\n# one example\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" example:add \"second-example.md\"\n# two example\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls example:\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -ge 7             ]]\n  [[ \"${lines[3]}\"  =~  one\\ example  ]]\n  [[ \"${lines[3]}\"  =~  [*1*]         ]]\n}\n\n@test \"'ls <notebook> --sort' exits with 0 and runs ls in the notebook.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"first-home.md\"\n# one home\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add \"second-home.md\"\n# two home\nline two\nline three\nline four\nHEREDOC\n    \"${_NB}\" notebooks add example\n    cat <<HEREDOC | \"${_NB}\" example:add \"first-example.md\"\n# one example\nline two\nline three\nline four\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" example:add \"second-example.md\"\n# two example\nline two\nline three\nline four\nHEREDOC\n  }\n\n  run \"${_NB}\" ls example --sort\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${#lines[@]}\" -eq 2             ]]\n  [[ \"${lines[0]}\"  =~  one\\ example  ]]\n  [[ \"${lines[0]}\"  =~  [*1*]         ]]\n}\n"
  },
  {
    "path": "test/move-rename.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_rename() {\n  \"${_NB}\" init\n  \"${_NB}\" add \"initial example name.md\"\n}\n\n# encoding ####################################################################\n\n@test \"'move <target>' with decomposed non-ASCII filename normalizes to precomposed format.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" move 1 \"тестовый.md\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" == 1             ]]\n  [[ \"${_files[0]}\" ==  \"тестовый.md\" ]] # precomposed\n  [[ \"${_files[0]}\" !=  \"тестовый.md\" ]] # decomposed\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ File\\.md.* ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*тестовый\\.md.*               ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*тестовый\\.md.*       ]]\n}\n\n# only extension ##############################################################\n\n@test \"'move .<extension>' with root-level note changes the file extension while retaining the name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\" --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" move 1 .js <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                            ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"     ]]\n  [[    -f \"${NB_DIR}/home/Example File.js\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ File\\.md.* ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Example\\ File\\.js.*          ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*Example\\ File\\.js.*  ]]\n}\n\n# --to <type> #################################################################\n\n@test \"'move --to' with no <type> exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.todo.md\" --content  \"# [ ] Example todo title.\"\n\n    [[    -f \"${NB_DIR}/home/Example File.todo.md\"    ]]\n    [[ !  -e \"${NB_DIR}/home/Example File.js\"         ]]\n  }\n\n  run \"${_NB}\" move 1 --to <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ \"${status}\" -eq 1                                ]]\n\n  # Does not move file:\n\n  [[    -f \"${NB_DIR}/home/Example File.todo.md\"      ]]\n  [[ !  -e \"${NB_DIR}/home/Example File.js\"           ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"             ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${#lines[@]}\" -eq 1                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n!.*\\ .*\\-\\-to.*\\ requires\\ a\\ valid\\ argument\\.       ]]\n}\n\n@test \"'move --to <extension>' (no period) with root-level todo changes the file extension while retaining the name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.todo.md\" --content  \"# [ ] Example todo title.\"\n\n    [[    -f \"${NB_DIR}/home/Example File.todo.md\"    ]]\n    [[ !  -e \"${NB_DIR}/home/Example File.js\"         ]]\n  }\n\n  run \"${_NB}\" move 1 --to js <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                                ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.todo.md\"      ]]\n  [[    -f \"${NB_DIR}/home/Example File.js\"           ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"             ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ File\\.todo\\.md.* ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Example\\ File\\.js.*                ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*Example\\ File\\.js.*        ]]\n}\n\n@test \"'move --to .<extension>' (period) with root-level todo changes the file extension while retaining the name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.todo.md\" --content  \"# [ ] Example todo title.\"\n\n    [[    -f \"${NB_DIR}/home/Example File.todo.md\"    ]]\n    [[ !  -e \"${NB_DIR}/home/Example File.js\"         ]]\n  }\n\n  run \"${_NB}\" move 1 --to .js <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                                ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.todo.md\"      ]]\n  [[    -f \"${NB_DIR}/home/Example File.js\"           ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"             ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ File\\.todo\\.md.* ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Example\\ File\\.js.*                ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*Example\\ File\\.js.*        ]]\n}\n\n@test \"'move --to .<extension>' (period) with nested todo changes the file extension while retaining the name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example Folder/Example File.todo.md\" \\\n      --content  \"# [ ] Example todo title.\"\n\n    [[    -f \"${NB_DIR}/home/Example Folder/Example File.todo.md\" ]]\n    [[ !  -e \"${NB_DIR}/home/Example Folder/Example File.js\"      ]]\n  }\n\n  run \"${_NB}\" move Example\\ Folder/1 --to .js <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ \"${status}\" -eq 0                                            ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example Folder/Example File.todo.md\"   ]]\n  [[    -f \"${NB_DIR}/home/Example Folder/Example File.js\"        ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"                         ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/Example\\ File\\.todo\\.md.* ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Example\\ Folder/Example\\ File\\.js.*                                ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/Example\\ File\\.js.*        ]]\n}\n\n# --to title / --to-title #####################################################\n\n@test \"'move --to title' with brackets in existing filename renames todo.\" {\n  # NOTE: https://github.com/xwmx/nb/issues/292\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add --filename \"[ ] Example Filename.md\" --title \"Example Title\"\n\n\n    _files=($(ls \"${NB_DIR}/home/\"))\n    printf \"\\${_files[0]}: '%s'\\\\n\" \"${_files[0]}\"\n\n    [[    -f \"${NB_DIR}/home/[ ] Example Filename.md\"  ]]\n    [[ !  -f \"${NB_DIR}/home/example_title.md\"         ]]\n  }\n\n  run \"${_NB}\" rename 1 --to title <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                                ]]\n\n  # Moves file:\n\n  [[ !  -f \"${NB_DIR}/home/[ ] Example Filename.md\" ]]\n  [[    -f \"${NB_DIR}/home/example_title.md\"        ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"             ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n#   [[ \"${lines[0]}\" =~ \\\n# Moving:\\ \\ \\ .*[.*2.*].*\\ ✔️\\ \\ .*example_one-1.todo.md.*\\ \\\".*[.*\\ .*].*\\ Example\\ Two\\\"  ]]\n#   [[ \"${lines[1]}\" =~ \\\n# To:\\ \\ \\ \\ \\ \\ \\ .*example_two.todo.md.*                                                  ]]\n#   [[ \"${lines[2]}\" =~ \\\n# Moved\\ to:\\ .*[.*2.*].*\\ .*example_two.todo.md.*\\ \\\".*[.*\\ .*].*\\ Example\\ Two\\\"          ]]\n}\n\n@test \"'move --to title' with duplicated, renamed todo renames title.\" {\n  # NOTE: https://github.com/xwmx/nb/issues/292\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" todo add \"Example One\"\n\n    \"${_NB}\" rename 1 --to-title <<< \"y${_NEWLINE}\"\n\n    [[    -f \"${NB_DIR}/home/example_one.todo.md\"   ]]\n    [[ !  -e \"${NB_DIR}/home/example_one-1.todo.md\" ]]\n    [[ !  -e \"${NB_DIR}/home/example_two.todo.md\"   ]]\n\n    \"${_NB}\" duplicate 1\n\n    [[    -f \"${NB_DIR}/home/example_one.todo.md\"   ]]\n    [[    -f \"${NB_DIR}/home/example_one-1.todo.md\" ]]\n    [[ !  -e \"${NB_DIR}/home/example_two.todo.md\"   ]]\n\n    printf \"# [ ] Example Two\\\\n\" > \"$(\"${_NB}\" show 2 --path)\"\n  }\n\n  run \"${_NB}\" rename 2 --to title <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                                ]]\n\n  # Moves file:\n\n  [[    -f \"${NB_DIR}/home/example_one.todo.md\"     ]]\n  [[ !  -e \"${NB_DIR}/home/example_one-1.todo.md\"   ]]\n  [[    -f \"${NB_DIR}/home/example_two.todo.md\"     ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"             ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*2.*].*\\ ✔️\\ \\ .*example_one-1.todo.md.*\\ \\\".*[.*\\ .*].*\\ Example\\ Two\\\"  ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*example_two.todo.md.*                                                  ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*2.*].*\\ .*example_two.todo.md.*\\ \\\".*[.*\\ .*].*\\ Example\\ Two\\\"          ]]\n}\n\n@test \"'move --to title' with title and root-level bookmark renames to title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.bookmark.md\"                                                \\\n      --title     \"Example Title: A*string•with/a\\\\bunch|of?invalid<filename\\\"characters>\"  \\\n      --content   \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" move 1 --to title <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                                  ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.bookmark.md\"  ]]\n  [[    -f \\\n\"${NB_DIR}/home/example_title__a_string•with_a_bunch_of_invalid_filename_characters_.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"             ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ File\\.bookmark.md.*\\ \\\"Example\\ Title:\\  ]]\n  [[ \"${lines[0]}\" =~ \\\nTitle:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"        ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*example_title__a_string•with_a_bunch_of_invalid_filename_characters_.bookmark.md           ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*example_title__a_string•with_a_bunch_of_invalid_filename_characters_.bookmark.md.* ]]\n  [[ \"${lines[2]}\" =~ \\\n \\\"Example\\ Title:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"          ]]\n}\n\n@test \"'move --to-title' with title and root-level bookmark renames to title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.bookmark.md\"                                                    \\\n      --title     \" [ ] Example Title: A*string•with/a\\\\bunch|of?invalid<filename\\\"characters>\" \\\n      --content   \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" move 1 --to-title <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                                  ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.bookmark.md\"  ]]\n  [[    -f \\\n\"${NB_DIR}/home/example_title__a_string•with_a_bunch_of_invalid_filename_characters_.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"             ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ File\\.bookmark.md.*\\ \\\"\\[\\ \\]\\ Example\\ Title:\\  ]]\n  [[ \"${lines[0]}\" =~ \\\nTitle:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"                ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*example_title__a_string•with_a_bunch_of_invalid_filename_characters_.bookmark.md           ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*example_title__a_string•with_a_bunch_of_invalid_filename_characters_.bookmark.md.* ]]\n  [[ \"${lines[2]}\" =~ \\\n \\\"\\[\\ \\]\\ Example\\ Title:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"  ]]\n}\n\n@test \"'move --to-title' with title and root-level note renames to title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"                                                             \\\n      --title     \" [ ] Example Title: A*string•with/a\\\\bunch|of?invalid<filename\\\"characters>\" \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" move 1 --to-title <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                            ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"     ]]\n  [[    -f \\\n\"${NB_DIR}/home/example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md\"    ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*1.*].*\\ .*Example\\ File\\.md.*\\ \\\"\\[\\ \\]\\ Example\\ Title:\\   ]]\n  [[ \"${lines[0]}\" =~ \\\nTitle:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"        ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md            ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*1.*].*\\ .*example_title__a_string•with_a_bunch_of_invalid_filename_characters_.md.*  ]]\n  [[ \"${lines[2]}\" =~ \\\n \\\"\\[\\ \\]\\ Example\\ Title:\\ A\\*string•with/a\\\\bunch\\|of\\?invalid\\<filename\\\"characters\\>\\\"            ]]\n}\n\n@test \"'move --to-title' prints message with file with no title.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" move 1 --to-title\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1                            ]]\n\n  # Does not move file:\n\n  [[ -e \"${NB_DIR}/home/Example File.md\"        ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Move'\n  git log | grep -q -v '\\[nb\\] Add'\n  git log | grep -q -v '\\[nb\\] Delete'\n\n  # Prints message:\n\n  [[ \"${lines[0]}\" =~ Title\\ not\\ found\\.       ]]\n}\n\n@test \"'move --to-title' prints message with non-text file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/example.pdf\"\n\n    [[ -e \"${NB_DIR}/home/example.pdf\"          ]]\n  }\n\n  run \"${_NB}\" move 1 --to-title\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1                            ]]\n\n  # Does not move file:\n\n  [[ -e \"${NB_DIR}/home/example.pdf\"            ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"       ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Move'\n  git log | grep -q -v '\\[nb\\] Add'\n  git log | grep -q -v '\\[nb\\] Delete'\n\n  # Prints message:\n\n  [[ \"${lines[0]}\" =~ Must\\ be\\ a\\ text\\ file\\. ]]\n}\n\n# --to todo / --to-todo #######################################################\n\n@test \"'move --to todo' with bookmark renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.bookmark.md\" --content \"<https://example.com>\"\n\n    [[ -e \"${NB_DIR}/home/Example File.bookmark.md\"   ]]\n  }\n\n  run \"${_NB}\" move \"Example File.bookmark.md\" --to todo --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.bookmark.md\"  ]]\n  [[    -e \"${NB_DIR}/home/Example File.todo.md\"      ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"Example File.todo.md\"\n\n  [[ \"$(\"${_NB}\" index get_id \"Example File.todo.md\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ Example\\ File.todo.md ]]\n}\n\n@test \"'move --to-todo' with note renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move \"Example File.md\" --to-todo --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"       ]]\n  [[    -e \"${NB_DIR}/home/Example File.todo.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"Example File.todo.md\"\n\n  [[ \"$(\"${_NB}\" index get_id \"Example File.todo.md\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ Example\\ File.todo.md ]]\n}\n\n@test \"'move --to-todo' with bookmark renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.bookmark.md\" --content \"<https://example.com>\"\n\n    [[ -e \"${NB_DIR}/home/Example File.bookmark.md\"   ]]\n  }\n\n  run \"${_NB}\" move \"Example File.bookmark.md\" --to-todo --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.bookmark.md\"  ]]\n  [[    -e \"${NB_DIR}/home/Example File.todo.md\"      ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"Example File.todo.md\"\n\n  [[ \"$(\"${_NB}\" index get_id \"Example File.todo.md\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ Example\\ File.todo.md ]]\n}\n\n# --to bookmark / --to-bookmark ###############################################\n\n@test \"'move --to bookmark' with note renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move \"Example File.md\" --to bookmark --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"          ]]\n  [[    -e \"${NB_DIR}/home/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"Example File.bookmark.md\"\n\n  [[ \"$(\"${_NB}\" index get_id \"Example File.bookmark.md\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                 ]]\n  [[ \"${output}\" =~ Example\\ File.bookmark.md ]]\n}\n\n@test \"'move --to-bookmark' with note renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move \"Example File.md\" --to-bookmark --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"          ]]\n  [[    -e \"${NB_DIR}/home/Example File.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"Example File.bookmark.md\"\n\n  [[ \"$(\"${_NB}\" index get_id \"Example File.bookmark.md\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                 ]]\n  [[ \"${output}\" =~ Example\\ File.bookmark.md ]]\n}\n\n@test \"'move 1 <name> --to-bookmark' with note renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move \"Example File.md\" \"New Name\" --to-bookmark --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"      ]]\n  [[    -e \"${NB_DIR}/home/New Name.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"New Name.bookmark.md\"\n\n  [[ \"$(\"${_NB}\" index get_id \"New Name.bookmark.md\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to               ]]\n  [[ \"${output}\" =~ New\\ Name.bookmark.md   ]]\n}\n\n@test \"'move 1 New\\ Name.demo --to-bookmark' discards extension and renames.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move \"Example File.md\" \"New Name.demo\" --to-bookmark --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"      ]]\n  [[    -e \"${NB_DIR}/home/New Name.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"New Name.bookmark.md\"\n\n  [[ \"$(\"${_NB}\" index get_id \"New Name.bookmark.md\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to               ]]\n  [[ \"${output}\" =~ New\\ Name.bookmark.md   ]]\n}\n\n# --to note / --to-note #######################################################\n\n@test \"'rename --to note' with bookmark renames to updated default extension without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.bookmark.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.bookmark.md\"   ]]\n\n    \"${_NB}\" set default_extension \"org\"\n  }\n\n  run \"${_NB}\" move \"Example File.bookmark.md\" --to note --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.bookmark.md\"  ]]\n  [[    -e \"${NB_DIR}/home/Example File.org\"          ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"Example File.org\"\n\n  [[ \"$(\"${_NB}\" index get_id \"Example File.org\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ Example\\ File.org     ]]\n}\n\n@test \"'rename --to-note' with bookmark renames to updated default extension without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.bookmark.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.bookmark.md\"   ]]\n\n    \"${_NB}\" set default_extension \"org\"\n  }\n\n  run \"${_NB}\" move \"Example File.bookmark.md\" --to-note --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0                      ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.bookmark.md\"  ]]\n  [[    -e \"${NB_DIR}/home/Example File.org\"          ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"Example File.org\"\n\n  [[ \"$(\"${_NB}\" index get_id \"Example File.org\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to         ]]\n  [[ \"${output}\" =~ Example\\ File.org ]]\n}\n\n@test \"'rename --to-note' with bookmark renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.bookmark.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.bookmark.md\"   ]]\n  }\n\n  run \"${_NB}\" move \"Example File.bookmark.md\" --to-note --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.bookmark.md\"  ]]\n  [[    -e \"${NB_DIR}/home/Example File.md\"           ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"Example File.md\"\n\n  [[ \"$(\"${_NB}\" index get_id \"Example File.md\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to         ]]\n  [[ \"${output}\" =~ Example\\ File.md  ]]\n}\n\n# no argument #################################################################\n\n@test \"'move' with no arguments exits with 1, does nothing, and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 1:\n\n  [[ ${status} -eq 1 ]]\n\n  # Does not move file:\n\n  [[ -e \"${NB_DIR}/home/Example File.md\"    ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Move'\n  git log | grep -q -v '\\[nb\\] Add'\n  git log | grep -q -v '\\[nb\\] Delete'\n\n  # Prints help:\n\n  [[ \"${lines[0]}\" =~ Usage.*:  ]]\n  [[ \"${lines[1]}\" =~ nb\\ move  ]]\n}\n\n# <filename> ##################################################################\n\n@test \"'move' with <filename> argument moves without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move \"Example File.md\" \"EXAMPLE NEW NAME.org\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example File.md\"       ]]\n  [[   -e \"${NB_DIR}/home/EXAMPLE NEW NAME.org\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  \"${_NB}\" index show\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.org')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to               ]]\n  [[ \"${output}\" =~ EXAMPLE\\ NEW\\ NAME.org  ]]\n}\n\n@test \"'move' with extension-less <filename> argument uses source extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move \"Example File.md\" \"EXAMPLE NEW NAME\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example File.md\"     ]]\n  [[ ! -e \"${NB_DIR}/home/EXAMPLE\"             ]]\n  [[   -e \"${NB_DIR}/home/EXAMPLE NEW NAME.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ EXAMPLE\\ NEW\\ NAME.md ]]\n}\n\n@test \"'move' bookmark with extension-less <filename> argument uses source extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.bookmark.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" move \"Example File.bookmark.md\" \"EXAMPLE NEW NAME\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Renames file:\n\n  [[ ! -e \"${NB_DIR}/home/Example File.bookmark.md\"      ]]\n  [[   -e \"${NB_DIR}/home/EXAMPLE NEW NAME.bookmark.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.bookmark.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                       ]]\n  [[ \"${output}\" =~ EXAMPLE\\ NEW\\ NAME.bookmark.md  ]]\n}\n\n@test \"'move' bookmark with extension <filename> argument uses target extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.bookmark.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.bookmark.md\" ]]\n  }\n\n  run \"${_NB}\" move \"Example File.bookmark.md\" \"EXAMPLE NEW NAME.md\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.bookmark.md\" ]]\n  [[    -e \"${NB_DIR}/home/EXAMPLE NEW NAME.md\"      ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ EXAMPLE\\ NEW\\ NAME.md ]]\n}\n\n@test \"'move' note with bookmark extension <filename> argument uses target extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" move \"Example File.md\" \"EXAMPLE NEW NAME.bookmark.md\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Renames file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"              ]]\n  [[    -e \"${NB_DIR}/home/EXAMPLE NEW NAME.bookmark.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.bookmark.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                       ]]\n  [[ \"${output}\" =~ EXAMPLE\\ NEW\\ NAME.bookmark.md  ]]\n}\n\n@test \"'move' with existing <filename> exits with status 1.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"          ]]\n\n    \"${_NB}\" add \"EXAMPLE NEW NAME.org\"\n\n    [[ -e \"${NB_DIR}/home/EXAMPLE NEW NAME.org\"     ]]\n  }\n\n  run \"${_NB}\" move \"Example File.md\" \"EXAMPLE NEW NAME.org\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 1                     ]]\n  [[    \"${output}\" =~  'File already exists' ]]\n  [[ -e \"${NB_DIR}/home/EXAMPLE NEW NAME.org\" ]]\n}\n\n# <id> ########################################################################\n\n@test \"'move <id>' with extension-less <filename> argument uses source extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" move 1 \"EXAMPLE NEW NAME\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"      ]]\n  [[    -e \"${NB_DIR}/home/EXAMPLE NEW NAME.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ EXAMPLE\\ NEW\\ NAME.md ]]\n}\n\n@test \"'<id> move' with extension-less <filename> argument uses source extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" 1 move \"EXAMPLE NEW NAME\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File.md\"      ]]\n  [[    -e \"${NB_DIR}/home/EXAMPLE NEW NAME.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ EXAMPLE\\ NEW\\ NAME.md ]]\n}\n\n# <filename> --reset ##########################################################\n\n@test \"'move --reset' with <filename> argument renames without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/home/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" rename \"Example File.md\" --reset --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example File.md\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n  printf \"\\${_files[0]}: '%s'\\\\n\" \"${_files[0]}\"\n\n  [[ \"${_files[0]}\" =~ [A-Za-z0-9]+.md      ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"   ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  cat \"${NB_DIR}/home/.index\"\n\n  \"${_NB}\" index get_id \"${_files[0]}\"\n\n  [[ \"$(\"${_NB}\" index get_id \"${_files[0]}\")\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to       ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.md ]]\n}\n\n# <scope> #####################################################################\n\n@test \"'move <scope>:<id>' with extension-less <filename> argument uses source extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/one/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" move one:1 \"EXAMPLE NEW NAME\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/one/Example File\"         ]]\n  [[    -e \"${NB_DIR}/one/EXAMPLE NEW NAME.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/one/\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                 ]]\n  [[ \"${output}\" =~ one:1                     ]]\n  [[ \"${output}\" =~ one:EXAMPLE\\ NEW\\ NAME.md ]]\n}\n\n@test \"'<scope>:move <id>' with extension-less <filename> argument uses source extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/one/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" one:move 1 \"EXAMPLE NEW NAME\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/one/Example File\"         ]]\n  [[    -e \"${NB_DIR}/one/EXAMPLE NEW NAME.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/one/\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                 ]]\n  [[ \"${output}\" =~ one:EXAMPLE\\ NEW\\ NAME.md ]]\n}\n\n@test \"'<scope>:<id> move' with extension-less <filename> argument uses source extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/one/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" one:1 move \"EXAMPLE NEW NAME\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/one/Example File\"         ]]\n  [[    -e \"${NB_DIR}/one/EXAMPLE NEW NAME.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/one/\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                 ]]\n  [[ \"${output}\" =~ one:EXAMPLE\\ NEW\\ NAME.md ]]\n}\n\n@test \"'<id> <scope>:move' with extension-less <filename> argument uses source extension.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"Example File.md\"\n\n    [[ -e \"${NB_DIR}/one/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" 1 one:move \"EXAMPLE NEW NAME\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/one/Example File\"         ]]\n  [[    -e \"${NB_DIR}/one/EXAMPLE NEW NAME.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/one/\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates index:\n\n  [[ \"$(\"${_NB}\" index get_id 'EXAMPLE NEW NAME.md')\" == '1' ]]\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                 ]]\n  [[ \"${output}\" =~ one:EXAMPLE\\ NEW\\ NAME.md ]]\n}\n\n# help ########################################################################\n\n@test \"'help move' exits with status 0.\" {\n  run \"${_NB}\" help move\n\n  [[ ${status} -eq 0 ]]\n}\n\n@test \"'help move' prints help information.\" {\n  run \"${_NB}\" help move\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Usage.*:  ]]\n  [[ \"${lines[1]}\" =~ nb\\ move  ]]\n}\n"
  },
  {
    "path": "test/move.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# multiple files and globbing #################################################\n\n@test \"'move <id> <id> <id> <notebook-1>:<id> <notebook-2>:<folder>/' with multiple selectors moves files.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" add \"Example File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"Example File Three.md\"  --content \"Example content three.\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample Notebook:Sample File One.md\" --content \"Sample content one.\"\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n\n    \"${_NB}\" add folder \"Demo Notebook:Demo Folder\"\n\n    [[   -f \"${NB_DIR}/home/Example File One.md\"                        ]]\n    [[   -f \"${NB_DIR}/home/Example File Two.md\"                        ]]\n    [[   -f \"${NB_DIR}/home/Example File Three.md\"                      ]]\n    [[   -f \"${NB_DIR}/Sample Notebook/Sample File One.md\"              ]]\n    [[   -d \"${NB_DIR}/Demo Notebook/Demo Folder\"                       ]]\n    [[ ! -e \"${NB_DIR}/Demo Notebook/Demo Folder/Example File One.md\"   ]]\n    [[ ! -e \"${NB_DIR}/Demo Notebook/Demo Folder/Example File Two.md\"   ]]\n    [[ ! -e \"${NB_DIR}/Demo Notebook/Demo Folder/Example File Three.md\" ]]\n    [[ ! -e \"${NB_DIR}/Demo Notebook/Demo Folder/Sample File One.md\"    ]]\n  }\n\n  run \"${_NB}\" move     \\\n    \"1\"                 \\\n    \"2\"                 \\\n    \"3\"                 \\\n    \"Sample Notebook:1\" \\\n    \"Demo Notebook:Demo Folder/\" <<< \"y${_NEWLINE}y${_NEWLINE}y${_NEWLINE}y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves files:\n\n  [[ ! -e \"${NB_DIR}/home/Example File One.md\"                        ]]\n  [[ ! -e \"${NB_DIR}/home/Example File Two.md\"                        ]]\n  [[ ! -e \"${NB_DIR}/home/Example File Three.md\"                      ]]\n  [[ ! -e \"${NB_DIR}/Sample Notebook/Sample File One.md\"              ]]\n  [[   -d \"${NB_DIR}/Demo Notebook/Demo Folder\"                       ]]\n  [[   -f \"${NB_DIR}/Demo Notebook/Demo Folder/Example File One.md\"   ]]\n  [[   -f \"${NB_DIR}/Demo Notebook/Demo Folder/Example File Two.md\"   ]]\n  [[   -f \"${NB_DIR}/Demo Notebook/Demo Folder/Example File Three.md\" ]]\n  [[   -f \"${NB_DIR}/Demo Notebook/Demo Folder/Sample File One.md\"    ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: Example File One.md'\n  git log | grep -q '\\[nb\\] Delete: Example File Two.md'\n  git log | grep -q '\\[nb\\] Delete: Example File Three.md'\n\n  cd \"${NB_DIR}/Sample Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: Sample File One.md'\n\n  cd \"${NB_DIR}/Demo Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Example File One.md'\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Example File Two.md'\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Example File Three.md'\n  git log | grep -q '\\[nb\\] Add: Demo Folder/Sample File One.md'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~    \\\nMoving:\\ \\ \\ .*\\[.*1.*\\].*\\ .*Example\\ File\\ One.md                     ]]\n  [[ \"${lines[1]}\"  =~    \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ One.md    ]]\n  [[ \"${lines[2]}\"  =~    \\\nMoved\\ to:\\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ One.md         ]]\n\n  [[ \"${lines[3]}\"  =~    \\\nMoving:\\ \\ \\ .*\\[.*2.*\\].*\\ .*Example\\ File\\ Two.md                     ]]\n  [[ \"${lines[4]}\"  =~    \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ Two.md    ]]\n  [[ \"${lines[5]}\"  =~    \\\nMoved\\ to:\\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ Two.md         ]]\n\n  [[ \"${lines[6]}\"  =~    \\\nMoving:\\ \\ \\ .*\\[.*3.*\\].*\\ .*Example\\ File\\ Three.md                   ]]\n  [[ \"${lines[7]}\"  =~    \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ Three.md  ]]\n  [[ \"${lines[8]}\"  =~    \\\nMoved\\ to:\\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ Three.md       ]]\n\n  [[ \"${lines[9]}\"  =~    \\\nMoving:\\ \\ \\ .*\\[.*Sample\\ Notebook:1.*\\].*\\ .*Sample\\ File\\ One.md     ]]\n  [[ \"${lines[10]}\"  =~   \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Demo\\ Notebook:Demo\\ Folder/Sample\\ File\\ One.md     ]]\n  [[ \"${lines[11]}\"  =~   \\\nMoved\\ to:\\ .*Demo\\ Notebook:Demo\\ Folder/Sample\\ File\\ One.md          ]]\n}\n\n# TODO\n# @test \"'move * <notebook-1>:<id> <notebook-2>:<folder>/' with multiple selectors moves files.\" {\n#   {\n#     \"${_NB}\" init\n\n#     \"${_NB}\" add \"Example File One.md\"    --content \"Example content one.\"\n#     \"${_NB}\" add \"Example File Two.md\"    --content \"Example content two.\"\n#     \"${_NB}\" add \"Example File Three.md\"  --content \"Example content three.\"\n\n#     \"${_NB}\" notebooks add \"Sample Notebook\"\n\n#     \"${_NB}\" add \"Sample Notebook:Sample File One.md\" --content \"Sample content one.\"\n\n#     \"${_NB}\" notebooks add \"Demo Notebook\"\n\n#     \"${_NB}\" add folder \"Demo Notebook:Demo Folder\"\n\n#     [[   -f \"${NB_DIR}/home/Example File One.md\"                        ]]\n#     [[   -f \"${NB_DIR}/home/Example File Two.md\"                        ]]\n#     [[   -f \"${NB_DIR}/home/Example File Three.md\"                      ]]\n#     [[   -f \"${NB_DIR}/Sample Notebook/Sample File One.md\"              ]]\n#     [[   -d \"${NB_DIR}/Demo Notebook/Demo Folder\"                       ]]\n#     [[ ! -e \"${NB_DIR}/Demo Notebook/Demo Folder/Example File One.md\"   ]]\n#     [[ ! -e \"${NB_DIR}/Demo Notebook/Demo Folder/Example File Two.md\"   ]]\n#     [[ ! -e \"${NB_DIR}/Demo Notebook/Demo Folder/Example File Three.md\" ]]\n#     [[ ! -e \"${NB_DIR}/Demo Notebook/Demo Folder/Sample File One.md\"    ]]\n#   }\n\n#   run \"${_NB}\" move *   \\\n#     \"Sample Notebook:1\" \\\n#     \"Demo Notebook:Demo Folder/\" <<< \"y${_NEWLINE}y${_NEWLINE}y${_NEWLINE}y${_NEWLINE}\"\n\n#   printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n#   printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n#   # Returns status 0:\n\n#   [[ ${status} -eq 0 ]]\n\n#   # Moves files:\n\n#   [[ ! -e \"${NB_DIR}/home/Example File One.md\"                        ]]\n#   [[ ! -e \"${NB_DIR}/home/Example File Two.md\"                        ]]\n#   [[ ! -e \"${NB_DIR}/home/Example File Three.md\"                      ]]\n#   [[ ! -e \"${NB_DIR}/Sample Notebook/Sample File One.md\"              ]]\n#   [[   -d \"${NB_DIR}/Demo Notebook/Demo Folder\"                       ]]\n#   [[   -f \"${NB_DIR}/Demo Notebook/Demo Folder/Example File One.md\"   ]]\n#   [[   -f \"${NB_DIR}/Demo Notebook/Demo Folder/Example File Two.md\"   ]]\n#   [[   -f \"${NB_DIR}/Demo Notebook/Demo Folder/Example File Three.md\" ]]\n#   [[   -f \"${NB_DIR}/Demo Notebook/Demo Folder/Sample File One.md\"    ]]\n\n#   # Creates git commits:\n\n#   cd \"${NB_DIR}/home\" || return 1\n#   while [[ -n \"$(git status --porcelain)\" ]]\n#   do\n#     sleep 1\n#   done\n#   git log\n#   git log | grep -q '\\[nb\\] Delete: Example File One.md'\n#   git log | grep -q '\\[nb\\] Delete: Example File Two.md'\n#   git log | grep -q '\\[nb\\] Delete: Example File Three.md'\n\n#   cd \"${NB_DIR}/Sample Notebook\" || return 1\n#   while [[ -n \"$(git status --porcelain)\" ]]\n#   do\n#     sleep 1\n#   done\n#   git log\n#   git log | grep -q '\\[nb\\] Delete: Sample File One.md'\n\n#   cd \"${NB_DIR}/Demo Notebook\" || return 1\n#   while [[ -n \"$(git status --porcelain)\" ]]\n#   do\n#     sleep 1\n#   done\n#   git log | grep -q '\\[nb\\] Add: Demo Folder/Example File One.md'\n#   git log | grep -q '\\[nb\\] Add: Demo Folder/Example File Two.md'\n#   git log | grep -q '\\[nb\\] Add: Demo Folder/Example File Three.md'\n#   git log | grep -q '\\[nb\\] Add: Demo Folder/Sample File One.md'\n\n#   # Prints output:\n\n#   [[ \"${lines[0]}\"  =~    \\\n# Moving:\\ \\ \\ .*\\[.*1.*\\].*\\ .*Example\\ File\\ One.md                     ]]\n#   [[ \"${lines[1]}\"  =~    \\\n# To:\\ \\ \\ \\ \\ \\ \\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ One.md    ]]\n#   [[ \"${lines[2]}\"  =~    \\\n# Moved\\ to:\\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ One.md         ]]\n\n#   [[ \"${lines[3]}\"  =~    \\\n# Moving:\\ \\ \\ .*\\[.*2.*\\].*\\ .*Example\\ File\\ Two.md                     ]]\n#   [[ \"${lines[4]}\"  =~    \\\n# To:\\ \\ \\ \\ \\ \\ \\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ Two.md    ]]\n#   [[ \"${lines[5]}\"  =~    \\\n# Moved\\ to:\\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ Two.md         ]]\n\n#   [[ \"${lines[6]}\"  =~    \\\n# Moving:\\ \\ \\ .*\\[.*3.*\\].*\\ .*Example\\ File\\ Three.md                   ]]\n#   [[ \"${lines[7]}\"  =~    \\\n# To:\\ \\ \\ \\ \\ \\ \\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ Three.md  ]]\n#   [[ \"${lines[8]}\"  =~    \\\n# Moved\\ to:\\ .*Demo\\ Notebook:Demo\\ Folder/Example\\ File\\ Three.md       ]]\n\n#   [[ \"${lines[9]}\"  =~    \\\n# Moving:\\ \\ \\ .*\\[.*Sample\\ Notebook:1.*\\].*\\ .*Sample\\ File\\ One.md     ]]\n#   [[ \"${lines[10]}\"  =~   \\\n# To:\\ \\ \\ \\ \\ \\ \\ .*Demo\\ Notebook:Demo\\ Folder/Sample\\ File\\ One.md     ]]\n#   [[ \"${lines[11]}\"  =~   \\\n# Moved\\ to:\\ .*Demo\\ Notebook:Demo\\ Folder/Sample\\ File\\ One.md          ]]\n# }\n\n# argument ordering ###########################################################\n\n@test \"'move <folder>/<id> <notebook>:<folder>/' moves file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n\n    \"${_NB}\" add folder \"Sample Notebook:Sample Folder\"\n\n    [[   -f \"${NB_DIR}/home/Example Folder/Example File.md\"           ]]\n    [[   -d \"${NB_DIR}/Sample Notebook/Sample Folder\"                 ]]\n    [[ ! -e \"${NB_DIR}/Sample Notebook/Sample Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" move \"Example Folder/1\" \"Sample Notebook:Sample Folder/\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.md\"             ]]\n  [[   -f \"${NB_DIR}/Sample Notebook/Sample Folder/Example File.md\"   ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete'\n\n  cd \"${NB_DIR}/Sample Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  \\\nMoving:\\ \\ \\ .*\\[.*Example\\ Folder/1.*\\].*\\ .*Example\\ File.md      ]]\n  [[ \"${lines[1]}\"  =~  \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Sample\\ Notebook:Sample\\ Folder/Example\\ File.md ]]\n  [[ \"${lines[2]}\"  =~  \\\nMoved\\ to:\\ .*Sample\\ Notebook:Sample\\ Folder/Example\\ File.md      ]]\n}\n\n@test \"'<folder>/<id> move <notebook>:<folder>/' moves file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n\n    \"${_NB}\" add folder \"Sample Notebook:Sample Folder\"\n\n    [[   -f \"${NB_DIR}/home/Example Folder/Example File.md\"           ]]\n    [[   -d \"${NB_DIR}/Sample Notebook/Sample Folder\"                 ]]\n    [[ ! -e \"${NB_DIR}/Sample Notebook/Sample Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" \"Example Folder/1\" move \"Sample Notebook:Sample Folder/\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.md\"             ]]\n  [[   -f \"${NB_DIR}/Sample Notebook/Sample Folder/Example File.md\"   ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete'\n\n  cd \"${NB_DIR}/Sample Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  \\\nMoving:\\ \\ \\ .*\\[.*Example\\ Folder/1.*\\].*\\ .*Example\\ File.md      ]]\n  [[ \"${lines[1]}\"  =~  \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Sample\\ Notebook:Sample\\ Folder/Example\\ File.md ]]\n  [[ \"${lines[2]}\"  =~  \\\nMoved\\ to:\\ .*Sample\\ Notebook:Sample\\ Folder/Example\\ File.md      ]]\n}\n\n@test \"'<folder>/<id> <notebook>:<folder>/ move' moves file.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n\n    \"${_NB}\" add folder \"Sample Notebook:Sample Folder\"\n\n    [[   -f \"${NB_DIR}/home/Example Folder/Example File.md\"           ]]\n    [[   -d \"${NB_DIR}/Sample Notebook/Sample Folder\"                 ]]\n    [[ ! -e \"${NB_DIR}/Sample Notebook/Sample Folder/Example File.md\" ]]\n  }\n\n  run \"${_NB}\" \"Example Folder/1\" \"Sample Notebook:Sample Folder/\" move <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.md\"             ]]\n  [[   -f \"${NB_DIR}/Sample Notebook/Sample Folder/Example File.md\"   ]]\n\n  # Creates git commits:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete'\n\n  cd \"${NB_DIR}/Sample Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Prints output:\n\n  [[ \"${lines[0]}\"  =~  \\\nMoving:\\ \\ \\ .*\\[.*Example\\ Folder/1.*\\].*\\ .*Example\\ File.md      ]]\n  [[ \"${lines[1]}\"  =~  \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Sample\\ Notebook:Sample\\ Folder/Example\\ File.md ]]\n  [[ \"${lines[2]}\"  =~  \\\nMoved\\ to:\\ .*Sample\\ Notebook:Sample\\ Folder/Example\\ File.md      ]]\n}\n\n# pinning #####################################################################\n\n@test \"'move' with pinned item and other notebook destination retains pinning in new notebook.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" add \"Example File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"Example File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" add \"Example File Four.md\"   --content \"Example content four.\"\n    \"${_NB}\" add \"Example File Five.md\"   --content \"Example content five.\"\n\n    \"${_NB}\" pin 2\n    \"${_NB}\" pin 4\n\n    [[ -e \"${NB_DIR}/home/Example File Two.md\"    ]]\n\n    diff                                          \\\n      <(cat \"${NB_DIR}/home/.pindex\")             \\\n      <(printf \"Example File Two.md\\\\nExample File Four.md\\\\n\")\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File One.md\"     --content \"Sample content one.\"\n    \"${_NB}\" add \"Sample File Two.md\"     --content \"Sample content two.\"\n    \"${_NB}\" add \"Sample File Three.md\"   --content \"Sample content three.\"\n    \"${_NB}\" add \"Sample File Four.md\"    --content \"Sample content four.\"\n\n    \"${_NB}\" pin 3\n\n    diff                                          \\\n      <(cat \"${NB_DIR}/Sample Notebook/.pindex\")  \\\n      <(printf \"Sample File Three.md\\\\n\")\n\n    \"${_NB}\" notebooks use \"home\"\n  }\n\n  run \"${_NB}\" move \"Example File Two.md\" \"Sample Notebook:\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File Two.md\"             ]]\n  [[    -e \"${NB_DIR}/Sample Notebook/Example File Two.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete: Example File Two.md'\n\n  cd \"${NB_DIR}/Sample Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add: Example File Two.md'\n\n  # Updates .pindexes:\n\n  diff                              \\\n    <(cat \"${NB_DIR}/home/.pindex\") \\\n    <(printf \"Example File Four.md\\\\n\")\n\n  diff                                          \\\n    <(cat \"${NB_DIR}/Sample Notebook/.pindex\")  \\\n    <(printf \"Sample File Three.md\\\\nExample File Two.md\\\\n\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*2.*].*\\ .*File\\ Two\\.md                           ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Sample\\ Notebook:Example\\ File\\ Two\\.md          ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*Sample\\ Notebook:5.*].*\\ .*Example\\ File\\ Two.md   ]]\n}\n\n@test \"'move' with pinned item and other folder destination retains pinning in new folder.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" add \"Example File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"Example File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" add \"Example File Four.md\"   --content \"Example content four.\"\n    \"${_NB}\" add \"Example File Five.md\"   --content \"Example content five.\"\n\n    \"${_NB}\" pin 2\n    \"${_NB}\" pin 4\n\n    [[ -e \"${NB_DIR}/home/Example File Two.md\"  ]]\n\n    diff                                        \\\n      <(cat \"${NB_DIR}/home/.pindex\")           \\\n      <(printf \"Example File Two.md\\\\nExample File Four.md\\\\n\")\n\n    \"${_NB}\" add folder \"Sample Folder\"\n\n    \"${_NB}\" add \"Sample Folder/Sample File One.md\"     --content \"Sample content one.\"\n    \"${_NB}\" add \"Sample Folder/Sample File Two.md\"     --content \"Sample content two.\"\n    \"${_NB}\" add \"Sample Folder/Sample File Three.md\"   --content \"Sample content three.\"\n    \"${_NB}\" add \"Sample Folder/Sample File Four.md\"    --content \"Sample content four.\"\n\n    \"${_NB}\" pin Sample\\ Folder/3\n\n    diff                                            \\\n      <(cat \"${NB_DIR}/home/Sample Folder/.pindex\") \\\n      <(printf \"Sample File Three.md\\\\n\")\n  }\n\n  run \"${_NB}\" move \"Example File Two.md\" \"Sample Folder/\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/Example File Two.md\"               ]]\n  [[    -e \"${NB_DIR}/home/Sample Folder/Example File Two.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates .pindexes:\n\n  diff                              \\\n    <(cat \"${NB_DIR}/home/.pindex\") \\\n    <(printf \"Example File Four.md\\\\n\")\n\n  diff                                            \\\n    <(cat \"${NB_DIR}/home/Sample Folder/.pindex\") \\\n    <(printf \"Sample File Three.md\\\\nExample File Two.md\\\\n\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ \\\nMoving:\\ \\ \\ .*[.*2.*].*\\ .*File\\ Two\\.md                                       ]]\n  [[ \"${lines[1]}\" =~ \\\nTo:\\ \\ \\ \\ \\ \\ \\ .*Sample\\ Folder/Example\\ File\\ Two\\.md                        ]]\n  [[ \"${lines[2]}\" =~ \\\nMoved\\ to:\\ .*[.*Sample\\ Folder/5.*].*\\ .*Sample\\ Folder/Example\\ File\\ Two.md  ]]\n}\n\n@test \"'move' with pinned item and same folder destination updates .pindex while retaining order.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Example content four.\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Example content five.\"\n\n    \"${_NB}\" pin 2\n    \"${_NB}\" pin 4\n\n    [[ -e \"${NB_DIR}/home/File Two.md\"  ]]\n\n    diff                                \\\n      <(cat \"${NB_DIR}/home/.pindex\")   \\\n      <(printf \"File Two.md\\\\nFile Four.md\\\\n\")\n  }\n\n  run \"${_NB}\" move \"File Two.md\" \"Example File Two.md\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ !  -e \"${NB_DIR}/home/File Two.md\"         ]]\n  [[    -e \"${NB_DIR}/home/Example File Two.md\" ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Move'\n\n  # Updates .pindex:\n\n  diff                              \\\n    <(cat \"${NB_DIR}/home/.pindex\") \\\n    <(printf \"Example File Two.md\\\\nFile Four.md\\\\n\")\n\n  # Prints output:\n\n  [[ \"${lines[0]}\" =~ Moving:\\ \\ \\ .*[.*2.*].*\\ .*File\\ Two\\.md         ]]\n  [[ \"${lines[1]}\" =~ To:\\ \\ \\ \\ \\ \\ \\ .*Example\\ File\\ Two\\.md         ]]\n  [[ \"${lines[2]}\" =~ Moved\\ to:\\ .*[.*2.*].*\\ .*Example\\ File\\ Two.md  ]]\n}\n\n# prompt ######################################################################\n\n@test \"'move' with non-affirmative prompt response exits without moving note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  run \"${_NB}\" move 1 destination: <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0                          ]]\n\n  # Does not file:\n\n  [[    -e \"${NB_DIR}/home/example.md\"        ]]\n  [[ !  -e \"${NB_DIR}/destination/example.md\" ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\"     ]]\n  do\n    sleep 1\n  done\n  git log | grep -v -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moving                    ]]\n  [[ \"${output}\" =~ Exiting.*\\.\\.\\.           ]]\n}\n\n# no argument #################################################################\n\n@test \"'move' with no arguments exits with status 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n  }\n\n  run \"${_NB}\" move\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with 1:\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # Does not delete file:\n\n  [[ -e \"${NB_DIR}/home/example.md\" ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Delete'\n\n  # Prints help:\n\n  [[ \"${lines[0]}\" =~ Usage.*\\: ]]\n  [[ \"${lines[1]}\" =~ nb\\ move  ]]\n}\n\n@test \"'move --force' with no arguments exits with status 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n  }\n\n  run \"${_NB}\" move --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with 1:\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # Does not delete file:\n\n  [[ -e \"${NB_DIR}/home/example.md\" ]]\n\n  # Does not create git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q -v '\\[nb\\] Delete'\n\n  # Prints help:\n\n  [[ \"${lines[0]}\" =~ Usage.*\\: ]]\n  [[ \"${lines[1]}\" =~ nb\\ move  ]]\n}\n\n# <selector> ##################################################################\n\n@test \"'move <selector> <notebook>:' with empty repo exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" move 1 destination:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1              ]]\n  [[ \"${lines[0]}\" =~ Not\\ found  ]]\n  [[ \"${lines[0]}\" =~ 1           ]]\n\n}\n\n@test \"'move <invalid> <notebook>:' exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n  }\n\n  run \"${_NB}\" move \"invalid\" destination: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1              ]]\n  [[ \"${lines[0]}\" =~ Not\\ found  ]]\n  [[ \"${lines[0]}\" =~ invalid     ]]\n\n}\n\n@test \"'move <selector> <invalid>:' exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n  }\n\n  run \"${_NB}\" move 1 invalid: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                                ]]\n  [[ \"${lines[0]}\" =~ Target\\ notebook\\ not\\ found  ]]\n  [[ \"${lines[0]}\" =~ invalid                       ]]\n}\n\n@test \"'move <selector> <notebook>: (no force)' returns 0 and moves note.\" {\n  skip \"Determine how to test interactive prompt.\"\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n\n    [[ -e \"${NB_DIR}/home/example.md\" ]]\n  }\n\n  run \"${_NB}\" move \"example.md\" destination:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ ! -e \"${NB_DIR}/home/example.md\" ]]\n}\n\n# <notebook>:<selector> #######################################################\n\n@test \"'move <notebook>:<filename> <notebook>:' with <filename> argument moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"example.md\" --content \"Example content.\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" move one:example.md home: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0              ]]\n  [[ \"${output}\" =~ Moved\\ to       ]]\n  [[ \"${output}\" =~ home:1          ]]\n  [[ \"${output}\" =~ home:example.md ]]\n}\n\n@test \"'<notebook>:move <filename> <notebook>:' with <filename> argument moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n    \"${_NB}\" add\n\n    _filename=$(\"${_NB}\" list -n 1 --no-id --filenames | head -1)\n\n    echo \"\\${_filename:-}: ${_filename:-}\"\n\n    \"${_NB}\" use \"home\"\n\n    [[ -n \"${_filename}\"                ]]\n    [[ -e \"${NB_DIR}/one/${_filename}\"  ]]\n  }\n\n  run \"${_NB}\" one:move \"${_filename}\" home: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                    ]]\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ home:[A-Za-z0-9]*     ]]\n  [[ \"${output}\" =~ home:[A-Za-z0-9]+.md  ]]\n}\n\n@test \"'<notebook>:<filename> move <notebook>:' with <filename> argument moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n\n    \"${_NB}\" use \"home\"\n\n    [[    -e \"${NB_DIR}/one/example.md\"   ]]\n    [[ !  -e \"${NB_DIR}/home/example.md\"  ]]\n  }\n\n  run \"${_NB}\" one:example.md move home: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                    ]]\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ home:example.md       ]]\n\n  [[ !  -e \"${NB_DIR}/one/example.md\"     ]]\n  [[    -e \"${NB_DIR}/home/example.md\"    ]]\n\n}\n\n@test \"'<filename> <notebook>:move <notebook>:' with <filename> argument moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" use \"one\"\n    \"${_NB}\" add\n\n    _filename=$(\"${_NB}\" list -n 1 --no-id --filenames | head -1)\n\n    echo \"\\${_filename:-}: ${_filename:-}\"\n\n    \"${_NB}\" use \"home\"\n\n    [[ -n \"${_filename}\"                ]]\n    [[ -e \"${NB_DIR}/one/${_filename}\"  ]]\n  }\n\n  run \"${_NB}\" \"${_filename}\" one:move home: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                    ]]\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ home:[A-Za-z0-9]*     ]]\n  [[ \"${output}\" =~ home:[A-Za-z0-9]+.md  ]]\n}\n\n# <filename> ##################################################################\n\n@test \"'move' with <filename> argument successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n  }\n\n  run \"${_NB}\" move \"example.md\" destination: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"       ]]\n  [[ -e \"${NB_DIR}/destination/example.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to               ]]\n  [[ \"${output}\" =~ destination:1           ]]\n  [[ \"${output}\" =~ destination:example.md  ]]\n}\n\n# <id> ########################################################################\n\n@test \"'move' with <id> argument successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  run \"${_NB}\" move 1 destination: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"       ]]\n  [[ -e \"${NB_DIR}/destination/example.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to               ]]\n  [[ \"${output}\" =~ destination:1           ]]\n  [[ \"${output}\" =~ destination:example.md  ]]\n}\n\n@test \"'<id> move' successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n  }\n\n  run \"${_NB}\" 1 move destination: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"       ]]\n  [[ -e \"${NB_DIR}/destination/example.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                   ]]\n  [[ \"${output}\" =~ destination:[A-Za-z0-9]*    ]]\n  [[ \"${output}\" =~ destination:[A-Za-z0-9]+.md ]]\n}\n\n@test \"'move' with <id> argument and trailing colon on destination successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n  }\n\n  run \"${_NB}\" move 1 destination: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"       ]]\n  [[ -e \"${NB_DIR}/destination/example.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to               ]]\n  [[ \"${output}\" =~ destination:1           ]]\n  [[ \"${output}\" =~ destination:example.md  ]]\n}\n\n# <path> ######################################################################\n\n@test \"'move' with <path> argument successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n  }\n\n  run \"${_NB}\" move \"${NB_DIR}/home/example.md\" destination: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"       ]]\n  [[ -e \"${NB_DIR}/destination/example.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to               ]]\n  [[ \"${output}\" =~ destination:1           ]]\n  [[ \"${output}\" =~ destination:example.md  ]]\n}\n\n# <title> #####################################################################\n\n@test \"'move' with <title> argument successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add --title \"Example Title\" --filename \"example.md\"\n    \"${_NB}\" notebooks add \"destination\"\n  }\n\n  run \"${_NB}\" move \"Example Title\" destination: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"       ]]\n  [[ -e \"${NB_DIR}/destination/example.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to               ]]\n  [[ \"${output}\" =~ destination:1           ]]\n  [[ \"${output}\" =~ destination:example.md  ]]\n}\n\n# <folder> ####################################################################\n\n@test \"'move' with <folder> argument successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"destination\"\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\"\n\n    [[ -d \"${NB_DIR}/home/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" move \"Example Folder\" destination: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves folder:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder\"       ]]\n  [[ -e \"${NB_DIR}/destination/Example Folder\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to                   ]]\n  [[ \"${output}\" =~ destination:1               ]]\n  [[ \"${output}\" =~ destination:Example\\ Folder ]]\n}\n\n# local #######################################################################\n\n@test \"'move' to local with <filename> argument successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n\n    [[ -e \"${NB_DIR}/home/example.md\" ]]\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n  }\n\n  run \"${_NB}\" move \"home:example.md\" local: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ ! -e \"${NB_DIR}/home/example.md\"           ]]\n  [[ -e \"${_TMP_DIR}/example-local/example.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to         ]]\n  [[ \"${output}\" =~ local:1           ]]\n  [[ \"${output}\" =~ local:example.md  ]]\n}\n\n@test \"'move' from local with <filename> argument successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n\n    \"${_NB}\" add \"local-example.md\" --content \"local example content\"\n  }\n\n  run \"${_NB}\" move \"local-example.md\" home: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ -e \"${NB_DIR}/home/local-example.md\"               ]]\n  [[ ! -e \"${_TMP_DIR}/example-local/local-example.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${_TMP_DIR}/example-local\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ home:2                ]]\n  [[ \"${output}\" =~ home:local-example.md ]]\n}\n\n@test \"'move' from local with local:<filename> argument successfully moves note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example content.\"\n    \"${_NB}\" notebooks add \"destination\"\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n\n    \"${_NB}\" add \"local-example.md\" --content \"local example content\"\n  }\n\n  run \"${_NB}\" move \"local:local-example.md\" home: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Exits with status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Moves file:\n\n  [[ -e \"${NB_DIR}/home/local-example.md\"               ]]\n  [[ ! -e \"${_TMP_DIR}/example-local/local-example.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${_TMP_DIR}/example-local\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Moved\\ to             ]]\n  [[ \"${output}\" =~ home:2                ]]\n  [[ \"${output}\" =~ home:local-example.md ]]\n}\n\n# help ########################################################################\n\n@test \"'help move' exits with status 0.\" {\n  run \"${_NB}\" help move\n\n  [[ ${status} -eq 0 ]]\n}\n\n@test \"'help move' prints help information.\" {\n  run \"${_NB}\" help move\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Usage.*\\: ]]\n  [[ \"${lines[1]}\" =~ nb\\ move  ]]\n}\n"
  },
  {
    "path": "test/notebook-resolution.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031\n\nload test_helper\n\n# edge cases ##################################################################\n\n@test \"'nb' resolves current notebook to other existing notebook when home is deleted.\" {\n  {\n    _setup_remote_repo\n\n    [[ ! -e \"${NB_DIR}\" ]]\n  }\n\n  # initialize with first run\n\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"Welcome.*to\"\n\n  [[    -d \"${NB_DIR}/home\"         ]]\n  [[ !  -d \"${NB_DIR}/Notebook One\" ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"^NB_NOTEBOOK_PATH=${NB_DIR}/home$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_LOCAL_NOTEBOOK_PATH=$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_GLOBAL_NOTEBOOK_PATH=${NB_DIR}/home$\"\n\n  [[    -d \"${NB_DIR}/home\"         ]]\n  [[ !  -d \"${NB_DIR}/Notebook One\" ]]\n\n  # create new notebook\n\n  run \"${_NB}\" notebooks add \"Notebook One\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"Added notebook:.*Notebook One\"\n\n  [[    -d \"${NB_DIR}/home\"         ]]\n  [[    -d \"${NB_DIR}/Notebook One\" ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"^NB_NOTEBOOK_PATH=${NB_DIR}/home$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_LOCAL_NOTEBOOK_PATH=$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_GLOBAL_NOTEBOOK_PATH=${NB_DIR}/home$\"\n\n  [[    -d \"${NB_DIR}/home\"         ]]\n  [[    -d \"${NB_DIR}/Notebook One\" ]]\n\n  # delete home notebook\n\n  run \"${_NB}\" delete home <<< \"home\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -E \"Deleting|Trash\"\n\n  [[ !  -d \"${NB_DIR}/home\"         ]]\n  [[    -d \"${NB_DIR}/Notebook One\" ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"^NB_NOTEBOOK_PATH=${NB_DIR}/Notebook One$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_LOCAL_NOTEBOOK_PATH=$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_GLOBAL_NOTEBOOK_PATH=${NB_DIR}/Notebook One$\"\n\n  [[ !  -d \"${NB_DIR}/home\"         ]]\n  [[    -d \"${NB_DIR}/Notebook One\" ]]\n}\n\n@test \"'nb' resolves current notebook to blank when home is deleted and no other notebooks exist.\" {\n  {\n    _setup_remote_repo\n\n    [[ ! -e \"${NB_DIR}\" ]]\n  }\n\n  # initialize with first run\n\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"Welcome.*to\"\n\n  [[ -d \"${NB_DIR}/home\" ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"^NB_NOTEBOOK_PATH=${NB_DIR}/home$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_LOCAL_NOTEBOOK_PATH=$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_GLOBAL_NOTEBOOK_PATH=${NB_DIR}/home$\"\n\n  [[ -d \"${NB_DIR}/home\" ]]\n\n  # delete home notebook\n\n  run \"${_NB}\" delete home <<< \"home\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -E \"Deleting|Trash\"\n\n  [[ ! -d \"${NB_DIR}/home\" ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"^NB_NOTEBOOK_PATH=$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_LOCAL_NOTEBOOK_PATH=$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_GLOBAL_NOTEBOOK_PATH=$\"\n\n  [[ ! -d \"${NB_DIR}/home\" ]]\n}\n\n# notebook resolution #########################################################\n\n@test \"'nb' resolves current notebook.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Notebook One\"\n    \"${_NB}\" notebooks add \"Notebook Two\"\n\n    [[ -d \"${NB_DIR}/home\"          ]]\n    [[ -d \"${NB_DIR}/Notebook One\"  ]]\n    [[ -d \"${NB_DIR}/Notebook Two\"  ]]\n  }\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"^NB_NOTEBOOK_PATH=${NB_DIR}/home$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_LOCAL_NOTEBOOK_PATH=$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_GLOBAL_NOTEBOOK_PATH=${NB_DIR}/home$\"\n}\n\n@test \"'nb' resolves current notebook to value in NB_DIR/.current.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Notebook One\"\n    \"${_NB}\" notebooks add \"Notebook Two\"\n\n    [[ -d \"${NB_DIR}/home\"          ]]\n    [[ -d \"${NB_DIR}/Notebook One\"  ]]\n    [[ -d \"${NB_DIR}/Notebook Two\"  ]]\n\n    printf \"Notebook One\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"^NB_NOTEBOOK_PATH=${NB_DIR}/Notebook One$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_LOCAL_NOTEBOOK_PATH=$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_GLOBAL_NOTEBOOK_PATH=${NB_DIR}/Notebook One$\"\n}\n\n@test \"'NB_NOTEBOOK_DIR=<notebook> nb' overrides value in NB_DIR/.current.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Notebook One\"\n    \"${_NB}\" notebooks add \"Notebook Two\"\n\n    [[ -d \"${NB_DIR}/home\"          ]]\n    [[ -d \"${NB_DIR}/Notebook One\"  ]]\n    [[ -d \"${NB_DIR}/Notebook Two\"  ]]\n\n    printf \"Notebook One\" > \"${NB_DIR}/.current\"\n  }\n\n  NB_NOTEBOOK_PATH=\"${NB_DIR}/Notebook Two\" run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"^NB_NOTEBOOK_PATH=${NB_DIR}/Notebook Two$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_LOCAL_NOTEBOOK_PATH=$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_GLOBAL_NOTEBOOK_PATH=${NB_DIR}/Notebook Two$\"\n}\n\n@test \"'nb' resolves to local notebook when present.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Notebook One\"\n    \"${_NB}\" notebooks add \"Notebook Two\"\n\n    [[ -d \"${NB_DIR}/home\"          ]]\n    [[ -d \"${NB_DIR}/Notebook One\"  ]]\n    [[ -d \"${NB_DIR}/Notebook Two\"  ]]\n\n    printf \"Notebook One\" > \"${NB_DIR}/.current\"\n\n    mkdir -p \"${_TMP_DIR}/Local Notebook\"\n    cd \"${_TMP_DIR}/Local Notebook\"\n\n    \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" env | grep \"^_CURRENT_WORKING_DIR=${_TMP_DIR}/Local Notebook$\"\n  }\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep \"^NB_NOTEBOOK_PATH=${_TMP_DIR}/Local Notebook$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_LOCAL_NOTEBOOK_PATH=${_TMP_DIR}/Local Notebook$\"\n  printf \"%s\\\\n\" \"${output}\" | grep \"^_GLOBAL_NOTEBOOK_PATH=${NB_DIR}/Notebook One\"\n}\n"
  },
  {
    "path": "test/notebooks-add.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebooks() {\n  \"${_NB}\" init\n\n  mkdir -p \"${NB_DIR}/one\"\n  cd \"${NB_DIR}/one\" || return 1\n  git init\n  git remote add origin \"${_GIT_REMOTE_URL}\"\n  touch \"${NB_DIR}/one/.index\"\n\n  mkdir -p \"${NB_DIR}/two\"\n\n  cd \"${NB_DIR}\" || return 1\n}\n\n# errors ######################################################################\n\n@test \"'notebooks add' with no <name>, <remote-url>, or <branch> exits with 1 and prints help.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n  }\n\n  run \"${_NB}\" notebooks add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"File Count: '%s'\\\\n\" \\\n    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\"\n  printf \"%s\\\\n\" \"$(cd \"${NB_DIR}\" && find . -maxdepth 1)\"\n\n  [[ \"${status}\"    -eq 1                                     ]]\n  [[ \"${lines[0]}\"  =~  Usage.*:                              ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ notebooks\\                    ]]\n  [[ \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 6  ]]\n}\n\n# remote ######################################################################\n\n@test \"'notebooks add <remote-url> --all' with no existing notebooks matching branch names exits with 0 and adds notebooks for all branches.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    printf \"Example File One.md created.\\\\n\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n    \"${_NB}\" git branch -m \"sample-branch\"\n\n    \"${_NB}\" add \"Sample File One.md\" --content \"Sample content one.\"\n\n    printf \"Sample File One.md created.\\\\n\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote  \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\nsample-branch\\\\n\")\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n    \"${_NB}\" git branch -m \"demo-branch\"\n\n    \"${_NB}\" add \"Demo File One.md\" --content \"Demo content one.\"\n\n    printf \"Demo File One.md created.\\\\n\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote    \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"demo-branch\\\\nexample-branch\\\\nmaster\\\\nsample-branch\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" --all \\\n    <<< \"${_NEWLINE}${_NEWLINE}${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[1]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/demo-branch\\'      ]]\n  [[    \"${lines[2]}\"   =~  Added\\ notebook\\:\\ .*demo-branch.*            ]]\n  [[    \"${lines[3]}\"   =~  [^-]------------------------------------[^-]  ]]\n  [[    \"${lines[4]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[5]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/example-branch\\'   ]]\n  [[    \"${lines[6]}\"   =~  Added\\ notebook\\:\\ .*example-branch.*         ]]\n  [[    \"${lines[7]}\"   =~  [^-]------------------------------------[^-]  ]]\n  [[    \"${lines[8]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[9]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/remote\\'           ]]\n  [[    \"${lines[10]}\"  =~  Added\\ notebook\\:\\ .*remote.*                 ]]\n  [[    \"${lines[11]}\"  =~  [^-]------------------------------------[^-]  ]]\n  [[    \"${lines[12]}\"  =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[13]}\"  =~  Cloning\\ into\\ \\'${NB_DIR}/sample-branch\\'    ]]\n  [[    \"${lines[14]}\"  =~  Added\\ notebook\\:\\ .*sample-branch.*          ]]\n\n\n  cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l\n  cd \"${NB_DIR}\" && find . -maxdepth 1\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 13      ]]\n  [[ -d \"${NB_DIR}/example-branch/.git\"                               ]]\n  [[ -f \"${NB_DIR}/example-branch/Example File One.md\"                ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"example-branch\\\\n\")\n\n  cd \"${NB_DIR}/demo-branch\"\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ demo-branch               ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/demo-branch    ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n\n  cd \"${NB_DIR}/example-branch\"\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n\n  cd \"${NB_DIR}/remote\"\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ master                    ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/master         ]]\n\n  cd \"${NB_DIR}/sample-branch\"\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ sample-branch             ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/sample-branch  ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n}\n\n@test \"'notebooks add <remote-url> <branch-1> <nonexistent-branch-2>' with existing <branch-1> notebook exits with 0 and adds notebook named <branch-1>.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    printf \"Example File One.md created.\\\\n\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n    \"${_NB}\" git branch -m \"sample-branch\"\n\n    \"${_NB}\" add \"Sample File One.md\" --content \"Sample content one.\"\n\n    printf \"Sample File One.md created.\\\\n\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote  \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\nsample-branch\\\\n\")\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n    \"${_NB}\" git branch -m \"demo-branch\"\n\n    \"${_NB}\" add \"Demo File One.md\" --content \"Demo content one.\"\n\n    printf \"Demo File One.md created.\\\\n\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote    \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"demo-branch\\\\nexample-branch\\\\nmaster\\\\nsample-branch\\\\n\")\n\n    \"${_NB}\" notebooks add \"example-branch\"\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" \\\n     \"nonexistent-branch\" \"example-branch\" <<< \"${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[1]}\"   =~  \\\nCloning\\ into\\ \\'${NB_DIR}/nonexistent-branch\\'                               ]]\n  [[    \"${lines[2]}\"   =~  \\\nfatal:\\ Remote\\ branch\\ nonexistent\\-branch\\ not\\ found\\ in\\ upstream\\ origin ]]\n  [[    \"${lines[3]}\"   =~  [^-]------------------------------------[^-]      ]]\n  [[    \"${lines[4]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[5]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/example-branch-1\\'     ]]\n  [[    \"${lines[6]}\"   =~  Added\\ notebook\\:\\ .*example-branch-1.*           ]]\n\n  cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l\n  cd \"${NB_DIR}\" && find . -maxdepth 1\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 11      ]]\n  [[ -d \"${NB_DIR}/example-branch-1/.git\"                             ]]\n  [[ -f \"${NB_DIR}/example-branch-1/Example File One.md\"              ]]\n\n  diff                                                                        \\\n    <(cd \"${NB_DIR}/example-branch-1\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                        \\\n    <(cd \"${NB_DIR}/example-branch-1\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"example-branch\\\\n\")\n\n  cd \"${NB_DIR}/example-branch-1\"\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n\n  [[ ! -e \"${NB_DIR}/sample-branch\"       ]]\n  [[ ! -e \"${NB_DIR}/nonexistent-branch\"  ]]\n}\n\n@test \"'notebooks add <remote-url> <branch-1> <branch-2>' with no existing notebooks with those names exits with 0 and adds notebook named <branch-1> and <branch-2>.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    printf \"Example File One.md created.\\\\n\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n    \"${_NB}\" git branch -m \"sample-branch\"\n\n    \"${_NB}\" add \"Sample File One.md\" --content \"Sample content one.\"\n\n    printf \"Sample File One.md created.\\\\n\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote  \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\nsample-branch\\\\n\")\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n    \"${_NB}\" git branch -m \"demo-branch\"\n\n    \"${_NB}\" add \"Demo File One.md\" --content \"Demo content one.\"\n\n    printf \"Demo File One.md created.\\\\n\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote    \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"demo-branch\\\\nexample-branch\\\\nmaster\\\\nsample-branch\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" \\\n    \"example-branch\" \"demo-branch\" <<< \"${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                           ]]\n\n  [[    \"${lines[0]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[1]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/example-branch\\'     ]]\n  [[    \"${lines[2]}\"   =~  Added\\ notebook\\:\\ .*example-branch.*           ]]\n  [[    \"${lines[3]}\"   =~  [^-]------------------------------------[^-]    ]]\n  [[    \"${lines[4]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[5]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/demo-branch\\'        ]]\n  [[    \"${lines[6]}\"   =~  Added\\ notebook\\:\\ .*demo-branch.*              ]]\n\n  cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l\n  cd \"${NB_DIR}\" && find . -maxdepth 1\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 11      ]]\n  [[ -d \"${NB_DIR}/example-branch/.git\"                               ]]\n  [[ -f \"${NB_DIR}/example-branch/Example File One.md\"                ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"example-branch\\\\n\")\n\n  cd \"${NB_DIR}/example-branch\"\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n\n  [[ ! -e \"${NB_DIR}/sample-branch\" ]]\n\n  cd \"${NB_DIR}/demo-branch\"\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ demo-branch               ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/demo-branch    ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n}\n\n@test \"'notebooks add <remote-url> <branch>' with reserved notebook name as branch name exits with a and prints message.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"readme\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"master\\\\nreadme\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" \"readme\" <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 1                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[1]}\"   =~  !.*\\ Name\\ reserved:\\ .*readme.*    ]]\n\n  [[ ! -e \"${NB_DIR}/readme\"                                    ]]\n}\n\n@test \"'notebooks add <remote-url> <branch>' with no existing notebook with that name exits with 0 and adds a notebook named <branch>.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" \"example-branch\" <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[1]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/example-branch\\'     ]]\n  [[    \"${lines[2]}\"   =~  Added\\ notebook\\:\\ .*example-branch.*           ]]\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 8 ]]\n  [[ -d \"${NB_DIR}/example-branch/.git\"                         ]]\n  [[ -f \"${NB_DIR}/example-branch/Example File One.md\"          ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"example-branch\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n}\n\n@test \"'notebooks add <name> <remote-url> <branch>' exits with 0 and adds a notebook.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add example \"${_GIT_REMOTE_URL}\" \"example-branch\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                     ]]\n  [[    \"${lines[1]}\" =~  Added\\ notebook\\:                     ]]\n  [[    \"${lines[1]}\" =~  example                               ]]\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 8 ]]\n  [[ -d \"${NB_DIR}/example/.git\"                                ]]\n  [[ -f \"${NB_DIR}/example/Example File One.md\"                 ]]\n\n  diff                                                              \\\n    <(cd \"${NB_DIR}/example\" && git config --get remote.origin.url) \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                              \\\n    <(cd \"${NB_DIR}/example\" && git rev-parse --abbrev-ref HEAD)    \\\n    <(printf \"example-branch\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n}\n\n@test \"'notebooks add <name> <remote-url>' exits with 0 and adds a notebook.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"Sample Notebook\" \"${_GIT_REMOTE_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  cd \"${NB_DIR}\" && find . -maxdepth 1\n\n  [[    \"${status}\"   -eq 0                                     ]]\n  [[    \"${lines[1]}\" =~  Added\\ notebook\\:                     ]]\n  [[    \"${lines[1]}\" =~  Sample\\ Notebook                      ]]\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 8 ]]\n  [[ -d \"${NB_DIR}/Sample Notebook/.git\"                        ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/Sample Notebook\" && git config --get remote.origin.url) \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/Sample Notebook\" && git rev-parse --abbrev-ref HEAD)    \\\n    <(printf \"master\\\\n\")\n\n  diff                                            \\\n    <(\"${_NB}\" Sample\\ Notebook:git branch --all) \\\n    <(cat <<HEREDOC\n* master\n  remotes/origin/HEAD -> origin/master\n  remotes/origin/master\nHEREDOC\n    )\n}\n\n@test \"'notebooks add <remote-url>' with multiple remote branches prompts for branch with 'All' response and notebook names with default response, and creates notebooks from branches.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    diff                          \\\n      <(\"${_NB}\" git branch -a)   \\\n      <(printf \"* example-branch\\\\n\")\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    \"${_NB}\" git status\n    \"${_NB}\" run ls -la\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\"     \\\n    <<< \"3${_NEWLINE}${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\"   =~  Choose\\ a\\ remote\\ branch\\:                     ]]\n  [[    \"${lines[1]}\"   =~  [^-]-----------------------[^-]                 ]]\n  [[    \"${lines[2]}\"   =~  .*[.*1.*].*\\ example-branch                     ]]\n  [[    \"${lines[3]}\"   =~  .*[.*2.*].*\\ master                             ]]\n  [[    \"${lines[4]}\"   =~  .*[.*3.*].*\\ All\\ Branches                      ]]\n  [[    \"${lines[5]}\"   =~  [^-]------------------------------------[^-]    ]]\n  [[    \"${lines[6]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[7]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/example-branch\\'     ]]\n  [[    \"${lines[8]}\"   =~  Added\\ notebook\\:\\ .*example-branch.*           ]]\n  [[    \"${lines[9]}\"   =~  [^-]------------------------------------[^-]    ]]\n  [[    \"${lines[10]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[11]}\"  =~  Cloning\\ into\\ \\'${NB_DIR}/remote\\'             ]]\n  [[    \"${lines[12]}\"  =~  Added\\ notebook\\:\\ .*remote.*                   ]]\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 9             ]]\n  [[ -d \"${NB_DIR}/example-branch/.git\"                                     ]]\n  [[ -d \"${NB_DIR}/remote/.git\"                                             ]]\n\n  ls -la \"${NB_DIR}/example-branch\"\n\n  [[ -f \"${NB_DIR}/example-branch/Example File One.md\"                      ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"example-branch\\\\n\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/remote\" && git config --get remote.origin.url)          \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/remote\" && git rev-parse --abbrev-ref HEAD)             \\\n    <(printf \"master\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch              ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch   ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                     ]]\n\n  \"${_NB}\" use remote\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ master                      ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/master           ]]\n}\n\n@test \"'notebooks add <remote-url>' with multiple remote branches prompts for branch with 'All' response and notebook names with alpha response, and creates notebooks from branches.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    diff                          \\\n      <(\"${_NB}\" git branch -a)   \\\n      <(printf \"* example-branch\\\\n\")\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    \"${_NB}\" git status\n    \"${_NB}\" run ls -la\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\"     \\\n    <<< \"3${_NEWLINE}sample-notebook${_NEWLINE}demo-notebook${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\"   =~  Choose\\ a\\ remote\\ branch\\:                     ]]\n  [[    \"${lines[1]}\"   =~  [^-]-----------------------[^-]                 ]]\n  [[    \"${lines[2]}\"   =~  .*[.*1.*].*\\ example-branch                     ]]\n  [[    \"${lines[3]}\"   =~  .*[.*2.*].*\\ master                             ]]\n  [[    \"${lines[4]}\"   =~  .*[.*3.*].*\\ All\\ Branches                      ]]\n  [[    \"${lines[5]}\"   =~  [^-]------------------------------------[^-]    ]]\n  [[    \"${lines[6]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[7]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/sample-notebook\\'    ]]\n  [[    \"${lines[8]}\"   =~  Added\\ notebook\\:\\ .*sample-notebook.*          ]]\n  [[    \"${lines[9]}\"   =~  [^-]------------------------------------[^-]    ]]\n  [[    \"${lines[10]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[11]}\"  =~  Cloning\\ into\\ \\'${NB_DIR}/demo-notebook\\'      ]]\n  [[    \"${lines[12]}\"  =~  Added\\ notebook\\:\\ .*demo-notebook.*            ]]\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 9             ]]\n  [[ -d \"${NB_DIR}/sample-notebook/.git\"                                    ]]\n  [[ -d \"${NB_DIR}/demo-notebook/.git\"                                      ]]\n\n  ls -la \"${NB_DIR}/sample-notebook\"\n\n  [[ -f \"${NB_DIR}/sample-notebook/Example File One.md\"                     ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/sample-notebook\" && git config --get remote.origin.url) \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/sample-notebook\" && git rev-parse --abbrev-ref HEAD)    \\\n    <(printf \"example-branch\\\\n\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/demo-notebook\" && git config --get remote.origin.url)   \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/demo-notebook\" && git rev-parse --abbrev-ref HEAD)      \\\n    <(printf \"master\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch              ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch   ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                     ]]\n\n  \"${_NB}\" use demo-notebook\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ master                      ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/master           ]]\n}\n\n@test \"'notebooks add <remote-url>' with multiple remote branches prompts for branch with numerical response and notebook name with alpha response, and creates notebook from branch.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    diff                          \\\n      <(\"${_NB}\" git branch -a)   \\\n      <(printf \"* example-branch\\\\n\")\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    \"${_NB}\" git status\n    \"${_NB}\" run ls -la\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" <<< \"1${_NEWLINE}sample-notebook${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\" =~  Choose\\ a\\ remote\\ branch\\:                   ]]\n  [[    \"${lines[1]}\" =~  [^-]-----------------------[^-]               ]]\n  [[    \"${lines[2]}\" =~  .*[.*1.*].*\\ example-branch                   ]]\n  [[    \"${lines[3]}\" =~  .*[.*2.*].*\\ master                           ]]\n  [[    \"${lines[4]}\" =~  .*[.*3.*].*\\ All\\ Branches                    ]]\n  [[    \"${lines[5]}\" =~  [^-]------------------------------------[^-]  ]]\n  [[    \"${lines[6]}\" =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[7]}\" =~  Cloning\\ into\\ \\'${NB_DIR}/sample-notebook\\'  ]]\n  [[    \"${lines[8]}\" =~  Added\\ notebook\\:\\ .*sample-notebook.*        ]]\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 8         ]]\n  [[ -d \"${NB_DIR}/sample-notebook/.git\"                                ]]\n\n  ls -la \"${NB_DIR}/sample-notebook\"\n\n  [[ -f \"${NB_DIR}/sample-notebook/Example File One.md\"                 ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/sample-notebook\" && git config --get remote.origin.url) \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/sample-notebook\" && git rev-parse --abbrev-ref HEAD)    \\\n    <(printf \"example-branch\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n}\n\n@test \"'notebooks add <remote-url>' with multiple remote branches prompts for branch with alpha / branch name response and notebook name with <enter> response, and creates notebook from branch.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    diff                          \\\n      <(\"${_NB}\" git branch -a)   \\\n      <(printf \"* example-branch\\\\n\")\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    \"${_NB}\" git status\n    \"${_NB}\" run ls -la\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" <<< \"example-branch${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\" =~  Choose\\ a\\ remote\\ branch\\:                   ]]\n  [[    \"${lines[1]}\" =~  [^-]-----------------------[^-]               ]]\n  [[    \"${lines[2]}\" =~  .*[.*1.*].*\\ example-branch                   ]]\n  [[    \"${lines[3]}\" =~  .*[.*2.*].*\\ master                           ]]\n  [[    \"${lines[4]}\" =~  .*[.*3.*].*\\ All\\ Branches                    ]]\n  [[    \"${lines[5]}\" =~  [^-]------------------------------------[^-]  ]]\n  [[    \"${lines[6]}\" =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[7]}\" =~  Cloning\\ into\\ \\'${NB_DIR}/example-branch\\'   ]]\n  [[    \"${lines[8]}\" =~  Added\\ notebook\\:\\ .*example-branch.*         ]]\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 8         ]]\n  [[ -d \"${NB_DIR}/example-branch/.git\"                                 ]]\n\n  ls -la \"${NB_DIR}/example-branch\"\n\n  [[ -f \"${NB_DIR}/example-branch/Example File One.md\"                  ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"example-branch\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n}\n\n@test \"'notebooks add <remote-url>' with multiple remote branches prompts for branch with numeric response and notebook name with <enter> response, and creates notebook from branch.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    diff                          \\\n      <(\"${_NB}\" git branch -a)   \\\n      <(printf \"* example-branch\\\\n\")\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    \"${_NB}\" git status\n    \"${_NB}\" run ls -la\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" <<< \"1${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\" =~  Choose\\ a\\ remote\\ branch\\:                   ]]\n  [[    \"${lines[1]}\" =~  [^-]-----------------------[^-]               ]]\n  [[    \"${lines[2]}\" =~  .*[.*1.*].*\\ example-branch                   ]]\n  [[    \"${lines[3]}\" =~  .*[.*2.*].*\\ master                           ]]\n  [[    \"${lines[4]}\" =~  .*[.*3.*].*\\ All\\ Branches                    ]]\n  [[    \"${lines[5]}\" =~  [^-]------------------------------------[^-]  ]]\n  [[    \"${lines[6]}\" =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[7]}\" =~  Cloning\\ into\\ \\'${NB_DIR}/example-branch\\'   ]]\n  [[    \"${lines[8]}\" =~  Added\\ notebook\\:\\ .*example-branch.*         ]]\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 8         ]]\n  [[ -d \"${NB_DIR}/example-branch/.git\"                                 ]]\n\n  ls -la \"${NB_DIR}/example-branch\"\n\n  [[ -f \"${NB_DIR}/example-branch/Example File One.md\"                  ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"example-branch\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n}\n\n@test \"'notebooks add <remote-url>' with one remote branch with uncommon default branch name uses repository name as notebook name.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" git branch -m  \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    _sed_i \"s/master/example-branch/\" \"${_GIT_REMOTE_PATH}/HEAD\"\n\n    \"${_NB}\" git push origin :master\n\n    diff                                  \\\n      <(git -C \"${NB_DIR}/home\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"    \\\n          | sed \"s/.*\\///g\" || :)         \\\n      <(printf \"example-branch\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[1]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/example-branch\\'   ]]\n  [[    \"${lines[2]}\"   =~  Added\\ notebook\\:\\ .*example-branch.*         ]]\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 7           ]]\n  [[ -d \"${NB_DIR}/example-branch/.git\"                                   ]]\n  [[ -f \"${NB_DIR}/example-branch/Example File One.md\"                    ]]\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                      \\\n    <(cd \"${NB_DIR}/example-branch\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"example-branch\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n}\n\n@test \"'notebooks add <remote-url>' with one remote branch with common default branch name uses repository name as notebook name.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                  \\\n      <(git -C \"${NB_DIR}/home\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"    \\\n          | sed \"s/.*\\///g\" || :)         \\\n      <(printf \"master\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks add \"${_GIT_REMOTE_URL}\" <<< \"${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n\n  [[    \"${lines[0]}\"   =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\. ]]\n  [[    \"${lines[1]}\"   =~  Cloning\\ into\\ \\'${NB_DIR}/remote\\'   ]]\n  [[    \"${lines[2]}\"   =~  Added\\ notebook\\:\\ .*remote.*         ]]\n\n  [[    \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 7   ]]\n  [[ -d \"${NB_DIR}/remote/.git\"                                   ]]\n  [[ -f \"${NB_DIR}/remote/Example File One.md\"                    ]]\n\n  diff                                                              \\\n    <(cd \"${NB_DIR}/remote\" && git config --get remote.origin.url)  \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                              \\\n    <(cd \"${NB_DIR}/remote\" && git rev-parse --abbrev-ref HEAD)     \\\n    <(printf \"master\\\\n\")\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ master            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/master ]]\n}\n\n# config ######################################################################\n\n@test \"'notebooks add --author' displays config prompt and sets email and name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Home File.md\" --content \"Example home content.\"\n\n    declare _global_email=\n    _global_email=\"$(git -C \"${NB_DIR}/home\" config --global --includes user.email)\"\n\n    declare _global_name=\n    _global_name=\"$(git -C \"${NB_DIR}/home\" config --global --includes user.name)\"\n\n    diff                                            \\\n      <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n      <(printf \"Author: %s <%s>\\\\n\" \"${_global_name}\" \"${_global_email}\")\n  }\n\n  run \"${_NB}\" notebooks add \"Example Notebook\" --author \\\n    <<< \"y${_NEWLINE}local@example.test${_NEWLINE}Example Local Name${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 11  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.email  || :)\"  ]]\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.name   || :)\"  ]]\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  [[ \"${lines[4]}\"  =~ \\\nEnter\\ a\\ new\\ value,\\ .*unset.*\\ to\\ use\\ the\\ global\\ value,                ]]\n  [[ \"${lines[5]}\"  =~ or\\ leave\\ blank\\ to\\ keep\\ the\\ current\\ value\\.      ]]\n\n  [[ \"${lines[6]}\"  =~ Updated\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[7]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[8]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[9]}\"  =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  [[ \"${lines[10]}\" =~ Added\\ notebook:\\ .*Example\\ Notebook                  ]]\n\n  \"${_NB}\" notebooks use \"Example Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n# --email and --name ##########################################################\n\n@test \"'notebooks add --email <email> --name <name>' sets the local email and name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Home File.md\" --content \"Example home content.\"\n\n    declare _global_email=\n    _global_email=\"$(git -C \"${NB_DIR}/home\" config --global --includes user.email)\"\n\n    declare _global_name=\n    _global_name=\"$(git -C \"${NB_DIR}/home\" config --global --includes user.name)\"\n\n    diff                                            \\\n      <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n      <(printf \"Author: %s <%s>\\\\n\" \"${_global_name}\" \"${_global_email}\")\n  }\n\n  run \"${_NB}\" notebooks add \"Example Notebook\"     \\\n    --email \"local@example.test\"                    \\\n    --name  \"Example Local Name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 13  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.name   || :)\" ]]\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[7]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[8]}\"  =~ Updated\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" notebooks use \"Example Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n@test \"'notebooks add --email <email>' sets the local email.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Home File.md\" --content \"Example home content.\"\n\n    declare _global_email=\n    _global_email=\"$(git -C \"${NB_DIR}/home\" config --global --includes user.email)\"\n\n    declare _global_name=\n    _global_name=\"$(git -C \"${NB_DIR}/home\" config --global --includes user.name)\"\n\n    diff                                            \\\n      <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n      <(printf \"Author: %s <%s>\\\\n\" \"${_global_name}\" \"${_global_email}\")\n  }\n\n  run \"${_NB}\"  notebooks add \"Example Notebook\"    \\\n    --email \"local@example.test\"                    \\\n    <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.name   || :)\" ]]\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[7]}\"  =~ Updated\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[8]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[9]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[10]}\" =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  [[ \"${lines[11]}\" =~ Added\\ notebook:\\ .*Example\\ Notebook                  ]]\n\n  \"${_NB}\" notebooks use \"Example Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: %s <local@example.test>\\\\n\" \"${_global_name}\")\n}\n\n@test \"'notebooks add --name <name>' sets the local name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Home File.md\" --content \"Example home content.\"\n\n    declare _global_email=\n    _global_email=\"$(git -C \"${NB_DIR}/home\" config --global --includes user.email)\"\n\n    declare _global_name=\n    _global_name=\"$(git -C \"${NB_DIR}/home\" config --global --includes user.name)\"\n\n    diff                                            \\\n      <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n      <(printf \"Author: %s <%s>\\\\n\" \"${_global_name}\" \"${_global_email}\")\n  }\n\n  run \"${_NB}\" notebooks add \"Example Notebook\"     \\\n    --name \"Example Local Name\"                     \\\n    <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.name   || :)\" ]]\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[7]}\"  =~ Updated\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[8]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[9]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[10]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  [[ \"${lines[11]}\" =~ Added\\ notebook:\\ .*Example\\ Notebook                  ]]\n\n  \"${_NB}\" notebooks use \"Example Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <%s>\\\\n\" \"${_global_email}\")\n}\n\n# <name> validation ###########################################################\n\n@test \"'notebooks add <reserved>' exits with 1 and prints error message.\" {\n  {\n    \"${_NB}\" init\n\n    _names=(\n      \".cache\"\n      \".current\"\n      \".plugins\"\n      \".readme\"\n      \"readme\"\n      \"readme.md\"\n    )\n  }\n\n  for __name in \"${_names[@]}\"\n  do\n    run \"${_NB}\" notebooks add \"${__name}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"    -eq 1               ]]\n    [[ \"${lines[0]}\"  =~  Name\\ reserved  ]]\n    [[ \"${lines[0]}\"  =~  ${__name}       ]]\n  done\n}\n\n# `notebooks add <name>` ######################################################\n\n@test \"'notebooks add <existing>' exits with 1 and prints error message.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks add one\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                     ]]\n  [[ \"${lines[0]}\"  =~  Already\\ exists                       ]]\n  [[ \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 6  ]]\n}\n\n@test \"'notebooks add <name>' exits with 0 and adds a notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks add example\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${lines[0]}\"  =~  Added\\ notebook\\:                     ]]\n  [[ \"${lines[0]}\"  =~  example                               ]]\n  [[ \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 7  ]]\n}\n\n@test \"'notebooks add <name>' creates git commit.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks add example\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf                                          \\\n    \"\\$(ls -la \\\"${NB_DIR}/example/\\\"): '%s'\\\\n\"  \\\n    \"$(ls -la \"${NB_DIR}/example/\")\"\n\n  [[ ${status} -eq 0 ]]\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git -C \"${NB_DIR}/example\" log)\"\n\n  while [[ -n \"$(git -C \"${NB_DIR}/example\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/example\" log | grep -q '\\[nb\\] Initialize'\n}\n\n@test \"'notebooks a <name>' exits with 0 and adds a notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks a example\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                       ]]\n  [[ \"${output}\"  =~  Added                                   ]]\n  [[ \"${output}\"  =~  example                                 ]]\n  [[ \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 7  ]]\n}\n\n@test \"'notebooks create <name>' exits with 0 and adds a notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks add example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                       ]]\n  [[ \"${output}\"  =~  Added                                   ]]\n  [[ \"${output}\"  =~  example                                 ]]\n  [[ \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 7  ]]\n}\n\n@test \"'notebooks new <name>' exits with 0 and adds a notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks add example\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                       ]]\n  [[ \"${output}\"  =~  Added                                   ]]\n  [[ \"${output}\"  =~  example                                 ]]\n  [[ \"$(cd \"${NB_DIR}\" && find . -maxdepth 1 | wc -l)\" -eq 7  ]]\n}\n"
  },
  {
    "path": "test/notebooks-author.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# prompt ######################################################################\n\n@test \"'notebooks author' with non-affirmative prompt response prints message and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks author --name \"Example Local Name\" <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 8   ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[7]}\"  =~ Exiting.*...                                           ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: %s <%s>\\\\n\" \"${_global_name}\" \"${_global_email}\")\n}\n\n# selectors ###################################################################\n\n@test \"'notebooks author <notebook-name>: --email <email> --name <name>' updates the local email and name in <notebook-path>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" notebooks author   \\\n    \"Example Notebook:\"           \\\n    --email \"local@example.test\"  \\\n    --name  \"Example Local Name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/Example Notebook\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/Example Notebook\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[7]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[8]}\"  =~ Updated\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" notebooks use \"Example Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n@test \"'notebooks author <notebook-name> --email <email> --name <name>' updates the local email and name in <notebook-path>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" notebooks author   \\\n    \"Example Notebook\"            \\\n    --email \"local@example.test\"  \\\n    --name  \"Example Local Name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/Example Notebook\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/Example Notebook\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[7]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[8]}\"  =~ Updated\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" notebooks use \"Example Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n@test \"'notebooks author <notebook-path> --email <email> --name <name>' updates the local email and name in <notebook-path>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" notebooks author   \\\n    \"${NB_DIR}/Example Notebook\"  \\\n    --email \"local@example.test\"  \\\n    --name  \"Example Local Name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/Example Notebook\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/Example Notebook\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[7]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[8]}\"  =~ Updated\\ author\\ for:\\ .*Example\\ Notebook             ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" notebooks use \"Example Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n# notebooks author email and name prompts #####################################\n\n@test \"'notebooks author' prompts update the local email and name.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks author \\\n    <<< \"y${_NEWLINE}local@example.test${_NEWLINE}Example Local Name${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 10  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  [[ \"${lines[4]}\"  =~ \\\nEnter\\ a\\ new\\ value,\\ .*unset.*\\ to\\ use\\ the\\ global\\ value,                ]]\n  [[ \"${lines[5]}\"  =~ or\\ leave\\ blank\\ to\\ keep\\ the\\ current\\ value\\.      ]]\n\n  [[ \"${lines[6]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[7]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[8]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[9]}\"  =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n@test \"'notebooks author' prompts update the local email.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks author \\\n    <<< \"y${_NEWLINE}local@example.test${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 10  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  [[ \"${lines[4]}\"  =~ \\\nEnter\\ a\\ new\\ value,\\ .*unset.*\\ to\\ use\\ the\\ global\\ value,                ]]\n  [[ \"${lines[5]}\"  =~ or\\ leave\\ blank\\ to\\ keep\\ the\\ current\\ value\\.      ]]\n\n  [[ \"${lines[6]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[7]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[8]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[9]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: %s <local@example.test>\\\\n\" \"${_global_name}\")\n}\n\n@test \"'notebooks author' prompts update the local name.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks author \\\n    <<< \"y${_NEWLINE}${_NEWLINE}Example Local Name${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 10  ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  [[ \"${lines[4]}\"  =~ \\\nEnter\\ a\\ new\\ value,\\ .*unset.*\\ to\\ use\\ the\\ global\\ value,                ]]\n  [[ \"${lines[5]}\"  =~ or\\ leave\\ blank\\ to\\ keep\\ the\\ current\\ value\\.      ]]\n\n  [[ \"${lines[6]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[7]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[8]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[9]}\"  =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <%s>\\\\n\" \"${_global_email}\")\n}\n\n# notebooks author --email and --name #########################################\n\n@test \"'notebooks author --email <email> --name <name>' updates the local email and name.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks author   \\\n    --email \"local@example.test\"  \\\n    --name  \"Example Local Name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[7]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[8]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n@test \"'notebooks author --email <email>' updates the local email.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks author --email \"local@example.test\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 11  ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[7]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[8]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[9]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[10]}\" =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: %s <local@example.test>\\\\n\" \"${_global_name}\")\n}\n\n@test \"'notebooks author --name <name>' updates the local name.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks author --name \"Example Local Name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 11  ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[7]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[8]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[9]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[10]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <%s>\\\\n\" \"${_global_email}\")\n}\n\n# notebooks author --unset ####################################################\n\n@test \"'notebooks author --unset --email' unsets only email and prints global values.\" {\n  {\n    \"${_NB}\" init\n\n    git -C \"${NB_DIR}/home\" config --local user.email \"local@example.test\"\n    git -C \"${NB_DIR}/home\" config --local user.name  \"Example Local Name\"\n  }\n\n  run \"${_NB}\" notebooks author --unset --email\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  [[ \"${lines[0]}\"  =~ Unsetting\\ local\\ email\\.                              ]]\n  [[ \"${lines[1]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[2]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[3]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[4]}\"  =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n}\n\n@test \"'notebooks author --unset --name' unsets only name and prints global values.\" {\n  {\n    \"${_NB}\" init\n\n    git -C \"${NB_DIR}/home\" config --local user.email \"local@example.test\"\n    git -C \"${NB_DIR}/home\" config --local user.name  \"Example Local Name\"\n  }\n\n  run \"${_NB}\" notebooks author --unset --name\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ -n \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Unsetting\\ local\\ name\\.                               ]]\n  [[ \"${lines[1]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[2]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[3]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[4]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n}\n\n@test \"'notebooks author --unset' with local email unsets and prints global values.\" {\n  {\n    \"${_NB}\" init\n\n    git -C \"${NB_DIR}/home\" config --local user.email  \"local@example.test\"\n  }\n\n  run \"${_NB}\" notebooks author --unset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Unsetting\\ local\\ email\\.                              ]]\n  [[ \"${lines[1]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[2]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[3]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[4]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n}\n\n@test \"'notebooks author --unset' with local name unsets and prints global values.\" {\n  {\n    \"${_NB}\" init\n\n    git -C \"${NB_DIR}/home\" config --local user.name  \"Example Local Name\"\n  }\n\n  run \"${_NB}\" notebooks author --unset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 5 ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Unsetting\\ local\\ name\\.                               ]]\n  [[ \"${lines[1]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[2]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[3]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[4]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n}\n\n@test \"'notebooks author --unset' with full local author unsets and prints global values.\" {\n  {\n    \"${_NB}\" init\n\n    git -C \"${NB_DIR}/home\" config --local user.email \"local@example.test\"\n    git -C \"${NB_DIR}/home\" config --local user.name  \"Example Local Name\"\n  }\n\n  run \"${_NB}\" notebooks author --unset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 6 ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Unsetting\\ local\\ email\\.                              ]]\n  [[ \"${lines[1]}\"  =~ Unsetting\\ local\\ name\\.                               ]]\n  [[ \"${lines[2]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[3]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[4]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[5]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n}\n\n@test \"'notebooks author --unset' with no local author prints global values.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks author --unset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 4 ]]\n\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${NB_DIR}/home\" config --local user.name   || :)\" ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Updated\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n}\n\n# notebooks author ############################################################\n\n@test \"'notebooks author' with local email prints local value with global name.\" {\n  {\n    \"${_NB}\" init\n\n    git -C \"${NB_DIR}/home\" config --local user.email  \"local@example.test\"\n  }\n\n  run \"${_NB}\" notebooks author --skip-prompt\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 4 ]]\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n}\n\n@test \"'notebooks author' with local name prints local value with global email.\" {\n  {\n    \"${_NB}\" init\n\n    git -C \"${NB_DIR}/home\" config --local user.name  \"Example Local Name\"\n  }\n\n  run \"${_NB}\" notebooks author --skip-prompt\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 4 ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n}\n\n@test \"'notebooks author' with full local author prints local values.\" {\n  {\n    \"${_NB}\" init\n\n    git -C \"${NB_DIR}/home\" config --local user.email \"local@example.test\"\n    git -C \"${NB_DIR}/home\" config --local user.name  \"Example Local Name\"\n  }\n\n  run \"${_NB}\" notebooks author --skip-prompt\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 4 ]]\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n}\n\n@test \"'notebooks author' with no local author prints global values.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks author --skip-prompt\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 4 ]]\n\n  declare _global_email=\n  _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n  declare _global_name=\n  _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n}\n"
  },
  {
    "path": "test/notebooks-current.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebooks() {\n  \"${_NB}\" init\n  \"${_NB}\" notebooks add one\n\n  cd \"${NB_DIR}\" || return 1\n}\n\n# `notebooks current` #########################################################\n\n@test \"'notebooks current' exits with 0 and prints the current notebook name.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0    ]]\n  [[ \"${output}\" =~ one ]]\n}\n\n@test \"'notebooks current --path' exits with 0 and prints the notebook path.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${output}\" =~ ${NB_DIR}/one ]]\n}\n\n@test \"'notebooks current' exits with 0 and prints the local notebook.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n  }\n\n  run \"${_NB}\" notebooks current\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0      ]]\n  [[ \"${output}\" =~ local ]]\n}\n\n@test \"'notebooks current --path' exits with 0 and prints the local notebook path.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n  }\n\n  run \"${_NB}\" notebooks current --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_TMP_DIR}: '%s'\\\\n\" \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0                    ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example ]]\n}\n\n@test \"'notebooks current' exits with 0 and prints the scoped notebook name.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" home:notebooks current\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0      ]]\n  [[ \"${output}\" =~ home  ]]\n}\n\n@test \"'notebooks current --path' exits with 0 and prints the scoped notebook path.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" home:notebooks current --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ \"${output}\" == \"${NB_DIR}/home\"  ]]\n}\n\n@test \"'notebooks current --path' exits with 0 and prints the selected notebook path with name.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current home --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ \"${output}\" == \"${NB_DIR}/home\"  ]]\n}\n\n@test \"'notebooks current --path' exits with 0 and prints the selected notebook path with colon name.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current home: --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ \"${output}\" == \"${NB_DIR}/home\"  ]]\n}\n\n@test \"'notebooks current --path' exits with 0 and prints the selected notebook path with path.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current \"${NB_DIR}/home\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ \"${output}\" == \"${NB_DIR}/home\"  ]]\n}\n\n@test \"'notebooks current --path' exits with 0 and prints the selected notebook path with identifier.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current home:example.md --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ \"${output}\" == \"${NB_DIR}/home\"  ]]\n}\n\n@test \"'notebooks current --path' exits with 0 and prints the current notebook path with not valid notebook selector.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current not-valid:example.md --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  [[ ${status} -eq 0                ]]\n  [[ \"${output}\" == \"${NB_DIR}/one\" ]]\n}\n\n@test \"'notebooks current --path' exits with 0 and prints the current notebook path with not valid path.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current \"${NB_DIR}/not-valid\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  [[ ${status} -eq 0                ]]\n  [[ \"${output}\" == \"${NB_DIR}/one\" ]]\n}\n\n# --selected ####################################################################\n\n@test \"'notebooks current --selected' exits with 1 when unscoped.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current --selected\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1  ]]\n  # TODO: This test fails. Review.\n  # [[ -z \"${output}\"   ]]\n}\n\n@test \"'notebooks current --selected' exits with 0 when scoped.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" home:notebooks current --selected\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0  ]]\n  [[ -z \"${output}\"   ]]\n}\n\n@test \"'notebooks current --selected' exits with 0 when passed a valid name.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current \"home\" --selected\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0  ]]\n  [[ -z \"${output}\"   ]]\n}\n\n@test \"'notebooks current --selected' exits with 0 when passed a name with colon.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current home: --selected\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0  ]]\n  [[ -z \"${output}\"   ]]\n}\n\n@test \"'notebooks current --selected' exits with 0 when passed a valid selector.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current home:example.md --selected\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0  ]]\n  [[ -z \"${output}\"   ]]\n}\n\n@test \"'notebooks current --selected' exits with 0 when passed an invalid selector.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current not-valid:example.md --selected\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1  ]]\n  [[ -z \"${output}\"   ]]\n}\n\n# --global ####################################################################\n\n@test \"'notebooks current --global' exits with 0 and prints the current global notebook name.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current --global\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0    ]]\n  [[ \"${output}\" =~ one ]]\n}\n\n@test \"'notebooks current --global --path' exits with 0 and prints the notebook path.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current --global --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${output}\" =~ ${NB_DIR}/one ]]\n}\n\n@test \"'notebooks current --global' in a local notebook exits with 0 and prints the global notebook.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n  }\n\n  run \"${_NB}\" notebooks current --global\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0    ]]\n  [[ \"${output}\" =~ one ]]\n}\n\n@test \"'notebooks current --global --path' in a local notebook exits with 0 and prints the global notebook path.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n  }\n\n  run \"${_NB}\" notebooks current --global --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_TMP_DIR}: '%s'\\\\n\" \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${output}\" =~ ${NB_DIR}/one ]]\n}\n\n@test \"'notebooks current --global' with selected exits with 0 and prints the global notebook name.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" home:notebooks current --global\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0    ]]\n  [[ \"${output}\" =~ one ]]\n}\n\n@test \"'notebooks current --global --path' with selected exits with 0 and prints the scoped notebook path.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" home:notebooks current --global --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${output}\" =~ ${NB_DIR}/one ]]\n}\n\n# --local #####################################################################\n\n@test \"'notebooks current --local' exits with 1 and prints nothing when not in local.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current --local\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1 ]]\n  [[ -z \"${output}\"  ]]\n}\n\n@test \"'notebooks current --local --path' exits with 1 and prints nothing when not in local.\" {\n  {\n    _setup_notebooks\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" notebooks current --local --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1 ]]\n  [[ -z \"${output}\"  ]]\n}\n\n@test \"'notebooks current --local' in a local notebook exits with 0 and prints nothing.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n  }\n\n  run \"${_NB}\" notebooks current --local\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0 ]]\n  [[ -z \"${output}\"  ]]\n}\n\n@test \"'notebooks current --local --path' in a local notebook exits with 0 and prints the local notebook path.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n  }\n\n  run \"${_NB}\" notebooks current --local --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_TMP_DIR}: '%s'\\\\n\" \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0                    ]]\n  [[ \"${output}\" =~ ${_TMP_DIR}/example ]]\n}\n\n@test \"'notebooks current --local' with selected exits with 1 and prints nothing.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" home:notebooks current --local\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1 ]]\n  [[ -z \"${output}\"  ]]\n}\n\n@test \"'notebooks current --local --path' with selected exits with 1 and prints nothing.\" {\n  {\n    _setup_notebooks\n\n    printf \"%s\\\\n\" \"one\" > \"${NB_DIR}/.current\"\n  }\n\n  run \"${_NB}\" home:notebooks current --local --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1 ]]\n  [[ -z \"${output}\"  ]]\n}\n\n# `notebooks current --filename` ##############################################\n\n@test \"'notebooks current --filename' prints a unique filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" notebooks current --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${lines[0]}\" =~ ^[0-9]+.md  ]]\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\"\n\n  run \"${_NB}\" notebooks current --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${lines[0]}\" =~ ^[0-9]+.md  ]]\n}\n\n@test \"'notebooks current <selector> --filename' prints a scoped unique filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n    \"${_NB}\" one:add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" notebooks current \"one\" --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${lines[0]}\" =~ ^[0-9]+.md  ]]\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\"\n\n  run \"${_NB}\" notebooks current \"one\" --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${lines[0]}\" =~ ^[0-9]+.md  ]]\n}\n\n@test \"'notebooks current --filename <filename>' prints a unique filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" notebooks current --filename \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\"\n\n  run \"${_NB}\" notebooks current --filename \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ example-2.md  ]]\n}\n\n@test \"'notebooks current <selector> --filename <filename>' prints a unique filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n    \"${_NB}\" one:add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" notebooks current \"one\" --filename \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  run \"${_NB}\" one:add \"example.md\" --content \"Example\"\n\n  run \"${_NB}\" notebooks current \"one\" --filename \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ example-2.md  ]]\n}\n"
  },
  {
    "path": "test/notebooks-delete.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebooks() {\n  \"${_NB}\" init\n\n  mkdir -p \"${NB_DIR}/one\"\n  cd \"${NB_DIR}/one\" || return 1\n\n  git init\n\n  git remote add origin \"${_GIT_REMOTE_URL}\"\n\n  touch \"${NB_DIR}/one/.index\"\n\n  cd \"${NB_DIR}\" || return 1\n}\n\n# prompt ######################################################################\n\n@test \"'notebooks delete' with non-affirmative prompt response prints message and exits.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks delete \"one\" <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                ]]\n\n  [[ \"${output}\" =~ Deleting\\ .*one.*\\.|Moving\\ to\\ Trash:\\ .*one.* ]]\n  [[ \"${output}\" =~ Exiting.*\\.\\.\\.                                 ]]\n\n\n  [[ -e \"${NB_DIR}/one\"                                             ]]\n}\n\n# <name> validation ###########################################################\n\n@test \"'notebooks delete <reserved>' exits with 1 and prints error message.\" {\n  {\n    \"${_NB}\" init\n\n    _names=(\n      \".cache\"\n      \".current\"\n      \".plugins\"\n      \".readme\"\n      \"readme\"\n      \"readme.md\"\n    )\n  }\n\n  for __name in \"${_names[@]}\"\n  do\n    run \"${_NB}\" notebooks delete \"${__name}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ ${status} -eq 1                  ]]\n    [[ \"${lines[0]}\" =~ Name\\ reserved  ]]\n    [[ \"${lines[0]}\" =~ ${__name}       ]]\n  done\n}\n\n# `notebooks delete` ##########################################################\n\n@test \"'notebooks delete <valid>' exits with 0 and deletes notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks delete \"one\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${output}\" =~ Notebook\\ deleted\\:       ]]\n  [[ \"${output}\" =~ one                       ]]\n  [[ ! -e \"${NB_DIR}/one\"                     ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n}\n\n@test \"'notebooks delete -f <valid>' parses arguments and deletes notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks delete -f \"one\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${output}\" =~ Notebook\\ deleted\\:       ]]\n  [[ \"${output}\" =~ one                       ]]\n  [[ ! -e \"${NB_DIR}/one\"                     ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n}\n\n@test \"'notebooks delete <notebook>:' exits with 0 and deletes notebook.\" {\n  {\n    _setup_notebooks\n    \"${_NB}\" notebooks use \"one\"\n    [[ \"$(cat \"${NB_DIR}/.current\")\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" notebooks delete one: --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${lines[0]}\" =~ Now\\ using              ]]\n  [[ \"${lines[0]}\" =~ home                    ]]\n  [[ \"${lines[1]}\" =~ Notebook\\ deleted\\:     ]]\n  [[ \"${lines[1]}\" =~ one                     ]]\n  [[ ! -e \"${NB_DIR}/one\"                     ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n}\n\n@test \"'notebooks delete <current>' exits with 0 and deletes notebook.\" {\n  {\n    _setup_notebooks\n    \"${_NB}\" notebooks use \"one\"\n    [[ \"$(cat \"${NB_DIR}/.current\")\" == \"one\" ]]\n  }\n\n  run \"${_NB}\" notebooks delete \"one\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${lines[0]}\" =~ Now\\ using              ]]\n  [[ \"${lines[0]}\" =~ home                    ]]\n  [[ \"${lines[1]}\" =~ Notebook\\ deleted\\:     ]]\n  [[ \"${lines[1]}\" =~ one                     ]]\n  [[ ! -e \"${NB_DIR}/one\"                     ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n}\n\n@test \"'notebooks delete <home>' exits with 0 and deletes notebook.\" {\n  {\n    _setup_notebooks\n    [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\" ]]\n  }\n\n  run \"${_NB}\" notebooks delete \"home\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${lines[0]}\" =~ Now\\ using                ]]\n  [[ \"${lines[0]}\" =~ one                       ]]\n  [[ \"${lines[1]}\" =~ Notebook\\ deleted\\:       ]]\n  [[ \"${lines[1]}\" =~ home                      ]]\n  [[ ! -e \"${NB_DIR}/home\"                      ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"one\"     ]]\n}\n\n@test \"'notebooks delete <home>' last notebook exits with 0 and deletes notebook.\" {\n  {\n    _setup_notebooks\n    [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n\n    \"${_NB}\" notebooks delete \"one\" --force\n\n    [[ -e \"${NB_DIR}/home\"                      ]]\n    [[ ! -e \"${NB_DIR}/one\"                     ]]\n  }\n\n  run \"${_NB}\" notebooks delete \"home\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${lines[0]}\" =~ Notebook\\ deleted\\:     ]]\n  [[ \"${lines[0]}\" =~ home                    ]]\n  [[ ! -e \"${NB_DIR}/home\"                    ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n}\n\n@test \"'notebooks delete <no name>' exits with 1.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks delete --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1        ]]\n  [[ \"${lines[0]}\" =~ Usage ]]\n  [[ -e \"${NB_DIR}/home\"    ]]\n}\n\n@test \"'notebooks delete <not-valid>' exits with 1.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks delete not-valid --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                        ]]\n  [[ \"${lines[0]}\" =~ Notebook\\ not\\ found  ]]\n  [[ -e \"${NB_DIR}/home\"                    ]]\n}\n\n@test \"'notebooks delete local' in local exits with 1.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add local\n    mkdir -p \"${_TMP_DIR}/example\"\n    cd \"${_TMP_DIR}/example\"\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\"  ]]\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n    [[ -e \"${NB_DIR}/local\"               ]]\n  }\n\n  run \"${_NB}\" notebooks delete local --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                  ]]\n  [[ \"${lines[0]}\" =~ file\\ explorer  ]]\n  [[ -e \"${NB_DIR}/home\"              ]]\n  [[ -e \"${NB_DIR}/local\"             ]]\n}\n\n@test \"'notebooks delete local' outside local deletes.\" {\n  {\n    _pwd=\"${PWD}\"\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add local\n    mkdir -p \"${_TMP_DIR}/example\"\n    cd \"${_TMP_DIR}/example\"\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n    cd \"${_pwd}\" || return 1\n    [[ -e \"${NB_DIR}/local\" ]]\n  }\n\n  run \"${_NB}\" notebooks delete local --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                      ]]\n  [[ \"${lines[0]}\" =~ Notebook\\ deleted\\: ]]\n  [[ \"${lines[0]}\" =~ local               ]]\n  [[ ! -e \"${NB_DIR}/local\"               ]]\n}\n"
  },
  {
    "path": "test/notebooks-export.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebooks() {\n  \"${_NB}\" init\n  mkdir -p \"${NB_DIR}/one\"\n  cd \"${NB_DIR}/one\" || return 1\n  git init\n  git remote add origin \"${_GIT_REMOTE_URL}\"\n  touch \"${NB_DIR}/one/.index\"\n  mkdir -p \"${NB_DIR}/two\"\n  cd \"${NB_DIR}\" || return 1\n}\n\n# <name> validation ###########################################################\n\n@test \"'notebooks export <reserved>' exits with 1 and prints error message.\" {\n  {\n    \"${_NB}\" init\n\n    cd \"${_TMP_DIR}\"\n\n    _names=(\n      \".cache\"\n      \".current\"\n      \".plugins\"\n      \".readme\"\n      \"readme\"\n      \"readme.md\"\n    )\n  }\n\n  for __name in \"${_names[@]}\"\n  do\n    run \"${_NB}\" notebooks export \"${__name}\" \"${_TMP_DIR}/example\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ ${status} -eq 1                  ]]\n    [[ \"${lines[0]}\" =~ Name\\ reserved  ]]\n    [[ \"${lines[0]}\" =~ ${__name}       ]]\n  done\n}\n\n# `notebooks export` ##########################################################\n\n@test \"'notebooks export' with no arguments exits with status 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks export\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1            ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\: ]]\n}\n\n@test \"'notebooks export' with valid <name> exports to current directory.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks add \"example\"\n\n  [[ -d \"${NB_DIR}/example\"     ]]\n  [[ ! -d \"${_TMP_DIR}/example\" ]]\n\n  cd \"${_TMP_DIR}\"\n\n  run \"${_NB}\" notebooks export \"example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ -d \"${_TMP_DIR}/example\"       ]]\n  [[ -d \"${_TMP_DIR}/example/.git\"  ]]\n  [[ \"${lines[0]}\" =~ \"Exported\"    ]]\n}\n\n@test \"'notebooks export' with valid <name> exports to current directory uniquely.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"example\"\n    [[ -d \"${NB_DIR}/example\"     ]]\n\n    mkdir -p \"${_TMP_DIR}/example\"\n    [[ -d \"${_TMP_DIR}/example\"   ]]\n\n    cd \"${_TMP_DIR}\"\n  }\n\n  run \"${_NB}\" notebooks export \"example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ -d \"${_TMP_DIR}/example-1\"       ]]\n  [[ -d \"${_TMP_DIR}/example-1/.git\"  ]]\n  [[ \"${lines[0]}\" =~ \"Exported\"      ]]\n}\n\n@test \"'notebooks export' with invalid <name> exits with 1.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"example\"\n    [[ -d \"${NB_DIR}/example\" ]]\n    cd \"${_TMP_DIR}\"\n  }\n\n  run \"${_NB}\" notebooks export \"not valid\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 1                  ]]\n  [[ ! -d \"${_TMP_DIR}/example\"       ]]\n  [[ ! -d \"${_TMP_DIR}/example/.git\"  ]]\n  [[ \"${lines[0]}\" =~ \"not found\"     ]]\n}\n\n@test \"'notebooks export' with valid <name> and <path> exports.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"example\"\n    [[ -d \"${NB_DIR}/example\"     ]]\n    [[ ! -d \"${_TMP_DIR}/example\" ]]\n  }\n\n  run \"${_NB}\" notebooks export \"example\" \"${_TMP_DIR}/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ -d \"${_TMP_DIR}/example\"       ]]\n  [[ -d \"${_TMP_DIR}/example/.git\"  ]]\n  [[ \"${lines[0]}\" =~ \"Exported\"    ]]\n}\n\n@test \"'notebooks export' with valid <name> and <path> exports uniquely.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"example\"\n    [[ -d \"${NB_DIR}/example\"     ]]\n    mkdir -p \"${_TMP_DIR}/example\"\n    [[ -d \"${_TMP_DIR}/example\"   ]]\n  }\n\n  run \"${_NB}\" notebooks export \"example\" \"${_TMP_DIR}/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ -d \"${_TMP_DIR}/example-1\"       ]]\n  [[ -d \"${_TMP_DIR}/example-1/.git\"  ]]\n  [[ \"${lines[0]}\" =~ \"Exported\"      ]]\n}\n\n@test \"'notebooks export' with valid <name> and <path> ending in existing name exports.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"example\"\n    [[ -d \"${NB_DIR}/example\"     ]]\n    mkdir -p \"${_TMP_DIR}/example\"\n    [[ -d \"${_TMP_DIR}/example\"   ]]\n  }\n\n  run \"${_NB}\" notebooks export \"example\" \"${_TMP_DIR}/sample-example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0                      ]]\n  [[ -d \"${_TMP_DIR}/sample-example\"      ]]\n  [[ -d \"${_TMP_DIR}/sample-example/.git\" ]]\n  [[ \"${lines[0]}\" =~ \"Exported\"          ]]\n}\n\n@test \"'notebooks export' with valid <name> and relative <path> exports.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"example\"\n    [[ -d \"${NB_DIR}/example\"       ]]\n    mkdir -p \"${_TMP_DIR}/subfolder\"\n    [[ -d \"${_TMP_DIR}/subfolder\"   ]]\n    cd \"${_TMP_DIR}\"\n  }\n\n  run \"${_NB}\" notebooks export \"example\" \"subfolder/local-notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${_TMP_DIR}\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ -d \"${_TMP_DIR}/subfolder/local-notebook\"      ]]\n  [[ -d \"${_TMP_DIR}/subfolder/local-notebook/.git\" ]]\n  [[ \"${lines[0]}\" =~ \"Exported\"                    ]]\n}\n"
  },
  {
    "path": "test/notebooks-import.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebooks() {\n  \"${_NB}\" init\n  mkdir -p \"${NB_DIR}/one\"\n  cd \"${NB_DIR}/one\" || return 1\n  git init\n  git remote add origin \"${_GIT_REMOTE_URL}\"\n  touch \"${NB_DIR}/one/.index\"\n  cd \"${NB_DIR}\" || return 1\n}\n\n# <name> validation ###########################################################\n\n@test \"'notebooks export <reserved>' exits with 1 and prints error message.\" {\n  {\n    \"${_NB}\" init\n\n    cd \"${_TMP_DIR}\"\n\n    _names=(\n      \".cache\"\n      \".current\"\n      \".plugins\"\n      \".readme\"\n      \"readme\"\n      \"readme.md\"\n    )\n  }\n\n  for __name in \"${_names[@]}\"\n  do\n    run \"${_NB}\" notebooks import                     \\\n      \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\"  \\\n      \"${__name}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    ls \"${NB_DIR}\"\n\n    [[ ${status} -eq 1                  ]]\n    [[ \"${lines[0]}\" =~ Name\\ reserved  ]]\n    [[ \"${lines[0]}\" =~ ${__name}       ]]\n\n    [[ ! \"${output}\" =~ \"Imported\"      ]]\n    \"${_NB}\" notebooks | grep -q -v 'example'\n  done\n}\n\n# no argument #################################################################\n\n@test \"'notebooks import' with no arguments exits with status 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks import\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1            ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\: ]]\n}\n\n@test \"'notebooks import' with valid directory <path> imports.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks import \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls \"${NB_DIR}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ -d \"${NB_DIR}/Example Folder\"              ]]\n  [[ \"${lines[0]}\" =~ \"Imported\"                ]]\n  \"${_NB}\" notebooks | grep -q 'Example Folder'\n}\n\n@test \"'notebooks import' with relative <path> imports.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${_TMP_DIR}/example\"\n\n    touch \"${_TMP_DIR}/example/file.md\"\n\n    cd \"${_TMP_DIR}\"\n  }\n\n  run \"${_NB}\" notebooks import example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls \"${NB_DIR}\"\n\n  [[ ${status} -eq 0                      ]]\n  [[ -d \"${NB_DIR}/example\"               ]]\n  [[ \"${lines[0]}\" =~ \"Imported\"          ]]\n  \"${_NB}\" notebooks | grep -q 'example'\n}\n\n@test \"'notebooks import' with existing notebook imports with unique name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Folder\"\n\n    [[ -d \"${NB_DIR}/Example Folder\" ]]\n  }\n\n  run \"${_NB}\" notebooks import \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls \"${NB_DIR}\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ -d \"${NB_DIR}/Example Folder-1\"              ]]\n  [[ \"${lines[0]}\" =~ \"Imported\"                  ]]\n  \"${_NB}\" notebooks | grep -q 'Example Folder-1'\n}\n\n@test \"'notebooks import' with invalid file <path> argument exits with 1.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks import \"${NB_TEST_BASE_PATH}/fixtures/example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\n  \"\n  ls \"${NB_DIR}\"\n\n  [[ ${status} -eq 1                    ]]\n  [[ ! -e \"${NB_DIR}/Example Folder\"    ]]\n  [[ \"${lines[0]}\" =~ \"Not a directory\" ]]\n}\n\n@test \"'notebooks import' with valid <name> argument imports.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" notebooks import                     \\\n    \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\"  \\\n    \"example-notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls \"${NB_DIR}\"\n\n  [[ ${status} -eq 0                        ]]\n  [[ -d \"${NB_DIR}/example-notebook\"        ]]\n  [[ -d \"${NB_DIR}/example-notebook/.git\"   ]]\n  [[ -f \"${NB_DIR}/example-notebook/.index\" ]]\n  [[ \"${lines[0]}\" =~ \"Imported\"            ]]\n  \"${_NB}\" notebooks | grep -q 'example'\n}\n\n@test \"'notebooks import' with existing notebook <name> imports with unique name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"example\"\n\n    [[ -d \"${NB_DIR}/example\" ]]\n  }\n\n  run \"${_NB}\" notebooks import                     \\\n    \"${NB_TEST_BASE_PATH}/fixtures/Example Folder\"  \\\n    \"example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  ls \"${NB_DIR}\"\n\n  [[ ${status} -eq 0                        ]]\n  [[ -d \"${NB_DIR}/example-1\"               ]]\n  [[ \"${lines[0]}\" =~ \"Imported\"            ]]\n  \"${_NB}\" notebooks | grep -q 'example-1'\n}\n"
  },
  {
    "path": "test/notebooks-init.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebooks() {\n  \"${_NB}\" init\n\n  mkdir -p \"${NB_DIR}/one\"\n  cd \"${NB_DIR}/one\" || return 1\n  git init\n  git remote add origin \"${_GIT_REMOTE_URL}\"\n  touch \"${NB_DIR}/one/.index\"\n\n  mkdir -p \"${NB_DIR}/two\"\n\n  cd \"${NB_DIR}\" || return 1\n}\n\n# edge cases ##################################################################\n\n@test \"'noteboos init' with uninitialized configuration initializes configuration\" {\n  run \"${_NB}\" notebooks init\n\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n  [[ !  \"${output}\"   =~  repository\\ \\'init\\'\\ does\\ not\\ exist  ]]\n  [[ !  \"${output}\"   =~  Not\\ found                              ]]\n  [[    \"${output}\"   =~  0\\ items.                               ]]\n}\n\n# nested repositories #########################################################\n\n@test \"'notebooks init <relative path>' with nested git repositories and positive prompt response prints warning and succeeds.\" {\n  {\n    \"${_NB}\" init\n\n    cd \"${_TMP_DIR}\"\n\n    declare _paths=(\n      \"${_TMP_DIR}/target-directory/repo-1\"\n      \"${_TMP_DIR}/target-directory/example-nested/repo-2\"\n      \"${_TMP_DIR}/target-directory/sample-nested/demo-nested/repo-3\"\n    )\n\n    declare __path=\n    for     __path in \"${_paths[@]:-}\"\n    do\n      mkdir -p \"${__path}\"\n\n      cd \"${__path}\"\n\n      git init\n    done\n\n    diff                \\\n      <(printf \"3\\\\n\")  \\\n      <(find \"${_TMP_DIR}/target-directory/\" -name .git -prune | wc -l | awk '$1=$1')\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/target-directory\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                   ]]\n  [[    \"${lines[0]}\" =~  \\\nDirectory\\ exists:\\ .*${_TMP_DIR}/target-directory            ]]\n  [[    \"${lines[1]}\" =~  \\\n!.*\\ This\\ directory\\ contains\\ .*3.*\\ git\\ repositories.     ]]\n  [[    \"${lines[2]}\" =~  \\\nInitialized\\ local\\ notebook:\\ .*${_TMP_DIR}/target-directory ]]\n\n  [[ -d \"${_TMP_DIR}/target-directory/.git\"                   ]]\n  [[ -f \"${_TMP_DIR}/target-directory/.index\"                 ]]\n}\n\n# remote ######################################################################\n\n@test \"'notebooks init <path> <remote-url> <branch>' exits with 0 and adds a notebook.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/example\" \"${_GIT_REMOTE_URL}\" \"example-branch\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  diff                                                                \\\n    <(cd \"${_TMP_DIR}/example\" && git config --get remote.origin.url) \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                \\\n    <(cd \"${_TMP_DIR}/example\" && git rev-parse --abbrev-ref HEAD)    \\\n    <(printf \"example-branch\\\\n\")\n\n  [[    \"${status}\"   -eq 0                             ]]\n  [[    \"${lines[0]}\" =~  Cloning                       ]]\n  [[    \"${lines[1]}\" =~  Initialized\\ local\\ notebook  ]]\n  [[    \"${lines[1]}\" =~  example                       ]]\n  [[ -d \"${_TMP_DIR}/example/.git\"                      ]]\n  [[ -f \"${_TMP_DIR}/example/.index\"                    ]]\n  [[ -f \"${_TMP_DIR}/example/Example File One.md\"       ]]\n\n  cd \"${_TMP_DIR}/example\" || return 1\n\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -v 'Initial commit.'\n  git log | grep 'Initialize'\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ example-branch            ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/example-branch ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  master|main                   ]]\n}\n\n@test \"'notebooks init <path> <remote-url>' exits with 0 and adds a notebook.\" {\n  {\n    _setup_notebooks\n    _setup_remote_repo\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                              \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"                \\\n          | sed \"s/.*\\///g\" || :)                     \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/example\" \"${_GIT_REMOTE_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  diff                                                                \\\n    <(cd \"${_TMP_DIR}/example\" && git config --get remote.origin.url) \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                                                \\\n    <(cd \"${_TMP_DIR}/example\" && git rev-parse --abbrev-ref HEAD)    \\\n    <(printf \"master\\\\n\")\n\n  [[    \"${status}\"   -eq 0                             ]]\n  [[    \"${lines[0]}\" =~  Cloning                       ]]\n  [[    \"${lines[1]}\" =~  Initialized\\ local\\ notebook  ]]\n  [[    \"${lines[1]}\" =~  example                       ]]\n  [[ -d \"${_TMP_DIR}/example/.git\"                      ]]\n  [[ -f \"${_TMP_DIR}/example/.index\"                    ]]\n\n  cd \"${_TMP_DIR}/example\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep 'Initial commit.'\n\n  \"${_NB}\" git branch --all\n\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  \\*\\ master                                ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/HEAD\\ \\-\\>\\ origin/master  ]]\n  [[    \"$(\"${_NB}\" git branch --all)\"  =~  remotes/origin/master                     ]]\n  [[ !  \"$(\"${_NB}\" git branch --all)\"  =~  example-branch                            ]]\n}\n\n# config ######################################################################\n\n@test \"'notebooks init --author' displays config prompt and sets email and name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Home File.md\" --content \"Example home content.\"\n\n    declare _global_email=\n    _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n    declare _global_name=\n    _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n    diff                                            \\\n      <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n      <(printf \"Author: %s <%s>\\\\n\" \"${_global_name}\" \"${_global_email}\")\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local Notebook\" --author \\\n    <<< \"y${_NEWLINE}local@example.test${_NEWLINE}Example Local Name${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 11  ]]\n\n  [[ -n \"$(git -C \"${_TMP_DIR}/Example Local Notebook\" config --local user.email  || :)\"  ]]\n  [[ -n \"$(git -C \"${_TMP_DIR}/Example Local Notebook\" config --local user.name   || :)\"  ]]\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*local                         ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  [[ \"${lines[4]}\"  =~ \\\nEnter\\ a\\ new\\ value,\\ .*unset.*\\ to\\ use\\ the\\ global\\ value,                ]]\n  [[ \"${lines[5]}\"  =~ or\\ leave\\ blank\\ to\\ keep\\ the\\ current\\ value\\.      ]]\n\n  [[ \"${lines[6]}\"  =~ Updated\\ author\\ for:\\ .*local                         ]]\n  [[ \"${lines[7]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[8]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[9]}\"  =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  [[ \"${lines[10]}\" =~ \\\nInitialized\\ local\\ notebook:\\ .*${_TMP_DIR}/Example\\ Local\\ Notebook         ]]\n\n  cd \"${_TMP_DIR}/Example Local Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n# --email and --name ##########################################################\n\n@test \"'notebooks init --email <email> --name <name>' sets the local email and name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Home File.md\" --content \"Example home content.\"\n\n    declare _global_email=\n    _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n    declare _global_name=\n    _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n    diff                                            \\\n      <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n      <(printf \"Author: %s <%s>\\\\n\" \"${_global_name}\" \"${_global_email}\")\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local Notebook\"     \\\n    --email \"local@example.test\"                                        \\\n    --name  \"Example Local Name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 13  ]]\n\n  [[ -n \"$(git -C \"${_TMP_DIR}/Example Local Notebook\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${_TMP_DIR}/Example Local Notebook\" config --local user.name   || :)\" ]]\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*local                         ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[7]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[8]}\"  =~ Updated\\ author\\ for:\\ .*local                         ]]\n  [[ \"${lines[9]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[10]}\" =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[11]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  [[ \"${lines[12]}\" =~ \\\nInitialized\\ local\\ notebook:\\ .*${_TMP_DIR}/Example\\ Local\\ Notebook         ]]\n\n  cd \"${_TMP_DIR}/Example Local Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <local@example.test>\\\\n\")\n}\n\n@test \"'notebooks init --email <email>' sets the local email.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Home File.md\" --content \"Example home content.\"\n\n    declare _global_email=\n    _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n    declare _global_name=\n    _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n    diff                                            \\\n      <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n      <(printf \"Author: %s <%s>\\\\n\" \"${_global_name}\" \"${_global_email}\")\n  }\n\n  run \"${_NB}\"  notebooks init \"${_TMP_DIR}/Example Local Notebook\" \\\n    --email \"local@example.test\"                                    \\\n    <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n\n  [[ -n \"$(git -C \"${_TMP_DIR}/Example Local Notebook\" config --local user.email  || :)\" ]]\n  [[ -z \"$(git -C \"${_TMP_DIR}/Example Local Notebook\" config --local user.name   || :)\" ]]\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*local                         ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*email.*:\\ local@example.test                  ]]\n  [[ \"${lines[7]}\"  =~ Updated\\ author\\ for:\\ .*local                         ]]\n  [[ \"${lines[8]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[9]}\"  =~ .*email.*\\ \\(.*local.*\\):\\ \\ local@example.test        ]]\n  [[ \"${lines[10]}\" =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n\n  [[ \"${lines[11]}\" =~ \\\nInitialized\\ local\\ notebook:\\ .*${_TMP_DIR}/Example\\ Local\\ Notebook         ]]\n\n  cd \"${_TMP_DIR}/Example Local Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: %s <local@example.test>\\\\n\" \"${_global_name}\")\n}\n\n@test \"'notebooks init --name <name>' sets the local name.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Home File.md\" --content \"Example home content.\"\n\n    declare _global_email=\n    _global_email=\"$(git -C \"${NB_DIR}/home\" config --global user.email)\"\n\n    declare _global_name=\n    _global_name=\"$(git -C \"${NB_DIR}/home\" config --global user.name)\"\n\n    diff                                            \\\n      <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n      <(printf \"Author: %s <%s>\\\\n\" \"${_global_name}\" \"${_global_email}\")\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/Example Local Notebook\"  \\\n    --name \"Example Local Name\"                                     \\\n    <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 12  ]]\n\n  [[ -z \"$(git -C \"${_TMP_DIR}/Example Local Notebook\" config --local user.email  || :)\" ]]\n  [[ -n \"$(git -C \"${_TMP_DIR}/Example Local Notebook\" config --local user.name   || :)\" ]]\n\n  [[ \"${lines[0]}\"  =~ Current\\ author\\ for:\\ .*local                         ]]\n  [[ \"${lines[1]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[3]}\"  =~ .*name.*\\ \\ \\(.*global.*\\):\\ ${_global_name//' '/\\\\ }  ]]\n  [[ \"${lines[4]}\"  =~ Update:                                                ]]\n  [[ \"${lines[5]}\"  =~ [^-]-------[^-]                                        ]]\n  [[ \"${lines[6]}\"  =~ local\\ .*name.*:\\ \\ Example\\ Local\\ Name               ]]\n  [[ \"${lines[7]}\"  =~ Updated\\ author\\ for:\\ .*local                         ]]\n  [[ \"${lines[8]}\"  =~ [^-]-------------------[^-]                            ]]\n  [[ \"${lines[9]}\"  =~ .*email.*\\ \\(.*global.*\\):\\ ${_global_email}           ]]\n  [[ \"${lines[10]}\" =~ .*name.*\\ \\ \\(.*local.*\\):\\ \\ Example\\ Local\\ Name     ]]\n\n  [[ \"${lines[11]}\" =~ \\\nInitialized\\ local\\ notebook:\\ .*${_TMP_DIR}/Example\\ Local\\ Notebook         ]]\n\n  cd \"${_TMP_DIR}/Example Local Notebook\"\n\n  \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n  diff                                            \\\n    <(\"${_NB}\" git log -1 --stat | sed -n '2 p')  \\\n    <(printf \"Author: Example Local Name <%s>\\\\n\" \"${_global_email}\")\n}\n\n# `notebooks init` ############################################################\n\n@test \"'notebooks init' with no arguments and positive prompt response initializes the current directory.\" {\n  {\n    _setup_notebooks\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n  }\n\n  run \"${_NB}\" notebooks init <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                           ]]\n  [[    \"${lines[0]}\" =~  \\\nDirectory\\ exists:\\ .*${_TMP_DIR}/example             ]]\n  [[    \"${lines[1]}\" =~  \\\nInitialized\\ local\\ notebook:\\ .*${_TMP_DIR}/example  ]]\n\n  [[ -d \"${_TMP_DIR}/example/.git\"                    ]]\n  [[ -f \"${_TMP_DIR}/example/.index\"                  ]]\n}\n\n@test \"'notebooks init' with no arguments and negative prompt response exits without initialization.\" {\n  {\n    _setup_notebooks\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\"  ]]\n  }\n\n  run \"${_NB}\" notebooks init <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0               ]]\n  [[    \"${lines[0]}\" =~  \\\nDirectory\\ exists:\\ .*${_TMP_DIR}/example ]]\n  [[    \"${lines[1]}\" =~ Exiting.*\\.\\.\\.  ]]\n\n\n  [[ ! -d \"${_TMP_DIR}/example/.git\"      ]]\n  [[ ! -f \"${_TMP_DIR}/example/.index\"    ]]\n}\n\n@test \"'notebooks init' in existing notebook exits with 1 and prints error message.\" {\n  {\n    _setup_notebooks\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\"  ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n  }\n\n  run \"${_NB}\" notebooks init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                         ]]\n  [[ \"${lines[0]}\"  =~  Notebook\\ exists:\\ .*${_TMP_DIR}/example  ]]\n}\n\n@test \"'notebooks init' in existing git repo exits with 1 and prints error message.\" {\n  {\n    _setup_notebooks\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\"  ]]\n\n    git init 1>/dev/null\n  }\n\n  run \"${_NB}\" notebooks init\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                       ]]\n  [[ \"${lines[0]}\"  =~  \\\nGit\\ repository\\ exists:\\ .*${_TMP_DIR}/example ]]\n}\n\n@test \"'notebooks init <relative path>' with no arguments succeeds.\" {\n  {\n    _setup_notebooks\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}\" ]]\n  }\n\n  run \"${_NB}\" notebooks init example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                           ]]\n  [[    \"${lines[0]}\" =~  \\\nInitialized\\ local\\ notebook:\\ .*${_TMP_DIR}/example  ]]\n\n  [[ -d \"${_TMP_DIR}/example/.git\"                    ]]\n  [[ -f \"${_TMP_DIR}/example/.index\"                  ]]\n}\n\n@test \"'notebooks init <relative path>' with existing directory and positive prompt response succeeds.\" {\n  {\n    _setup_notebooks\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}\"  ]]\n\n    mkdir \"${_TMP_DIR}/example\"\n\n    [[ -d \"${_TMP_DIR}/example\"   ]]\n  }\n\n  run \"${_NB}\" notebooks init example <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                           ]]\n  [[    \"${lines[0]}\" =~  \\\nDirectory\\ exists:\\ .*${_TMP_DIR}/example             ]]\n  [[    \"${lines[1]}\" =~  \\\nInitialized\\ local\\ notebook:\\ .*${_TMP_DIR}/example  ]]\n\n  [[ -d \"${_TMP_DIR}/example/.git\"                    ]]\n  [[ -f \"${_TMP_DIR}/example/.index\"                  ]]\n}\n\n@test \"'notebooks init <relative path>' with existing directory and negative prompt response exits without initialization.\" {\n  {\n    _setup_notebooks\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}\"  ]]\n\n    mkdir \"${_TMP_DIR}/example\"\n\n    [[ -d \"${_TMP_DIR}/example\"   ]]\n  }\n\n  run \"${_NB}\" notebooks init example <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0               ]]\n  [[    \"${lines[0]}\" =~  \\\nDirectory\\ exists:\\ .*${_TMP_DIR}/example ]]\n  [[    \"${lines[1]}\" =~ Exiting.*\\.\\.\\.  ]]\n\n  [[ ! -d \"${_TMP_DIR}/example/.git\"      ]]\n  [[ ! -f \"${_TMP_DIR}/example/.index\"    ]]\n}\n\n@test \"'notebooks init <relative path>' in existing notebook exits with 1.\" {\n  {\n    _setup_notebooks\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}\" ]]\n  }\n\n  run \"${_NB}\" notebooks init example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                         ]]\n  [[ \"${lines[0]}\"  =~  Notebook\\ exists:\\ .*${_TMP_DIR}/example  ]]\n}\n\n@test \"'notebooks init <relative path>' in existing git repo exits with 1.\" {\n  {\n    _setup_notebooks\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}\" ]]\n  }\n\n  run \"${_NB}\" notebooks init example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                               ]]\n  [[ \"${lines[0]}\"  =~  Git\\ repository\\ exists:\\ .*${_TMP_DIR}/example ]]\n}\n\n@test \"'notebooks init <absolute path>' with no arguments succeeds.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                     ]]\n  [[ \"${lines[0]}\"  =~  Initialized\\ local\\ notebook:\\ .*${_TMP_DIR}/example  ]]\n\n  [[ -d \"${_TMP_DIR}/example/.git\"                                            ]]\n  [[ -f \"${_TMP_DIR}/example/.index\"                                          ]]\n\n  cd \"${_TMP_DIR}/example\" || return 1\n  printf \"\\$(git log): '%s'\\n\" \"$(git log)\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep '\\[nb\\] Initialize'\n}\n\n@test \"'notebooks init <absolute path>' with existing directory and positive prompt response succeeds.\" {\n  {\n    _setup_notebooks\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}\"  ]]\n\n    mkdir \"${_TMP_DIR}/example\"\n\n    [[ -d \"${_TMP_DIR}/example\"   ]]\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/example\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                           ]]\n  [[    \"${lines[0]}\" =~  \\\nDirectory\\ exists:\\ .*${_TMP_DIR}/example             ]]\n  [[    \"${lines[1]}\" =~  \\\nInitialized\\ local\\ notebook:\\ .*${_TMP_DIR}/example  ]]\n\n  [[ -d \"${_TMP_DIR}/example/.git\"                    ]]\n  [[ -f \"${_TMP_DIR}/example/.index\"                  ]]\n}\n\n@test \"'notebooks init <absolute path>' with existing directory and negative prompt response exits without initialization.\" {\n  {\n    _setup_notebooks\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}\"  ]]\n\n    mkdir \"${_TMP_DIR}/example\"\n\n    [[ -d \"${_TMP_DIR}/example\"   ]]\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/example\" <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0               ]]\n  [[    \"${lines[0]}\" =~  \\\nDirectory\\ exists:\\ .*${_TMP_DIR}/example ]]\n  [[    \"${lines[1]}\" =~ Exiting.*\\.\\.\\.  ]]\n\n  [[ ! -d \"${_TMP_DIR}/example/.git\"      ]]\n  [[ ! -f \"${_TMP_DIR}/example/.index\"    ]]\n}\n\n@test \"'notebooks init <absolute path>' in existing notebook exits with 1.\" {\n  {\n    _setup_notebooks\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                         ]]\n  [[ \"${lines[0]}\"  =~  Notebook\\ exists:\\ .*${_TMP_DIR}/example  ]]\n}\n\n@test \"'notebooks init <absolute path>' in existing git repo exits with 1.\" {\n  {\n    _setup_notebooks\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null\n  }\n\n  run \"${_NB}\" notebooks init \"${_TMP_DIR}/example\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                               ]]\n  [[ \"${lines[0]}\"  =~  Git\\ repository\\ exists:\\ .*${_TMP_DIR}/example ]]\n}\n\n@test \"'notebooks init <top-level-directory>' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    declare _current_home=\"${HOME}\"\n  }\n\n  while [[ \"${_current_home}\" =~ /  ]]\n  do\n    printf \"_current_home: %s\\\\n\" \"${_current_home}\"\n\n    run \"${_NB}\" notebooks init \"${_current_home}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"    -eq 1         ]]\n    [[ \"${lines[0]}\"  =~  \\\n!.*\\ Unable\\ to\\ turn\\ top\\-level\\ directory\\ into\\ local\\ notebook:\\ .*${_current_home} ]]\n\n    _current_home=\"${_current_home%/*}\"\n  done\n}\n"
  },
  {
    "path": "test/notebooks-notebook.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebook() {\n  {\n    \"${_NB}\" init\n\n    mkdir -p \"${NB_DIR}/one\"\n\n    cd \"${NB_DIR}/one\" || return 1\n\n    git init\n    git remote add origin \"${_GIT_REMOTE_URL}\"\n\n    mkdir -p \"${NB_DIR}/two\"\n\n    cd \"${NB_DIR}\" || return 1\n  } > /dev/null 2>&1\n}\n\n# <name> validation ###########################################################\n\n@test \"'notebooks archive <reserved>' exits with 1 and prints error message.\" {\n  {\n    \"${_NB}\" init\n\n    cd \"${_TMP_DIR}\"\n\n    declare _names=(\n      \".cache\"\n      \".current\"\n      \".plugins\"\n      \".readme\"\n      \"readme\"\n      \"readme.md\"\n    )\n  }\n\n  declare __name=\n  for     __name in \"${_names[@]}\"\n  do\n    run \"${_NB}\" notebooks archive \"${__name}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"    -eq 1               ]]\n    [[ \"${lines[0]}\"  =~  Name\\ reserved  ]]\n    [[ \"${lines[0]}\"  =~  ${__name}       ]]\n  done\n}\n\n# `notebooks archive` #########################################################\n\n@test \"'notebooks archive' exits with 0 and archives.\" {\n  {\n    _setup_notebook\n  }\n\n  run \"${_NB}\" notebooks archive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                     ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"home\") archived.\"  ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"                   ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q '\\[nb\\] Archived'\n}\n\n@test \"'notebooks archive <name>' exits with 0 and archives.\" {\n  {\n    _setup_notebook\n  }\n\n  run \"${_NB}\" notebooks archive one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                   ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"one\") archived.\" ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/one\" || return 1\n\n  declare _counter=0\n\n  while [[ -n \"$(git status --porcelain)\"                 ]]\n  do\n    [[ \"${_counter}\" -gt 5 ]] && git status && break\n\n    sleep 1\n\n    _counter=\"$((_counter+1))\"\n  done\n\n  git log | grep -q '\\[nb\\] Archived'\n}\n\n@test \"'notebooks archive' does not create git commit if already archived.\" {\n  {\n    _setup_notebook\n\n    touch \"${NB_DIR}/home/.archived\"\n  }\n\n  run \"${_NB}\" notebooks archive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                   ]]\n\n  # NOTE: Spinner changes output in unexpected ways.\n  [[ \"${output}\"  =~  home                ]]\n  [[ \"${output}\"  =~  archived\\.$         ]]\n\n  # Does not create git commit\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q -v '\\[nb\\] Archived'\n}\n\n# `notebooks unarchive` #######################################################\n\n@test \"'notebooks unarchive' exits with 0 and unarchives.\" {\n  {\n    _setup_notebook\n\n    \"${_NB}\" notebooks archive\n  }\n\n  run \"${_NB}\" notebooks unarchive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                       ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"home\") unarchived.\"  ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"                     ]]\n  do\n    sleep 1\n  done\n\n  git log | grep '\\[nb\\] Unarchived'\n}\n\n@test \"'notebooks unarchive <name>' exits with 0 and unarchives.\" {\n  {\n    _setup_notebook\n\n    \"${_NB}\" notebooks archive one\n  }\n\n  run \"${_NB}\" notebooks unarchive one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                     ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"one\") unarchived.\" ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/one\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"                   ]]\n  do\n    sleep 1\n  done\n\n  git log | grep '\\[nb\\] Unarchived'\n}\n\n@test \"'notebooks unarchive' does not create git commit if already unarchived.\" {\n  {\n    _setup_notebook\n  }\n\n  run \"${_NB}\" notebooks unarchive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                       ]]\n  [[ \"${output}\"  ==  \"$(_color_primary \"home\") unarchived.\"  ]]\n\n  # Creates git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n\n  while [[ -n \"$(git status --porcelain)\"                     ]]\n  do\n    sleep 1\n  done\n\n  git log | grep -q -v '\\[nb\\] Unarchived'\n}\n\n# `notebooks status` ##########################################################\n\n@test \"'notebooks status' exits with 0 and prints status.\" {\n  {\n    _setup_notebook\n  }\n\n  run \"${_NB}\" notebooks status\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                            ]]\n  [[ \"${output}\" == \"$(_color_primary \"home\") is not archived.\" ]]\n\n  run \"${_NB}\" notebooks archive\n  run \"${_NB}\" notebooks status\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                        ]]\n  [[ \"${output}\" == \"$(_color_primary \"home\") is archived.\" ]]\n}\n\n@test \"'notebooks status <name>' exits with 0 and prints status.\" {\n  {\n    _setup_notebook\n  }\n\n  run \"${_NB}\" notebooks status one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                            ]]\n  [[ \"${output}\" == \"$(_color_primary \"one\") is not archived.\"  ]]\n\n  run \"${_NB}\" notebooks archive one\n  run \"${_NB}\" notebooks status one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                        ]]\n  [[ \"${output}\" == \"$(_color_primary \"one\") is archived.\"  ]]\n}\n\n# help ########################################################################\n\n@test \"'help notebooks' exits with status 0.\" {\n  run \"${_NB}\" help notebooks\n\n  [[ ${status} -eq 0                ]]\n}\n\n@test \"'help notebooks' prints help information.\" {\n  run \"${_NB}\" help notebooks\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Usage.*:      ]]\n  [[ \"${lines[1]}\" =~ nb\\ notebook  ]]\n}\n"
  },
  {
    "path": "test/notebooks-rename.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebooks() {\n  \"${_NB}\" init\n\n  mkdir -p \"${NB_DIR}/one\"\n\n  cd \"${NB_DIR}/one\" || return 1\n\n  git init\n\n  git remote add origin \"${_GIT_REMOTE_URL}\"\n\n  touch \"${NB_DIR}/one/.index\"\n\n  mkdir -p \"${NB_DIR}/two\"\n\n  cd \"${NB_DIR}/two\" || return 1\n\n  git init\n\n  touch \"${NB_DIR}/two/.index\"\n\n  cd \"${NB_DIR}\" || return 1\n}\n\n# aliases #####################################################################\n\n@test \"'notebooks move <valid-old> <valid-new>' exits with 0 and renames notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks move \"one\" \"new-name\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[        \"${status}\" -eq 0                       ]]\n  [[        \"${output}\" =~  one                     ]]\n  [[        \"${output}\" =~  is\\ now\\ named          ]]\n  [[        \"${output}\" =~  new-name                ]]\n  [[    -e  \"${NB_DIR}/new-name/.git\"               ]]\n  [[ !  -e  \"${NB_DIR}/one\"                         ]]\n  [[        \"$(cat \"${NB_DIR}/.current\")\" == \"home\" ]]\n}\n\n@test \"'notebooks mv <valid-old> <valid-new>' exits with 0 and renames notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks mv \"one\" \"new-name\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[        \"${status}\" -eq 0                       ]]\n  [[        \"${output}\" =~  one                     ]]\n  [[        \"${output}\" =~  is\\ now\\ named          ]]\n  [[        \"${output}\" =~  new-name                ]]\n  [[    -e  \"${NB_DIR}/new-name/.git\"               ]]\n  [[ !  -e  \"${NB_DIR}/one\"                         ]]\n  [[        \"$(cat \"${NB_DIR}/.current\")\" == \"home\" ]]\n}\n\n# <name> validation ###########################################################\n\n@test \"'notebooks rename <reserved> <new>' exits with 1 and prints error message.\" {\n  {\n    \"${_NB}\" init\n\n    cd \"${_TMP_DIR}\"\n\n    _names=(\n      \".cache\"\n      \".current\"\n      \".plugins\"\n      \".readme\"\n      \"readme\"\n      \"readme.md\"\n    )\n  }\n\n  for __name in \"${_names[@]}\"\n  do\n    run \"${_NB}\" notebooks rename \"${__name}\" \"example\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ ${status} -eq 1                  ]]\n    [[ \"${lines[0]}\" =~ Name\\ reserved  ]]\n    [[ \"${lines[0]}\" =~ ${__name}       ]]\n  done\n}\n\n@test \"'notebooks rename <old> <reserved>' exits with 1 and prints error message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"example\"\n\n    cd \"${_TMP_DIR}\"\n\n    _names=(\n      \".cache\"\n      \".current\"\n      \".plugins\"\n      \".readme\"\n      \"readme\"\n      \"readme.md\"\n    )\n  }\n\n  for __name in \"${_names[@]}\"\n  do\n    run \"${_NB}\" notebooks rename \"example\" \"${__name}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ ${status} -eq 1                  ]]\n    [[ \"${lines[0]}\" =~ Name\\ reserved  ]]\n    [[ \"${lines[0]}\" =~ ${__name}       ]]\n  done\n}\n\n# `notebooks rename` ##########################################################\n\n@test \"'notebooks rename <valid-old> <valid-new>' exits with 0 and renames notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks rename \"one\" \"new-name\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${output}\" =~ one                       ]]\n  [[ \"${output}\" =~ is\\ now\\ named            ]]\n  [[ \"${output}\" =~ new-name                  ]]\n  [[ -e \"${NB_DIR}/new-name/.git\"             ]]\n  [[ ! -e \"${NB_DIR}/one\"                     ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n}\n\n@test \"'notebooks rename home <valid-new>' exits with 0,  renames notebook, and updates .current.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks rename \"home\" \"new-name\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ \"${output}\" =~ home                          ]]\n  [[ \"${output}\" =~ is\\ now\\ named                ]]\n  [[ \"${output}\" =~ new-name                      ]]\n  [[ -e \"${NB_DIR}/new-name/.git\"                 ]]\n  [[ ! -e \"${NB_DIR}/home\"                        ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"new-name\"  ]]\n}\n\n@test \"'notebooks rename <invalid-old> <valid-new>' exits with 1 and does not rename notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks rename \"invalid\" \"new-name\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                                    ]]\n  [[ \"${output}\" =~ invalid                             ]]\n  [[ \"${output}\" =~ is\\ not\\ a\\ valid\\ notebook\\ name\\. ]]\n  [[ ! -e \"${NB_DIR}/new-name/.git\"                     ]]\n  [[ -e \"${NB_DIR}/one/.git\"                            ]]\n  [[ -e \"${NB_DIR}/two\"                                 ]]\n  [[ -e \"${NB_DIR}/two/.git\"                            ]]\n  [[ -e \"${NB_DIR}/home/.git\"                           ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"            ]]\n}\n\n@test \"'notebooks rename <valid-old> <invalid-new>' exits with 1 and does not rename notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks rename \"one\" \"two\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                          ]]\n  [[ \"${output}\" =~ A\\ notebook\\ named        ]]\n  [[ \"${output}\" =~ two                       ]]\n  [[ \"${output}\" =~ lready\\ exists\\.          ]]\n  [[ -e \"${NB_DIR}/one/.git\"                  ]]\n  [[ -e \"${NB_DIR}/two\"                       ]]\n  [[ -e \"${NB_DIR}/two/.git\"                  ]]\n  [[ -e \"${NB_DIR}/home/.git\"                 ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n}\n\n@test \"'notebooks rename local <new-name>' in local exits with 1.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add local\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\"  ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n\n    [[ -e \"${NB_DIR}/local\"               ]]\n  }\n\n  run \"${_NB}\" notebooks rename local new-name\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                            ]]\n  [[ \"${lines[0]}\" =~ can\\ not\\ be\\ renamed\\.   ]]\n  [[ -e \"${NB_DIR}/local\"                       ]]\n}\n\n@test \"'notebooks rename local <new-name>' outside local deletes.\" {\n  {\n    _pwd=\"${PWD}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add local\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\"  ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n\n    cd \"${_pwd}\" || return 1\n\n    [[ -e \"${NB_DIR}/local\"               ]]\n  }\n\n  run \"${_NB}\" notebooks rename local new-name\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                  ]]\n  [[ \"${lines[0]}\" =~ is\\ now\\ named  ]]\n  [[ ! -e \"${NB_DIR}/local\"           ]]\n  [[ -e \"${NB_DIR}/new-name\"          ]]\n}\n"
  },
  {
    "path": "test/notebooks-show.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# show <full-paths> ###########################################################\n\n@test \"'notebooks show <notebook-path>/<folder-path> --path' with conflicting folder and notebook names exits with 0 and prints the notebook path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Folder\"\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder/Example File.md\"  \\\n      --content \"Example file content.\"\n  }\n\n  run \"${_NB}\" notebooks show \"${NB_DIR}/Example Notebook/Example Folder\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                             ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/Example Notebook\"  ]]\n}\n\n@test \"'notebooks show <notebook-path>/<folder-path>/<filename> --path' exits with 0 and prints the notebook path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder/Example File.md\"  \\\n      --content \"Example file content.\"\n  }\n\n  run \"${_NB}\" notebooks show                                       \\\n    \"${NB_DIR}/Example Notebook/Example Folder/Example File.md\"     \\\n    --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                             ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/Example Notebook\"  ]]\n}\n\n@test \"'notebooks show <notebook-path>/<folder-path> --path' exits with 0 and prints the notebook path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder/Example File.md\" \\\n      --content \"Example file content.\"\n  }\n\n  run \"${_NB}\" notebooks show \"${NB_DIR}/Example Notebook/Example Folder\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                             ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/Example Notebook\"  ]]\n}\n\n@test \"'notebooks show <notebook-path> --path' (no slash) exits with 0 and prints the notebook path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" notebooks show \"${NB_DIR}/Example Notebook\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                             ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/Example Notebook\"  ]]\n}\n\n@test \"'notebooks show <notebook-path>/ --path' (slash) exits with 0 and prints the notebook path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" notebooks show \"${NB_DIR}/Example Notebook/\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                             ]]\n  [[ \"${output}\"  ==  \"${NB_DIR}/Example Notebook\"  ]]\n}\n\n# local #######################################################################\n\n@test \"'notebooks show <local-full-path> --name' exits with 0 and prints 'local'.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n  }\n\n  run \"${_NB}\" notebooks show \"${_TMP_DIR}/example-local\" --name\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0       ]]\n  [[ \"${output}\"  ==  \"local\" ]]\n}\n\n@test \"'notebooks show <local-full-path> --name' exits with 0 and prints 'local' when not local.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n  }\n\n  run \"${_NB}\" notebooks show \"${_TMP_DIR}/example-local\" --name\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0       ]]\n  [[ \"${output}\"  ==  \"local\" ]]\n}\n\n@test \"'notebooks show <local-item-full-path> --name' exits with 0 and prints 'local' when not local.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example-local.md\" --content \"Example local content.\"\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}\" ]]\n  }\n\n  run \"${_NB}\" notebooks show                                                 \\\n    \"${_TMP_DIR}/example-local/Example Folder/Sample Folder/example-local.md\" \\\n    --name\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0       ]]\n  [[ \"${output}\"  ==  \"local\" ]]\n}\n\n@test \"'notebooks show <local-full-path> --path' exits with 0 and prints the local notebook path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n  }\n\n  run \"${_NB}\" notebooks show \"${_TMP_DIR}/example-local\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${output}\" == \"${_TMP_DIR}/example-local\" ]]\n}\n\n@test \"'notebooks show <local-full-path> --path' exits with 0 and prints the local notebook path when not local.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n  }\n\n  run \"${_NB}\" notebooks show \"${_TMP_DIR}/example-local\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${output}\" == \"${_TMP_DIR}/example-local\" ]]\n}\n\n@test \"'notebooks show <local-item-full-path> --path' exits with 0 and prints the local notebook item path when not local.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/example-local.md\" --content \"Example local content.\"\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}\" ]]\n  }\n\n  run \"${_NB}\" notebooks show \"${_TMP_DIR}/example-local/Example Folder/Sample Folder/example-local.md\" \\\n    --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${output}\" == \"${_TMP_DIR}/example-local\" ]]\n}\n\n# `notebooks show` ############################################################\n\n@test \"'notebooks show <notebook>:<folder-id>/<filename> --path' exits with status 0 and prints path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add  \"Example Notebook:Sample Folder/Example File.md\"  \\\n      --title     \"Example Title\"                                   \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" notebooks show \"Example Notebook:1/Example File.md\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  =~  1                           ]]\n  [[    \"${lines[0]}\"   =~  ${NB_DIR}/Example\\ Notebook ]]\n}\n\n@test \"'notebooks show <full-path>' exits with 0 and prints the notebook name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n  }\n\n  run \"${_NB}\" notebooks show \"${NB_DIR}/one\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0      ]]\n  [[ \"${output}\" == \"one\" ]]\n}\n\n@test \"'notebooks show' with no id exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n  }\n\n  run \"${_NB}\" notebooks show\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1      ]]\n  [[ \"${output}\" =~ Usage ]]\n}\n\n@test \"'notebooks show example' with exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n  }\n\n  run \"${_NB}\" notebooks show example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                      ]]\n  [[ \"${output}\" =~ Notebook\\ not\\ found  ]]\n  [[ \"${output}\" =~ example               ]]\n}\n\n@test \"'notebooks show <name>' exits with 0 and prints the notebook name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n  }\n\n  run \"${_NB}\" notebooks show one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0      ]]\n  [[ \"${output}\" == \"one\" ]]\n}\n\n@test \"'notebooks show <path>' exits with 0 and prints the notebook name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n  }\n\n  run \"${_NB}\" notebooks show \"${NB_DIR}/one\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0      ]]\n  [[ \"${output}\" == \"one\" ]]\n}\n\n@test \"'notebooks show <selector>' exits with 0 and prints the notebook name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n  }\n\n  run \"${_NB}\" notebooks show one:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0    ]]\n  [[ \"${output}\" =~ one ]]\n\n  run \"${_NB}\" notebooks show one:example.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0    ]]\n  [[ \"${output}\" =~ one ]]\n}\n\n# `notebooks show --path` #####################################################\n\n@test \"'notebooks show --path' with exits with 0 and prints path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n  }\n\n  run \"${_NB}\" notebooks show one --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${output}\" == \"${NB_DIR}/one\" ]]\n}\n\n# `notebooks show --escaped` ##################################################\n\n@test \"'notebooks show --escaped' with exits with 0 and prints display name.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"long example\"\n  }\n\n  run \"${_NB}\" notebooks show \"long example\" --escaped\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${output}\" == \"long\\ example\" ]]\n}\n\n# `notebooks show --filename` #################################################\n\n@test \"'notebooks show --filename' prints a unique filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" notebooks show \"home\" --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${lines[0]}\" =~ ^[0-9]+.md  ]]\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\"\n\n  run \"${_NB}\" notebooks show \"home\" --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${lines[0]}\" =~ ^[0-9]+.md  ]]\n}\n\n@test \"'notebooks show --filename <filename>' prints a unique filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --content \"Example\"\n  }\n\n  run \"${_NB}\" notebooks show \"home\" --filename \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ example-1.md  ]]\n\n  run \"${_NB}\" add \"example.md\" --content \"Example\"\n\n  run \"${_NB}\" notebooks show \"home\" --filename \"example.md\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}: '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ example-2.md  ]]\n}\n"
  },
  {
    "path": "test/notebooks-use.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebooks() {\n  \"${_NB}\" init\n  mkdir -p \"${NB_DIR}/one\"\n  cd \"${NB_DIR}/one\" || return 1\n  git init\n  git remote add origin \"${_GIT_REMOTE_URL}\"\n  touch \"${NB_DIR}/one/.index\"\n  mkdir -p \"${NB_DIR}/two\"\n  cd \"${NB_DIR}\" || return 1\n}\n\n# <name> validation ###########################################################\n\n@test \"'notebooks use <reserved>' exits with 1 and prints error message.\" {\n  {\n    \"${_NB}\" init\n\n    cd \"${_TMP_DIR}\"\n\n    _names=(\n      \".cache\"\n      \".current\"\n      \".plugins\"\n      \".readme\"\n      \"readme\"\n      \"readme.md\"\n    )\n  }\n\n  for __name in \"${_names[@]}\"\n  do\n    run \"${_NB}\" notebooks use \"${__name}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ ${status} -eq 1                  ]]\n    [[ \"${lines[0]}\" =~ Name\\ reserved  ]]\n    [[ \"${lines[0]}\" =~ ${__name}       ]]\n  done\n}\n\n# `notebooks use <name>` ######################################################\n\n@test \"'notebooks use' exits with 1 and prints error message.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks use\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".current: %s\\\\n\" \"$(cat \"${NB_DIR}/.current\")\"\n\n  [[ ${status} -eq 1                                  ]]\n  [[ \"${lines[1]}\" =~ \\ \\ nb\\ notebooks               ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"          ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'NB_NOTEBOOK_PATH=${NB_DIR}/home'\" \"'${lines[2]}'\"\n\n  [[ \"${output}\" =~ NB_NOTEBOOK_PATH=${NB_DIR}/home   ]]\n}\n\n@test \"'notebooks use <invalid>' exits with 1 and prints error message.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks use not-a-notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".current: %s\\\\n\" \"$(cat \"${NB_DIR}/.current\")\"\n\n  [[ ${status} -eq 1                          ]]\n  [[ \"${lines[0]}\" =~ Not\\ found              ]]\n  [[ \"${lines[0]}\" =~ not-a-notebook          ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'NB_NOTEBOOK_PATH=${NB_DIR}/home'\" \"'${lines[2]}'\"\n\n  [[ \"${output}\" =~ NB_NOTEBOOK_PATH=${NB_DIR}/home ]]\n}\n\n@test \"'notebooks use <name>' exits with 0 and sets <name> in .current.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks use one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'Now using: $(_color_primary 'one')'\" \"'${output}'\"\n\n  [[ ${status} -eq 0                                      ]]\n  [[ \"${output}\" == \"Now using: $(_color_primary 'one')\"  ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"one\"               ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'NB_NOTEBOOK_PATH=${NB_DIR}/one'\" \"'${lines[2]}'\"\n\n  [[ \"${output}\" =~ NB_NOTEBOOK_PATH=${NB_DIR}/one ]]\n}\n\n@test \"'notebooks use <name>:' exits with 0 and sets <name> in .current.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks use one:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'Now using: $(_color_primary 'one')'\" \"'${output}'\"\n\n  [[ ${status} -eq 0                        ]]\n  [[ \"${output}\" =~ Now\\ using:             ]]\n  [[ \"${output}\" =~ one                     ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"one\" ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'NB_NOTEBOOK_PATH=${NB_DIR}/one'\" \"'${lines[2]}'\"\n\n  [[ \"${output}\" =~ NB_NOTEBOOK_PATH=${NB_DIR}/one ]]\n}\n\n@test \"'notebooks use <name>:' exits with 0, sets the current notebook, and loads local .nbrc.\" {\n  {\n    _setup_notebooks\n\n    touch \"${NB_DIR}/one/.nbrc\"\n\n    cat <<HEREDOC > \"${NB_DIR}/one/.nbrc\"\nNB_DEFAULT_EXTENSION=\"adoc\"\nHEREDOC\n  }\n\n  run \"${_NB}\" notebooks use one:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'Now using: $(_color_primary 'one')'\" \"'${output}'\"\n\n  [[ ${status} -eq 0                        ]]\n  [[ \"${output}\" =~ Now\\ using:             ]]\n  [[ \"${output}\" =~ one                     ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"one\" ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'NB_NOTEBOOK_PATH=${NB_DIR}/one'\" \"'${lines[2]}'\"\n  _compare \"'NB_DEFAULT_EXTENSION=adoc'\"      \"'${lines[8]}'\"\n\n  [[ \"${output}\" =~ NB_NOTEBOOK_PATH=${NB_DIR}/one  ]]\n  [[ \"${output}\" =~ \"NB_DEFAULT_EXTENSION=adoc\"      ]]\n}\n\n@test \"'notebooks use' in local exits with 1 and prints error message.\" {\n  {\n    _setup_notebooks\n\n    mkdir -p \"${_TMP_DIR}/example\"\n    cd \"${_TMP_DIR}/example\"\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n\n  }\n\n  run \"${_NB}\" notebooks use one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".current: %s\\\\n\" \"$(cat \"${NB_DIR}/.current\")\"\n\n  [[ ${status} -eq 1                          ]]\n  [[ \"${lines[0]}\" =~ in\\ a\\ local\\ notebook  ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'NB_NOTEBOOK_PATH=${_TMP_DIR}/example'\" \"'${lines[2]}'\"\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\" ]]\n\n  [[ \"${output}\" =~ NB_NOTEBOOK_PATH=${_TMP_DIR}/example ]]\n}\n"
  },
  {
    "path": "test/notebooks.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_notebooks() {\n  \"${_NB}\" init\n\n  mkdir -p \"${NB_DIR}/one\"\n  cd \"${NB_DIR}/one\" || return 1\n  git init\n  git remote add origin \"${_GIT_REMOTE_URL}\"\n  touch \"${NB_DIR}/one/.index\"\n\n  cd \"${NB_DIR}\" || return 1\n}\n\n# --archived / --unarchived ###################################################\n\n@test \"'notebooks --archived' works with filtering.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Query Notebook\"\n    \"${_NB}\" notebooks add \"Demo Query Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" archive \"Sample Query Notebook\"\n    \"${_NB}\" archive \"Demo Query Notebook\"\n    \"${_NB}\" archive \"Test Notebook\"\n  }\n\n  run \"${_NB}\" notebooks --archived query\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                                      ]]\n  [[    \"${#lines[@]}\" -eq 2                                      ]]\n\n  [[ !  \"${output}\"    =~  home                                   ]]\n  [[ !  \"${output}\"    =~  Example\\ Notebook                      ]]\n  [[    \"${output}\"    =~  Sample\\ Query\\ Notebook\\ \\(archived\\)  ]]\n  [[    \"${output}\"    =~  Demo\\ Query\\ Notebook\\ \\(archived\\)    ]]\n  [[ !  \"${output}\"    =~  Test\\ Notebook                         ]]\n}\n\n@test \"'notebooks --ar' exits with 0 and prints archived notebooks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" archive \"Sample Notebook\"\n    \"${_NB}\" archive \"Test Notebook\"\n  }\n\n  run \"${_NB}\" notebooks --ar\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                              ]]\n  [[    \"${#lines[@]}\" -eq 2                              ]]\n\n  [[ !  \"${output}\"    =~  home                           ]]\n  [[ !  \"${output}\"    =~  Example\\ Notebook              ]]\n  [[    \"${output}\"    =~  Sample\\ Notebook\\ \\(archived\\) ]]\n  [[ !  \"${output}\"    =~  Demo\\ Notebook                 ]]\n  [[    \"${output}\"    =~  Test\\ Notebook\\ \\(archived\\)   ]]\n}\n\n@test \"'notebooks --archived' exits with 0 and prints archived notebooks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" archive \"Sample Notebook\"\n    \"${_NB}\" archive \"Test Notebook\"\n  }\n\n  run \"${_NB}\" notebooks --archived\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                              ]]\n  [[    \"${#lines[@]}\" -eq 2                              ]]\n\n  [[ !  \"${output}\"    =~  home                           ]]\n  [[ !  \"${output}\"    =~  Example\\ Notebook              ]]\n  [[    \"${output}\"    =~  Sample\\ Notebook\\ \\(archived\\) ]]\n  [[ !  \"${output}\"    =~  Demo\\ Notebook                 ]]\n  [[    \"${output}\"    =~  Test\\ Notebook\\ \\(archived\\)   ]]\n}\n\n@test \"'notebooks --unarchived' exits with 0 and prints unarchived notebooks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" archive \"Sample Notebook\"\n    \"${_NB}\" archive \"Test Notebook\"\n  }\n\n  run \"${_NB}\" notebooks --unarchived\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                  ]]\n  [[    \"${#lines[@]}\" -eq 3                  ]]\n\n  [[    \"${output}\"    =~  home               ]]\n  [[    \"${output}\"    =~  Example\\ Notebook  ]]\n  [[ !  \"${output}\"    =~  Sample\\ Notebook   ]]\n  [[    \"${output}\"    =~  Demo\\ Notebook     ]]\n  [[ !  \"${output}\"    =~  Test\\ Notebook     ]]\n}\n\n@test \"'notebooks --unar' exits with 0 and prints unarchived notebooks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks add \"Test Notebook\"\n\n    \"${_NB}\" archive \"Sample Notebook\"\n    \"${_NB}\" archive \"Test Notebook\"\n  }\n\n  run \"${_NB}\" notebooks --unar\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0                  ]]\n  [[    \"${#lines[@]}\" -eq 3                  ]]\n\n  [[    \"${output}\"    =~  home               ]]\n  [[    \"${output}\"    =~  Example\\ Notebook  ]]\n  [[ !  \"${output}\"    =~  Sample\\ Notebook   ]]\n  [[    \"${output}\"    =~  Demo\\ Notebook     ]]\n  [[ !  \"${output}\"    =~  Test\\ Notebook     ]]\n}\n\n# notebook name filtering #####################################################\n\n@test \"'notebooks --not-valid-option-or-query' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example One\"\n    \"${_NB}\" notebooks add \"Example Two\"\n    \"${_NB}\" notebooks add \"Example Three\"\n\n    \"${_NB}\" notebooks add \"Sample One\"\n    \"${_NB}\" notebooks add \"Sample Two\"\n\n    \"${_NB}\" notebooks add \"Demo One\"\n    \"${_NB}\" notebooks add \"Demo Two\"\n  }\n\n  run \"${_NB}\" notebooks --not-valid-option-or-query\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${output}\"    =~  \\\n\\!.*\\ Notebook\\ not\\ found:\\ .*--not-valid-option-or-query ]]\n}\n\n@test \"'notebooks <query> --path' exits with 0 and prints matching notebook paths.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example One\"\n    \"${_NB}\" notebooks add \"Example Two\"\n    \"${_NB}\" notebooks add \"Example Three\"\n\n    \"${_NB}\" notebooks add \"Sample One\"\n    \"${_NB}\" notebooks add \"Sample Two\"\n\n    \"${_NB}\" notebooks add \"Demo One\"\n    \"${_NB}\" notebooks add \"Demo Two\"\n  }\n\n  run \"${_NB}\" notebooks example --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${output}\"    =~  ${NB_DIR}/Example\\ Three  ]]\n  [[ \"${output}\"    =~  ${NB_DIR}/Example\\ Two    ]]\n  [[ \"${output}\"    =~  ${NB_DIR}/Example\\ One    ]]\n\n  run \"${_NB}\" notebooks two --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${output}\"    =~  ${NB_DIR}/Example\\ Two    ]]\n  [[ \"${output}\"    =~  ${NB_DIR}/Sample\\ Two     ]]\n  [[ \"${output}\"    =~  ${NB_DIR}/Demo\\ Two       ]]\n\n  run \"${_NB}\" notebooks no-match --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${output}\"    =~  \\!.*\\ Notebook\\ not\\ found:\\ .*no-match ]]\n}\n\n@test \"'notebooks <query> --name' exits with 0 and prints matching notebook names.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example One\"\n    \"${_NB}\" notebooks add \"Example Two\"\n    \"${_NB}\" notebooks add \"Example Three\"\n\n    \"${_NB}\" notebooks add \"Sample One\"\n    \"${_NB}\" notebooks add \"Sample Two\"\n\n    \"${_NB}\" notebooks add \"Demo One\"\n    \"${_NB}\" notebooks add \"Demo Two\"\n  }\n\n  run \"${_NB}\" notebooks example --name\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${#lines[@]}\" -eq 3               ]]\n\n  [[ \"${output}\"    =~  Example\\ Three  ]]\n  [[ \"${output}\"    =~  Example\\ Two    ]]\n  [[ \"${output}\"    =~  Example\\ One    ]]\n\n  run \"${_NB}\" notebooks two --name\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${#lines[@]}\" -eq 3               ]]\n\n  [[ \"${output}\"    =~  Example\\ Two    ]]\n  [[ \"${output}\"    =~  Sample\\ Two     ]]\n  [[ \"${output}\"    =~  Demo\\ Two       ]]\n\n  run \"${_NB}\" notebooks no-match --name\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1               ]]\n  [[ \"${#lines[@]}\" -eq 1               ]]\n\n  [[ \"${output}\"    =~  \\!.*\\ Notebook\\ not\\ found:\\ .*no-match ]]\n}\n\n@test \"'notebooks <query>' exits with 0 and prints matching notebook names.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example One\"\n    \"${_NB}\" notebooks add \"Example Two\"\n    \"${_NB}\" notebooks add \"Example Three\"\n\n    \"${_NB}\" notebooks add \"Sample One\"\n    \"${_NB}\" notebooks add \"Sample Two\"\n\n    \"${_NB}\" notebooks add \"Demo One\"\n    \"${_NB}\" notebooks add \"Demo Two\"\n  }\n\n  run \"${_NB}\" notebooks example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${#lines[@]}\" -eq 3               ]]\n\n  [[ \"${output}\"    =~  Example\\ Three  ]]\n  [[ \"${output}\"    =~  Example\\ Two    ]]\n  [[ \"${output}\"    =~  Example\\ One    ]]\n\n  run \"${_NB}\" notebooks two\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${#lines[@]}\" -eq 3               ]]\n\n  [[ \"${output}\"    =~  Example\\ Two    ]]\n  [[ \"${output}\"    =~  Sample\\ Two     ]]\n  [[ \"${output}\"    =~  Demo\\ Two       ]]\n\n  run \"${_NB}\" notebooks no-match\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1               ]]\n  [[ \"${#lines[@]}\" -eq 1               ]]\n\n  [[ \"${output}\"    =~  \\!.*\\ Notebook\\ not\\ found:\\ .*no-match ]]\n}\n\n@test \"'notebooks <name>:' with colon exits with 0 and prints matching notebook names.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n\n  }\n\n  run \"${_NB}\" notebooks Sample\\ Notebook:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                 ]]\n  [[    \"${#lines[@]}\"  -eq 1                 ]]\n\n  [[    \"${lines[0]}\"   =~  Sample\\ Notebook  ]]\n  [[ !  \"${output}\"     =~  Example\\ Notebook ]]\n  [[ !  \"${output}\"     =~  Demo\\ Notebook    ]]\n\n  run \"${_NB}\" notebooks Sample\\ Notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                 ]]\n  [[    \"${#lines[@]}\"  -eq 1                 ]]\n\n  [[    \"${lines[0]}\"   =~  Sample\\ Notebook  ]]\n  [[ !  \"${output}\"     =~  Example\\ Notebook ]]\n  [[ !  \"${output}\"     =~  Demo\\ Notebook    ]]\n}\n\n# `notebooks` #################################################################\n\n@test \"'notebooks' exits with 0 and prints all notebook names.\" {\n  {\n    _setup_notebooks\n    _expected=\"$(_color_primary 'home' --underline)\none (${_GIT_REMOTE_URL})\"\n  }\n\n  NB_COLOR_HIGHLIGHT=3 run \"${_NB}\" notebooks\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_expected}: '%s'\\\\n\" \"${_expected}\"\n\n  [[ \"${status}\"  -eq 0               ]]\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n}\n\n@test \"'notebooks <name>' exits with 0 and prints the given notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"one (${_GIT_REMOTE_URL})\"\n\n  [[ \"${status}\"  -eq 0               ]]\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n}\n\n@test \"'notebooks <name> <name>' exits with 0 and prints the given notebooks.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks one home\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"one (${_GIT_REMOTE_URL})\n$(_color_primary 'home' --underline)\"\n  _compare \"${_expected}\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0               ]]\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n}\n\n@test \"'notebooks <invalid>' exits with 1 and prints the given notebook.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 1                     ]]\n  [[ \"${output}\"  =~  Notebook\\ not\\ found  ]]\n}\n\n@test \"'notebooks <name> --names' exits with 0 and prints the given notebook name.\" {\n  {\n    _setup_notebooks\n\n    _expected=\"$(_color_primary 'home')\"\n  }\n\n  run \"${_NB}\" notebooks home --names\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_expected}: '%s'\\\\n\" \"${_expected}\"\n\n  [[ \"${status}\"  -eq 0               ]]\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n}\n\n@test \"'notebooks --names' exits with 0 and prints all notebook names.\" {\n  {\n    _setup_notebooks\n    _expected=\"$(_color_primary 'home' --underline)\none\"\n  }\n\n  run \"${_NB}\" notebooks --names\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_expected}: '%s'\\\\n\" \"${_expected}\"\n\n  [[ \"${status}\"  -eq 0               ]]\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n}\n\n@test \"'notebooks --no-color' exits with 0 and prints all notebook names with no highlighting.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"home\none (${_GIT_REMOTE_URL})\"\n\n  [[ \"${status}\"  -eq 0               ]]\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n}\n\n@test \"'notebooks <name> --no-color' exits with 0 and prints the given notebook name with no highlighting.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks home --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"home\"\n\n  [[ \"${status}\"  -eq 0               ]]\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n}\n\n@test \"'notebooks --names --no-color' exits with 0 and prints all notebook names with no highlighting.\" {\n  {\n    _setup_notebooks\n  }\n\n  run \"${_NB}\" notebooks --names --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"home\none\"\n\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n  [[ \"${status}\"  -eq 0               ]]\n}\n\n@test \"'notebooks --names --no-color --archived' exits with 0 and prints archived.\" {\n  {\n    _setup_notebooks\n    \"${_NB}\" one:notebook archive\n  }\n\n  run \"${_NB}\" notebooks --names --no-color --archived\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"one\"\n\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n  [[ \"${status}\"  -eq 0               ]]\n}\n\n@test \"'notebooks --names --no-color --unarchived' exits with 0 and prints unarchived.\" {\n  {\n    _setup_notebooks\n    \"${_NB}\" one:notebook archive\n  }\n\n  run \"${_NB}\" notebooks --names --no-color --unarchived\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"home\"\n\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n  [[ \"${status}\"  -eq 0               ]]\n}\n\n@test \"'notebooks --names --no-color' prints local and global.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\"   ==  \"${_TMP_DIR}/example-local\" ]]\n  }\n\n  run \"${_NB}\" notebooks --names --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"local\nhome\none\"\n\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n  [[ \"${status}\"  -eq 0               ]]\n}\n\n@test \"'notebooks --names --no-color --local' exits with 0 and prints local.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\"   ==  \"${_TMP_DIR}/example-local\" ]]\n  }\n\n  run \"${_NB}\" notebooks --names --no-color --local\n\n  printf \"\\${PWD}: %s\\\\n\" \"${PWD}\"\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"local\"\n\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n  [[ \"${status}\"  -eq 0               ]]\n}\n\n@test \"'notebooks --names --no-color --local' with no local exits with 1.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\"   ==  \"${_TMP_DIR}\"   ]]\n  }\n\n  run \"${_NB}\" notebooks --names --no-color --local\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ -z \"${output}\"       ]]\n  [[    \"${status}\" -eq 1 ]]\n}\n\n@test \"'notebooks --names --no-color --global' exits with 0 and prints global.\" {\n  {\n    _setup_notebooks\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n  }\n\n  run \"${_NB}\" notebooks --names --no-color --global\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"home\none\"\n\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n  [[ \"${status}\"  -eq 0               ]]\n}\n\n# `notebooks --paths` #########################################################\n\n@test \"'notebooks --paths' prints local and global.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\"   ==  \"${_TMP_DIR}/example-local\" ]]\n  }\n\n  run \"${_NB}\" notebooks --paths\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"${_TMP_DIR}/example-local\n${NB_DIR}/home\n${NB_DIR}/one\"\n\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n  [[ \"${status}\"  -eq 0               ]]\n}\n\n@test \"'notebooks --paths --local' exits with 0 and prints local.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\"   ==  \"${_TMP_DIR}/example-local\" ]]\n  }\n\n  run \"${_NB}\" notebooks --paths --local\n\n  printf \"\\${PWD}: %s\\\\n\" \"${PWD}\"\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"${_TMP_DIR}/example-local\"\n\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n  [[ \"${status}\"  -eq 0               ]]\n}\n\n@test \"'notebooks --paths --local' with no local exits with 1.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}\"\n\n    [[ \"$(pwd)\"     ==  \"${_TMP_DIR}\" ]]\n  }\n\n  run \"${_NB}\" notebooks --paths --local\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ -z \"${output}\"                   ]]\n  [[    \"${status}\" -eq 1             ]]\n}\n\n@test \"'notebooks --paths --global' exits with 0 and prints global.\" {\n  {\n    _setup_notebooks\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n  }\n\n  run \"${_NB}\" notebooks --paths --global\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  _expected=\"${NB_DIR}/home\n${NB_DIR}/one\"\n\n  [[ \"${output}\"  ==  \"${_expected}\"  ]]\n  [[ \"${status}\"  -eq 0               ]]\n}\n\n# help ########################################################################\n\n@test \"'help notebooks' exits with status 0.\" {\n  run \"${_NB}\" help notebooks\n\n  [[ \"${status}\"    -eq 0                 ]]\n}\n\n@test \"'help notebooks' prints help information.\" {\n  run \"${_NB}\" help notebooks\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\"  =~  Usage.*:          ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ notebooks ]]\n}\n"
  },
  {
    "path": "test/open.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# error handling ##############################################################\n\n@test \"'open' with no selector with exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" open\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq  1         ]]\n\n  [[    \"${lines[0]}\"   =~  Usage     ]]\n  [[    \"${lines[1]}\"   =~  nb\\ open  ]]\n}\n"
  },
  {
    "path": "test/pin-unpin.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# search-based pinning integration ############################################\n\n@test \"'pin' integrates with search-based pinning and preserves .pindex order.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"   --content \"#pinned\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin 1\n    \"${_NB}\" pin 4\n\n    diff                                        \\\n      <(printf \"File One.md\\\\nFile Four.md\\\\n\") \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 4                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*4.*].*\\ 📌\\ Title\\ Four ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ 📌\\ Title\\ Two  ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n}\n\n@test \"'pin' and search-based pinning preserve .pindex order and don't duplicate pinned entries.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"   --content \"#pinned\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin 1\n    \"${_NB}\" pin 4\n\n    diff                                        \\\n      <(printf \"File One.md\\\\nFile Four.md\\\\n\") \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  NB_PINNED_PATTERN=\"#pinned\" run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 4                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*4.*].*\\ 📌\\ Title\\ Four ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n}\n\n# error handling ##############################################################\n\n@test \"'pin' with not-valid selector prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n\n    diff                              \\\n      <(printf \"%s\\\\n\" \"File One.md\") \\\n      <(cat \"${NB_DIR}/home/.pindex\") || return 0\n  }\n\n  run \"${_NB}\" pin not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # exits with status 1\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # does not change pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\") || return 0\n\n  # prints message\n\n  [[ \"${output}\" =~ Not\\ found:\\ .*not-valid ]]\n\n  # does not create  git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: File One.md' || return 0\n}\n\n@test \"'unpin' with not-valid selector prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n\n    \"${_NB}\" pin \"File One.md\"\n\n    diff                              \\\n      <(printf \"%s\\\\n\" \"File One.md\") \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  run \"${_NB}\" unpin not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # exits with status 1\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # does not change pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  # prints message\n\n  [[ \"${output}\" =~ Not\\ found:\\ .*not-valid ]]\n\n  # does not create  git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: File One.md' || return 0\n}\n\n@test \"'pin' with already-pinned selector exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title One\"\n\n    \"${_NB}\" pin \"File One.md\"\n\n    diff                              \\\n      <(printf \"%s\\\\n\" \"File One.md\") \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  run \"${_NB}\" pin File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # exits with status 1\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # does not change pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  # prints message\n\n  [[ \"${output}\" =~ Already\\ pinned:\\ .*File\\ One.md ]]\n\n  # does not create  git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  [[ \"$(git log | grep -c '\\[nb\\] Pinned: File One.md')\" -eq 1 ]]\n}\n\n@test \"'unpin' with not-pinned selector prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title One\"\n\n    \"${_NB}\" pin \"File One.md\"\n\n    diff                              \\\n      <(printf \"%s\\\\n\" \"File One.md\") \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  run \"${_NB}\" unpin File\\ Two.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # exits with status 1\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # does not change pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  # prints message\n\n  [[ \"${output}\" =~ Not\\ pinned:\\ .*File\\ Two.md ]]\n\n  # does not create  git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: File Two.md' || return 0\n}\n\n@test \"'pin' with no selector prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\"  --type folder\n\n    diff                                  \\\n      <(printf \"%s\\\\n\" \"Example Folder\")  \\\n      <(cat \"${NB_DIR}/home/.pindex\") || return 0\n  }\n\n  run \"${_NB}\" pin\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # exits with status 1\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # does not change pindex\n\n  diff                                  \\\n    <(printf \"%s\\\\n\" \"Example Folder\")  \\\n    <(cat \"${NB_DIR}/home/.pindex\") || return 0\n\n  # prints help\n\n  [[ \"${output}\" =~ Usage.*:    ]]\n  [[ \"${output}\" =~ nb\\ pin     ]]\n\n\n  # does not create  git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: Example Folder' || return 0\n}\n\n@test \"'unpin' with no selector prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder\"  --type folder\n\n    \"${_NB}\" pin \"Example Folder\"\n\n    diff                                  \\\n      <(printf \"%s\\\\n\" \"Example Folder\")  \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  run \"${_NB}\" unpin\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # exits with status 1\n\n  [[ \"${status}\" -eq 1 ]]\n\n  # does not change pindex\n\n  diff                                  \\\n    <(printf \"%s\\\\n\" \"Example Folder\")  \\\n    <(cat \"${NB_DIR}/home/.pindex\") || return 0\n\n  # prints help\n\n  [[ \"${output}\" =~ Usage.*:    ]]\n  [[ \"${output}\" =~ nb\\ unpin   ]]\n\n\n  # does not create  git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: Example Folder' || return 0\n}\n\n# pin / unpin #################################################################\n\n@test \"'pin <filename>' and 'unpin <filename>' pin and unpin items.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n  }\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 3                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n\n  # `pin` an item\n\n  run \"${_NB}\" pin File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  [[ \"$(wc -l < \"${NB_DIR}/home/.pindex\")\"  -eq 1               ]]\n  [[ \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  ^File\\ One.md$  ]]\n\n  # prints output\n\n  [[ \"${output}\" =~ Pinned:\\ .*[.*1.*].*\\ 📌\\ .*File\\ One.md    ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: File One.md'\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n\n  # `pin` an item\n\n  run \"${_NB}\" pin File\\ Two.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md${_NEWLINE}File Two.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  [[ \"$(wc -l < \"${NB_DIR}/home/.pindex\")\"  -eq 2             ]]\n  [[ \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  File\\ One.md  ]]\n  [[ \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  File\\ Two.md  ]]\n\n  # prints output\n\n  [[ \"${output}\" =~ Pinned:\\ .*[.*2.*].*\\ 📌\\ .*File\\ Two.md  ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: File Two.md'\n\n  # `list` with two pinned items\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ 📌\\ Title\\ Two  ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n\n  # `unpin` an item\n\n  run \"${_NB}\" unpin File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File Two.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  [[    \"$(wc -l < \"${NB_DIR}/home/.pindex\")\"  -eq 1              ]]\n  [[ !  \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  File\\ One.md   ]]\n  [[    \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  File\\ Two.md   ]]\n\n  # prints output\n\n  [[    \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ .*File\\ One.md     ]]\n  [[ !  \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ 📌\\ .*File\\ One.md ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: File One.md'\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*2.*].*\\ 📌\\ Title\\ Two  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*1.*].*\\ Title\\ One      ]]\n}\n\n# pin #########################################################################\n\n@test \"'pin <filename>' adds an item to the folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n  }\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 3                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n\n  # `pin` an item\n\n  run \"${_NB}\" pin File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  [[ \"$(wc -l < \"${NB_DIR}/home/.pindex\")\"  -eq 1               ]]\n  [[ \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  ^File\\ One.md$  ]]\n\n  # prints output\n\n  [[ \"${output}\" =~ Pinned:\\ .*[.*1.*].*\\ 📌\\ .*File\\ One.md    ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: File One.md'\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n}\n\n@test \"'pin <id>' adds an item to the folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n  }\n\n  run \"${_NB}\" pin 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  [[ \"$(wc -l < \"${NB_DIR}/home/.pindex\")\"  -eq 1               ]]\n  [[ \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  ^File\\ One.md$  ]]\n\n  # prints output\n\n  [[ \"${output}\" =~ Pinned:\\ .*[.*1.*].*\\ 📌\\ .*File\\ One.md    ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: File One.md'\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n}\n\n@test \"'pin <title>' adds an item to the folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n  }\n\n  run \"${_NB}\" pin Title\\ One\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  [[ \"$(wc -l < \"${NB_DIR}/home/.pindex\")\"  -eq 1               ]]\n  [[ \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  ^File\\ One.md$  ]]\n\n  # prints output\n\n  [[ \"${output}\" =~ Pinned:\\ .*[.*1.*].*\\ 📌\\ .*File\\ One.md    ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: File One.md'\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n}\n\n@test \"'pin <folder-name>' adds a folder to the parent folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder\" --type  \"folder\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n  }\n\n  run \"${_NB}\" pin Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                                  \\\n    <(printf \"%s\\\\n\" \"Example Folder\")  \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  [[ \"$(wc -l < \"${NB_DIR}/home/.pindex\")\"  -eq 1                 ]]\n  [[ \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  Example\\ Folder$  ]]\n\n  # prints output\n\n  [[ \"${output}\" =~ Pinned:\\ .*[.*3.*].*\\ 📌\\ .*Example\\ Folder   ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: Example Folder'\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 4                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ 📌\\ 📂\\ Example\\ Folder ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*4.*].*\\ Title\\ Three            ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two              ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*1.*].*\\ Title\\ One              ]]\n}\n\n@test \"'pin <folder-id>' adds a folder to the parent folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder\"  --type \"folder\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n  }\n\n  run \"${_NB}\" pin 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                                  \\\n    <(printf \"%s\\\\n\" \"Example Folder\")  \\\n    <(cat \"${NB_DIR}/home/.pindex\")\n\n  [[ \"$(wc -l < \"${NB_DIR}/home/.pindex\")\"  -eq 1                   ]]\n  [[ \"$(cat \"${NB_DIR}/home/.pindex\")\"      =~  ^Example\\ Folder$   ]]\n\n  # prints output\n\n  [[ \"${output}\" =~ Pinned:\\ .*[.*3.*].*\\ 📌\\ .*Example\\ Folder     ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: Example Folder'\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 4                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ 📌\\ 📂\\ Example\\ Folder ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*4.*].*\\ Title\\ Three            ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two              ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*1.*].*\\ Title\\ One              ]]\n}\n\n@test \"'pin <dolder>/<id>' adds an item to the folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n  }\n\n  run \"${_NB}\" pin Example\\ Folder/File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n\n  [[ \"$(wc -l < \"${NB_DIR}/home/Example Folder/.pindex\")\"  -eq 1              ]]\n  [[ \"$(cat \"${NB_DIR}/home/Example Folder/.pindex\")\"      =~  ^File\\ One.md$ ]]\n\n  # prints output\n\n  [[ \"${output}\" =~ Pinned:\\ .*[.*Example\\ Folder/1.*].*\\ 📌\\ .*File\\ One.md  ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: Example Folder/File One.md'\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n}\n\n@test \"'pin <notebook>:<dolder>/<id>' adds an item to the folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Notebook:Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Notebook:Example Folder/File Three.md\"  --title \"Title Three\"\n\n    [[ ! -e \"${NB_DIR}/Example Notebook/.pindex\" ]]\n  }\n\n  # `pin` an item\n\n  run \"${_NB}\" pin Example\\ Notebook:Example\\ Folder/File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.pindex\")\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # updates pindex\n\n  diff                              \\\n    <(printf \"%s\\\\n\" \"File One.md\") \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/.pindex\")\n\n  [[ \"$(wc -l < \"${NB_DIR}/Example Notebook/Example Folder/.pindex\")\"  -eq 1                    ]]\n  [[ \"$(cat \"${NB_DIR}/Example Notebook/Example Folder/.pindex\")\"      =~  ^File\\ One.md$       ]]\n\n  # prints output\n\n  [[ \"${output}\" =~ Pinned:\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ 📌\\ .*File\\ One.md  ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/Example Notebook\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Pinned: Example Folder/File One.md'\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list Example\\ Notebook:Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Notebook:Example\\ Folder/3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Notebook:Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n}\n\n# unpin #######################################################################\n\n@test \"'unpin <filename>' removes an item from the folder's .pindex without unpinning other pinned items.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n    \"${_NB}\" add \"File Four.md\"   --title \"Title Four\"\n\n    \"${_NB}\" pin \"File One.md\"\n    \"${_NB}\" pin \"File Three.md\"\n\n    diff                                          \\\n      <(printf \"File One.md\\\\nFile Three.md\\\\n\")  \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                               ]]\n  [[ \"${#lines[@]}\" -eq 4                               ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One    ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ 📌\\ Title\\ Three  ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*4.*].*\\ Title\\ Four       ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two        ]]\n\n  # `unpin` an item\n\n  run \"${_NB}\" unpin File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # removes item from the .pindex file\n\n    diff                            \\\n      <(printf \"File Three.md\\\\n\")  \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n\n  # prints output\n\n  [[    \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ .*File\\ One.md     ]]\n  [[ !  \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ 📌\\ .*File\\ One.md ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: File One.md'\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                               ]]\n  [[ \"${#lines[@]}\" -eq 4                               ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ 📌\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*4.*].*\\ Title\\ Four       ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two        ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*1.*].*\\ Title\\ One        ]]\n}\n\n@test \"'unpin <filename>' removes an item from the folder's .pindex when it's the last pinned item.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" pin \"File One.md\"\n\n    diff                              \\\n      <(printf \"%s\\\\n\" \"File One.md\") \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n\n  # `unpin` an item\n\n  run \"${_NB}\" unpin File\\ One.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # removes the pindex when it's last\n\n  [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n\n  # prints output\n\n  [[    \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ .*File\\ One.md     ]]\n  [[ !  \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ 📌\\ .*File\\ One.md ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: File One.md'\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 3                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n}\n\n@test \"'unpin <id>' removes an item from the folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" pin \"File One.md\"\n\n    diff                              \\\n      <(printf \"%s\\\\n\" \"File One.md\") \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n\n  # `unpin` an item\n\n  run \"${_NB}\" unpin 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # removes the pindex when it's last\n\n  [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n\n  # prints output\n\n  [[    \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ .*File\\ One.md     ]]\n  [[ !  \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ 📌\\ .*File\\ One.md ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: File One.md'\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 3                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n}\n\n@test \"'unpin <title>' removes an item from the folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" pin \"File One.md\"\n\n    diff                              \\\n      <(printf \"%s\\\\n\" \"File One.md\") \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two      ]]\n\n  # `unpin` an item\n\n  run \"${_NB}\" unpin Title\\ One\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # removes the pindex when it's last\n\n  [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n\n  # prints output\n\n  [[    \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ .*File\\ One.md     ]]\n  [[ !  \"${output}\" =~ Unpinned:\\ .*[.*1.*].*\\ 📌\\ .*File\\ One.md ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: File One.md'\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 3                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*1.*].*\\ Title\\ One    ]]\n}\n\n@test \"'unpin <folder-name>' removes a folder from the parent folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder\"  --type \"folder\"\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" pin \"Example Folder\"\n\n    diff                                  \\\n      <(printf \"%s\\\\n\" \"Example Folder\")  \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 4                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ 📌\\ 📂\\ Example\\ Folder ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*4.*].*\\ Title\\ Three            ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two              ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*1.*].*\\ Title\\ One              ]]\n\n  # `unpin` an item\n\n  run \"${_NB}\" unpin Example\\ Folder\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # removes the pindex when it's last\n\n  [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n\n  # prints output\n\n  [[    \"${output}\" =~ Unpinned:\\ .*[.*3.*].*\\ .*Example\\ Folder      ]]\n  [[ !  \"${output}\" =~ Unpinned:\\ .*[.*3.*].*\\ 📌\\ .*Example\\ Folder  ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: Example Folder'\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n  [[ \"${#lines[@]}\" -eq 4                                 ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*4.*].*\\ Title\\ Three        ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ 📂\\ Example\\ Folder ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two          ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*1.*].*\\ Title\\ One          ]]\n}\n\n@test \"'unpin <folder-id>' removes a folder from the parent folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder\"  --type folder\n    \"${_NB}\" add \"File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" pin \"Example Folder\"\n\n    diff                                  \\\n      <(printf \"%s\\\\n\" \"Example Folder\")  \\\n      <(cat \"${NB_DIR}/home/.pindex\")\n  }\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 4                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*3.*].*\\ 📌\\ 📂\\ Example\\ Folder ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*4.*].*\\ Title\\ Three            ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two              ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*1.*].*\\ Title\\ One              ]]\n\n  # `unpin` an item\n\n  run \"${_NB}\" unpin 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # removes the pindex when it's last\n\n  [[ ! -e \"${NB_DIR}/home/.pindex\" ]]\n\n  # prints output\n\n  [[    \"${output}\" =~ Unpinned:\\ .*[.*3.*].*\\ .*Example\\ Folder      ]]\n  [[ !  \"${output}\" =~ Unpinned:\\ .*[.*3.*].*\\ 📌\\ .*Example\\ Folder  ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: Example Folder'\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                 ]]\n  [[ \"${#lines[@]}\" -eq 4                                 ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*4.*].*\\ Title\\ Three        ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*3.*].*\\ 📂\\ Example\\ Folder ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*2.*].*\\ Title\\ Two          ]]\n  [[ \"${lines[3]}\"  =~  \\.*[.*1.*].*\\ Title\\ One          ]]\n}\n\n@test \"'unpin <folder>/<id>' removes an item from the folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Folder/File Three.md\"  --title \"Title Three\"\n\n    \"${_NB}\" pin \"Example Folder/File One.md\"\n\n    diff                              \\\n      <(printf \"%s\\\\n\" \"File One.md\") \\\n      <(cat \"${NB_DIR}/home/Example Folder/.pindex\")\n  }\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 3 ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Folder/3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n\n  # `unpin` an item\n\n  run \"${_NB}\" unpin Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # removes the pindex when it's last\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/.pindex\" ]]\n\n  # prints output\n\n  [[    \"${output}\" =~ Unpinned:\\ .*[.*Example\\ Folder/1.*].*\\ .*Example\\ Folder/File\\ One.md     ]]\n  [[ !  \"${output}\" =~ Unpinned:\\ .*[.*Example\\ Folder/1.*].*\\ 📌\\ .*Example\\ Folder/File\\ One.md ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/home\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: Example Folder/File One.md'\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n  [[ \"${#lines[@]}\" -eq 3                                           ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Folder/3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Folder/2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Folder/1.*].*\\ Title\\ One    ]]\n}\n\n@test \"'unpin <notebook>:<folder>/<id>' removes an item from the folder's .pindex.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example Folder/File One.md\"    --title \"Title One\"\n    \"${_NB}\" add \"Example Notebook:Example Folder/File Two.md\"    --title \"Title Two\"\n    \"${_NB}\" add \"Example Notebook:Example Folder/File Three.md\"  --title \"Title Three\"\n\n    [[ -f \"${NB_DIR}/Example Notebook/Example Folder/File One.md\" ]]\n\n    \"${_NB}\" pin \"Example Notebook:Example Folder/File One.md\"\n\n    diff                              \\\n      <(printf \"%s\\\\n\" \"File One.md\") \\\n      <(cat \"${NB_DIR}/Example Notebook/Example Folder/.pindex\")\n  }\n\n  # `list` with one pinned item\n\n  run \"${_NB}\" list Example\\ Notebook:Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n  [[ \"${#lines[@]}\" -eq 3 ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ 📌\\ Title\\ One  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Notebook:Example\\ Folder/3.*].*\\ Title\\ Three    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Notebook:Example\\ Folder/2.*].*\\ Title\\ Two      ]]\n\n  # `unpin` an item\n\n  run \"${_NB}\" unpin Example\\ Notebook:Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # returns status 0\n\n  [[ \"${status}\" -eq 0 ]]\n\n  # removes the pindex when it's last\n\n  [[ ! -e \"${NB_DIR}/Example Notebook/Example Folder/.pindex\" ]]\n\n  # prints output\n\n  [[    \"${lines[0]}\" =~ Unpinned:\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ .*Example      ]]\n  [[    \"${lines[0]}\" =~ Example\\ Notebook:Example\\ Folder/File\\ One.md                           ]]\n  [[ !  \"${lines[0]}\" =~ Unpinned:\\ .*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ 📌\\ .*Example  ]]\n\n  # creates git commit\n\n  cd \"${NB_DIR}/Example Notebook\"\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Unpinned: Example Folder/File One.md'\n\n  # `list` with no pinned items\n\n  run \"${_NB}\" list Example\\ Notebook:Example\\ Folder/ --with-pinned\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                             ]]\n  [[ \"${#lines[@]}\" -eq 3                                                             ]]\n\n  [[ \"${lines[0]}\"  =~  \\.*[.*Example\\ Notebook:Example\\ Folder/3.*].*\\ Title\\ Three  ]]\n  [[ \"${lines[1]}\"  =~  \\.*[.*Example\\ Notebook:Example\\ Folder/2.*].*\\ Title\\ Two    ]]\n  [[ \"${lines[2]}\"  =~  \\.*[.*Example\\ Notebook:Example\\ Folder/1.*].*\\ Title\\ One    ]]\n}\n"
  },
  {
    "path": "test/plugin-backlink.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `backlink` ##################################################################\n\n@test \"'nb backlink' with links adds backlinks.\" {\n  if ! hash \"note-link-janitor\" 2>/dev/null\n  then\n    skip \"note-link-janitor not installed.\"\n  fi\n\n  {\n    \"${_NB}\" init\n    run \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/backlink.nb-plugin\"\n\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# one\n\nExample content [[three]] apple pear.\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# two\n\nSample content [[three]] orange.\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# three\n\nDemo content [[one]] apricot plum.\nHEREDOC\n\n    [[ \"${status}\" == 0 ]]\n  }\n\n  run \"${_NB}\" backlink --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  cat \"${NB_DIR}/home/first.md\"\n  cat \"${NB_DIR}/home/second.md\"\n  cat \"${NB_DIR}/home/third.md\"\n\n  _first_content=\"# one\n\nExample content [[three]] apple pear.\n## Backlinks\n* [[three]]\n\t* Demo content [[one]] apricot plum.\n\"\n\n  _second_content=\"# two\n\nSample content [[three]] orange.\"\n\n  _third_content=\"# three\n\nDemo content [[one]] apricot plum.\n## Backlinks\n* [[one]]\n\t* Example content [[three]] apple pear.\n* [[two]]\n\t* Sample content [[three]] orange.\n\"\n\n  [[ \"${status}\" == 0               ]]\n  [[ \"${output:-}\" == \"Backlinked!\" ]]\n\n  diff <(cat \"${NB_DIR}/home/first.md\")  <(echo \"${_first_content}\")\n  diff <(cat \"${NB_DIR}/home/second.md\") <(echo \"${_second_content}\")\n  diff <(cat \"${NB_DIR}/home/third.md\")  <(echo \"${_third_content}\")\n\n  # Creates git commit\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Backlinked'\n}\n\n@test \"'nb backlink' with no links does not add backlinks.\" {\n  if ! hash \"note-link-janitor\" 2>/dev/null\n  then\n    skip \"note-link-janitor not installed.\"\n  fi\n\n  {\n    \"${_NB}\" init\n    run \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/backlink.nb-plugin\"\n\n    cat <<HEREDOC | \"${_NB}\" add 'first.md'\n# one\n\nExample content three apple pear.\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'second.md'\n# two\n\nSample content three orange.\nHEREDOC\n    cat <<HEREDOC | \"${_NB}\" add 'third.md'\n# three\n\nDemo content one apricot plum.\nHEREDOC\n\n    [[ \"${status}\" == 0 ]]\n  }\n\n  run \"${_NB}\" backlink --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  cat \"${NB_DIR}/home/first.md\"\n  cat \"${NB_DIR}/home/second.md\"\n  cat \"${NB_DIR}/home/third.md\"\n\n  _first_content=\"# one\n\nExample content three apple pear.\"\n\n  _second_content=\"# two\n\nSample content three orange.\"\n\n  _third_content=\"# three\n\nDemo content one apricot plum.\"\n\n  [[ \"${status}\" == 0                       ]]\n  [[ \"${output:-}\" == \"No new links found.\" ]]\n\n  diff <(cat \"${NB_DIR}/home/first.md\")  <(echo \"${_first_content}\")\n  diff <(cat \"${NB_DIR}/home/second.md\") <(echo \"${_second_content}\")\n  diff <(cat \"${NB_DIR}/home/third.md\")  <(echo \"${_third_content}\")\n\n  # Does not create git commit\n  cd \"${NB_DIR}/home\" || return 1\n  if [[ -n \"$(git status --porcelain)\" ]]\n  then\n    sleep 1\n  fi\n  git log | grep -q -v '\\[nb\\] Backlinked'\n}\n\n# help ########################################################################\n\n@test \"'help backlink' exits with status 0 and prints usage.\" {\n  if ! hash \"note-link-janitor\" 2>/dev//null\n  then\n    skip \"note-link-janitor not installed.\"\n  fi\n\n  {\n    \"${_NB}\" init\n    run \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/backlink.nb-plugin\"\n\n    [[ \"${status}\" == 0 ]]\n  }\n\n  run \"${_NB}\" help backlink\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\:     ]]\n  [[ \"${lines[1]}\" =~ nb\\ backlink  ]]\n}\n"
  },
  {
    "path": "test/plugin-bump.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `bump` ###################################################################\n\n@test \"'nb bump' updates order of items in 'ls'.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set footer 0\n\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/bump.nb-plugin\"\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Example content four.\"\n  }\n\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${lines[0]}\"  =~  home                                      ]]\n  [[ \"${lines[1]}\"  =~  ----                                      ]]\n  [[ \"${lines[2]}\"  =~  \\\n\\[.*4.*\\].*\\ File\\ Four\\.md\\ ·\\ \\\"Example\\ content\\ four\\.\\\"      ]]\n  [[ \"${lines[3]}\"  =~  \\\n\\[.*3.*\\].*\\ File\\ Three\\.md\\ ·\\ \\\"Example\\ content\\ three\\.\\\"    ]]\n  [[ \"${lines[4]}\"  =~  \\\n\\[.*2.*\\].*\\ File\\ Two\\.md\\ ·\\ \\\"Example\\ content\\ two\\.\\\"        ]]\n  [[ \"${lines[5]}\"  =~  \\\n\\[.*1.*\\].*\\ File\\ One\\.md\\ ·\\ \\\"Example\\ content\\ one\\.\\\"        ]]\n\n\n  run \"${_NB}\" bump 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${#lines[@]}\" -eq 1                                         ]]\n  [[ \"${lines[0]}\"  =~  \\\nBumped.*to\\ top.*:.*\\ .*\\[.*2.*\\].*\\ .*File\\ Two\\.md              ]]\n\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${lines[0]}\"  =~  home                                      ]]\n  [[ \"${lines[1]}\"  =~  ----                                      ]]\n  [[ \"${lines[2]}\"  =~  \\\n\\[.*2.*\\].*\\ File\\ Two\\.md\\ ·\\ \\\"Example\\ content\\ two\\.\\\"        ]]\n  [[ \"${lines[3]}\"  =~  \\\n\\[.*4.*\\].*\\ File\\ Four\\.md\\ ·\\ \\\"Example\\ content\\ four\\.\\\"      ]]\n  [[ \"${lines[4]}\"  =~  \\\n\\[.*3.*\\].*\\ File\\ Three\\.md\\ ·\\ \\\"Example\\ content\\ three\\.\\\"    ]]\n  [[ \"${lines[5]}\"  =~  \\\n\\[.*1.*\\].*\\ File\\ One\\.md\\ ·\\ \\\"Example\\ content\\ one\\.\\\"        ]]\n\n  run \"${_NB}\" bump 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${#lines[@]}\" -eq 1                                         ]]\n  [[ \"${lines[0]}\"  =~  \\\nBumped.*to\\ top.*:.*\\ .*\\[.*1.*\\].*\\ .*File\\ One\\.md              ]]\n\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${lines[0]}\"  =~  home                                      ]]\n  [[ \"${lines[1]}\"  =~  ----                                      ]]\n  [[ \"${lines[2]}\"  =~  \\\n\\[.*1.*\\].*\\ File\\ One\\.md\\ ·\\ \\\"Example\\ content\\ one\\.\\\"        ]]\n  [[ \"${lines[3]}\"  =~  \\\n\\[.*2.*\\].*\\ File\\ Two\\.md\\ ·\\ \\\"Example\\ content\\ two\\.\\\"        ]]\n  [[ \"${lines[4]}\"  =~  \\\n\\[.*4.*\\].*\\ File\\ Four\\.md\\ ·\\ \\\"Example\\ content\\ four\\.\\\"      ]]\n  [[ \"${lines[5]}\"  =~  \\\n\\[.*3.*\\].*\\ File\\ Three\\.md\\ ·\\ \\\"Example\\ content\\ three\\.\\\"    ]]\n}\n\n# `touch` alias ###############################################################\n\n@test \"'nb touch' updates order of items in 'ls'.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" set footer 0\n\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/bump.nb-plugin\"\n\n    \"${_NB}\" add \"File One.md\"    --content \"Example content one.\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Example content two.\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Example content three.\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Example content four.\"\n  }\n\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${lines[0]}\"  =~  home                                      ]]\n  [[ \"${lines[1]}\"  =~  ----                                      ]]\n  [[ \"${lines[2]}\"  =~  \\\n\\[.*4.*\\].*\\ File\\ Four\\.md\\ ·\\ \\\"Example\\ content\\ four\\.\\\"      ]]\n  [[ \"${lines[3]}\"  =~  \\\n\\[.*3.*\\].*\\ File\\ Three\\.md\\ ·\\ \\\"Example\\ content\\ three\\.\\\"    ]]\n  [[ \"${lines[4]}\"  =~  \\\n\\[.*2.*\\].*\\ File\\ Two\\.md\\ ·\\ \\\"Example\\ content\\ two\\.\\\"        ]]\n  [[ \"${lines[5]}\"  =~  \\\n\\[.*1.*\\].*\\ File\\ One\\.md\\ ·\\ \\\"Example\\ content\\ one\\.\\\"        ]]\n\n\n  run \"${_NB}\" touch 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${#lines[@]}\" -eq 1                                         ]]\n  [[ \"${lines[0]}\"  =~  \\\nBumped.*\\ to\\ top.*:.*\\ .*\\[.*2.*\\].*\\ .*File\\ Two\\.md            ]]\n\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${lines[0]}\"  =~  home                                      ]]\n  [[ \"${lines[1]}\"  =~  ----                                      ]]\n  [[ \"${lines[2]}\"  =~  \\\n\\[.*2.*\\].*\\ File\\ Two\\.md\\ ·\\ \\\"Example\\ content\\ two\\.\\\"        ]]\n  [[ \"${lines[3]}\"  =~  \\\n\\[.*4.*\\].*\\ File\\ Four\\.md\\ ·\\ \\\"Example\\ content\\ four\\.\\\"      ]]\n  [[ \"${lines[4]}\"  =~  \\\n\\[.*3.*\\].*\\ File\\ Three\\.md\\ ·\\ \\\"Example\\ content\\ three\\.\\\"    ]]\n  [[ \"${lines[5]}\"  =~  \\\n\\[.*1.*\\].*\\ File\\ One\\.md\\ ·\\ \\\"Example\\ content\\ one\\.\\\"        ]]\n\n  run \"${_NB}\" touch 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${#lines[@]}\" -eq 1                                         ]]\n  [[ \"${lines[0]}\"  =~  \\\nBumped.*to\\ top.*:.*\\ .*\\[.*1.*\\].*\\ .*File\\ One\\.md              ]]\n\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                                         ]]\n  [[ \"${lines[0]}\"  =~  home                                      ]]\n  [[ \"${lines[1]}\"  =~  ----                                      ]]\n  [[ \"${lines[2]}\"  =~  \\\n\\[.*1.*\\].*\\ File\\ One\\.md\\ ·\\ \\\"Example\\ content\\ one\\.\\\"        ]]\n  [[ \"${lines[3]}\"  =~  \\\n\\[.*2.*\\].*\\ File\\ Two\\.md\\ ·\\ \\\"Example\\ content\\ two\\.\\\"        ]]\n  [[ \"${lines[4]}\"  =~  \\\n\\[.*4.*\\].*\\ File\\ Four\\.md\\ ·\\ \\\"Example\\ content\\ four\\.\\\"      ]]\n  [[ \"${lines[5]}\"  =~  \\\n\\[.*3.*\\].*\\ File\\ Three\\.md\\ ·\\ \\\"Example\\ content\\ three\\.\\\"    ]]\n}\n\n# help ########################################################################\n\n@test \"'help bump' exits with status 0 and prints usage.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/bump.nb-plugin\"\n  }\n\n  run \"${_NB}\" help bump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\:       ]]\n  [[ \"${lines[1]}\"  =~  nb\\ bump        ]]\n}\n"
  },
  {
    "path": "test/plugin-daily.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `daily --prev` ##############################################################\n\n@test \"'nb daily --prev' with no content and no existing note prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n  }\n\n  run \"${_NB}\" daily --prev\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${output}\"    ==  \"Add the first daily note: nb daily <content>\" ]]\n}\n\n@test \"'nb daily --prev' with existing notes lists notes.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n\n    \"${_NB}\" add                    \\\n      --filename  \"43210101.md\"     \\\n      --content   \"$(cat <<HEREDOC\n# Daily 4321-01-01\n\n## 01:01:01\n\nExample content one.\nHEREDOC\n      )\"\n\n    \"${_NB}\" add                    \\\n      --filename  \"43210202.md\"     \\\n      --content   \"$(cat <<HEREDOC\n# Daily 4321-02-02\n\n## 02:02:02\n\nExample content two.\nHEREDOC\n      )\"\n\n\n    \"${_NB}\" add                    \\\n      --filename  \"43210303.md\"     \\\n      --content   \"$(cat <<HEREDOC\n# Daily 4321-03-03\n\n## 03:03:03\n\nExample content three.\nHEREDOC\n      )\"\n    }\n\n  run \"${_NB}\" daily --prev\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*0.*].*\\ \\[3\\]\\ Daily\\ 4321-03-03 ]]\n  [[ \"${lines[1]}\"  =~  .*[.*1.*].*\\ \\[2\\]\\ Daily\\ 4321-02-02 ]]\n  [[ \"${lines[2]}\"  =~  .*[.*2.*].*\\ \\[1\\]\\ Daily\\ 4321-01-01 ]]\n}\n\n@test \"'nb daily --prev <number>' shows notes.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n\n    \"${_NB}\" add                    \\\n      --filename  \"43210101.md\"     \\\n      --content   \"$(cat <<HEREDOC\n# Daily 4321-01-01\n\n## 01:01:01\n\nExample content one.\nHEREDOC\n      )\"\n\n    \"${_NB}\" add                    \\\n      --filename  \"43210202.md\"     \\\n      --content   \"$(cat <<HEREDOC\n# Daily 4321-02-02\n\n## 02:02:02\n\nExample content two.\nHEREDOC\n      )\"\n\n\n    \"${_NB}\" add                    \\\n      --filename  \"43210303.md\"     \\\n      --content   \"$(cat <<HEREDOC\n# Daily 4321-03-03\n\n## 03:03:03\n\nExample content three.\nHEREDOC\n      )\"\n  }\n\n  run \"${_NB}\" daily --prev 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*\\[.*2.*\\].*43210202\\.md.*:  ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*\\#.*Daily\\ 4321-02-02       ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*\\#\\#.*02:02:02              ]]\n  [[ \"${lines[3]}\"  =~  \\\nExample\\ content\\ two\\.       ]]\n\n  run \"${_NB}\" daily --prev 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0     ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*\\[.*3.*\\].*43210303\\.md.*:  ]]\n  [[ \"${lines[1]}\"  =~  \\\n.*\\#.*Daily\\ 4321-03-03       ]]\n  [[ \"${lines[2]}\"  =~  \\\n.*\\#\\#.*03:03:03              ]]\n  [[ \"${lines[3]}\"  =~  \\\nExample\\ content\\ three\\.     ]]\n\n  run \"${_NB}\" daily --prev 42\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1     ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*!.*\\ Not\\ found\\.           ]]\n}\n\n# `daily` #####################################################################\n\n@test \"'nb daily' with no content and no existing note prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n  }\n\n  run \"${_NB}\" daily\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${output}\"    ==  \"Add the first note of the day: nb daily <content>\" ]]\n}\n\n@test \"'nb daily' with no content and existing note prints note contents.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n\n    \"${_NB}\" daily \"Example content one.\"\n    \"${_NB}\" daily \"Example content two.\"\n  }\n\n  run \"${_NB}\" daily\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n.*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\\.md.*:     ]]\n  [[ \"${lines[1]}\"  =~  \\\n\\#.*Daily.*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ]]\n  [[ \"${lines[2]}\"  =~  \\\n\\#\\#.*[0-9][0-9]:[0-9][0-9]:[0-9][0-9]                ]]\n  [[ \"${lines[3]}\"  =~  \\\nExample\\ content\\ one\\.                               ]]\n  [[ \"${lines[4]}\"  =~  \\\n\\#\\#.*[0-9][0-9]:[0-9][0-9]:[0-9][0-9]                ]]\n  [[ \"${lines[5]}\"  =~  \\\nExample\\ content\\ two\\.                               ]]\n}\n\n@test \"'nb daily \\\"<content>\\\"' (with quotes) without existing note adds new note with content.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n\n    declare _target_filename=\n    _target_filename=\"$(date \"+%Y%m%d\").md\"\n  }\n\n  run \"${_NB}\" daily \"Example content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0 ]]\n\n  \"${_NB}\" show 1 --print\n\n  [[ \"${output}\"    =~  Added:\\ .*[.*1.*].*\\ .*${_target_filename}  ]]\n  [[ \"$(\"${_NB}\" show 1 --print | wc -l | awk '$1=$1')\" == 5        ]]\n  [[ \"$(\"${_NB}\" show 1 --print)\" =~ \\\n\\#\\#.*[0-9][0-9]:[0-9][0-9]:[0-9][0-9]                              ]]\n  [[ \"$(\"${_NB}\" show 1 --print)\" =~ Example\\ content\\.             ]]\n}\n\n@test \"'nb daily <content>' (without quotes) without existing note adds new note with content.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n\n    declare _target_filename=\n    _target_filename=\"$(date \"+%Y%m%d\").md\"\n  }\n\n  run \"${_NB}\" daily Example note content.\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0 ]]\n\n  \"${_NB}\" show 1 --print\n\n  [[ \"${output}\"    =~  Added:\\ .*[.*1.*].*\\ .*${_target_filename}  ]]\n  [[ \"$(\"${_NB}\" show 1 --print | wc -l | awk '$1=$1')\" == 5        ]]\n  [[ \"$(\"${_NB}\" show 1 --print)\" =~ \\\n\\#\\#.*[0-9][0-9]:[0-9][0-9]:[0-9][0-9]                              ]]\n  [[ \"$(\"${_NB}\" show 1 --print)\" =~ Example\\ note\\ content\\.       ]]\n}\n\n@test \"'nb daily \\\"<content>\\\"' (with quotes) with existing note adds content to existing note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n\n    declare _target_filename=\n    _target_filename=\"$(date \"+%Y%m%d\").md\"\n\n    \"${_NB}\" daily \"Example initial content.\"\n  }\n\n  run \"${_NB}\" daily \"Example new content.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0 ]]\n\n  \"${_NB}\" show 1 --print\n\n  [[ \"${output}\"    =~  Updated:\\ .*[.*1.*].*\\ .*${_target_filename}  ]]\n\n  \"${_NB}\" show 1 --print --no-color | grep -q \\\n\"# Daily \\d\\d\\d\\d-\\d\\d-\\d\\d\n\n## \\d\\d:\\d\\d:\\d\\d\n\nExample initial content.\n\n## \\d\\d:\\d\\d:\\d\\d\n\nExample new content.\"\n}\n\n@test \"'nb daily <content>' (without quotes) with existing note adds content to existing note.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n\n    declare _target_filename=\n    _target_filename=\"$(date \"+%Y%m%d\").md\"\n\n    \"${_NB}\" daily \"Example initial content.\"\n  }\n\n  run \"${_NB}\" daily Example new content.\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0 ]]\n\n  \"${_NB}\" show 1 --print\n\n  [[ \"${output}\"    =~  Updated:\\ .*[.*1.*].*\\ .*${_target_filename}  ]]\n\n  \"${_NB}\" show 1 --print --no-color | grep -q \\\n\"# Daily \\d\\d\\d\\d-\\d\\d-\\d\\d\n\n## \\d\\d:\\d\\d:\\d\\d\n\nExample initial content.\n\n## \\d\\d:\\d\\d:\\d\\d\n\nExample new content.\"\n}\n\n# help ########################################################################\n\n@test \"'help example' exits with status 0 and prints usage.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/daily.nb-plugin\"\n  }\n\n  run \"${_NB}\" help daily\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\:       ]]\n  [[ \"${lines[1]}\"  =~  nb\\ daily       ]]\n}\n"
  },
  {
    "path": "test/plugin-ebook.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `ebook init <name>` #########################################################\n\n@test \"'ebook init <name>' creates new ebook notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/ebook.nb-plugin\"\n  }\n\n  run \"${_NB}\" ebook init \"example-ebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" == 0                               ]]\n  [[ \"${lines[0]}\" =~ Added\\ notebook               ]]\n  [[ \"${lines[0]}\" =~ example-ebook                 ]]\n  [[ -d \"${NB_DIR}/example-ebook\"                   ]]\n\n  [[ \"${lines[1]}\" =~ Added:                        ]]\n  [[ \"${lines[1]}\" =~ example-ebook:1               ]]\n  [[ \"${lines[1]}\" =~ example-ebook:title.txt       ]]\n  [[ -f \"${NB_DIR}/example-ebook/title.txt\"         ]]\n\n  [[ \"${lines[2]}\" =~ Added:                        ]]\n  [[ \"${lines[2]}\" =~ example-ebook:2               ]]\n  [[ \"${lines[2]}\" =~ example-ebook:stylesheet.css  ]]\n  [[ -f \"${NB_DIR}/example-ebook/stylesheet.css\"    ]]\n\n  [[ \"${lines[3]}\" =~ Added:                        ]]\n  [[ \"${lines[3]}\" =~ example-ebook:3               ]]\n  [[ \"${lines[3]}\" =~ example-ebook:01-chapter1.md  ]]\n  [[ -f \"${NB_DIR}/example-ebook/01-chapter1.md\"    ]]\n\n  [[ \"${lines[4]}\" =~ Ebook\\ initialized:           ]]\n  [[ \"${lines[4]}\" =~ example-ebook                 ]]\n}\n\n@test \"'ebook init' sets up current notebook as ebook.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n    \"${_NB}\" use example\n\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/ebook.nb-plugin\"\n  }\n\n  run \"${_NB}\" ebook init --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  echo \"ls example:\"\n  ls \"${NB_DIR}/example\"\n  echo \"ls home:\"\n  ls \"${NB_DIR}/home\"\n\n  [[ \"${status}\" == 0                         ]]\n\n  [[ \"${lines[0]}\" =~ Adding\\ the\\ following  ]]\n  [[ \"${lines[0]}\" =~ current\\ notebook       ]]\n  [[ \"${lines[1]}\" =~ title.txt               ]]\n  [[ \"${lines[2]}\" =~ stylesheet.css          ]]\n  [[ \"${lines[3]}\" =~ 01-chapter1.md          ]]\n\n  [[ \"${lines[4]}\" =~ Added:                  ]]\n  [[ \"${lines[4]}\" =~ 1                       ]]\n  [[ \"${lines[4]}\" =~ title.txt               ]]\n  [[ -f \"${NB_DIR}/example/title.txt\"         ]]\n\n  [[ \"${lines[5]}\" =~ Added:                  ]]\n  [[ \"${lines[5]}\" =~ 2                       ]]\n  [[ \"${lines[5]}\" =~ stylesheet.css          ]]\n  [[ -f \"${NB_DIR}/example/stylesheet.css\"    ]]\n\n  [[ \"${lines[6]}\" =~ Added:                  ]]\n  [[ \"${lines[6]}\" =~ 3                       ]]\n  [[ \"${lines[6]}\" =~ 01-chapter1.md          ]]\n  [[ -f \"${NB_DIR}/example/01-chapter1.md\"    ]]\n\n  [[ \"${lines[7]}\" =~ Ebook\\ initialized:     ]]\n  [[ \"${lines[7]}\" =~ example                 ]]\n}\n\n@test \"'ebook init <existing>' sets up <existing> notebook as ebook.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/ebook.nb-plugin\"\n  }\n\n  run \"${_NB}\" ebook init example --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Adding\\ the\\ following  ]]\n  [[ \"${lines[0]}\" =~ example                 ]]\n  [[ \"${lines[1]}\" =~ title.txt               ]]\n  [[ \"${lines[2]}\" =~ stylesheet.css          ]]\n  [[ \"${lines[3]}\" =~ 01-chapter1.md          ]]\n\n  [[ \"${status}\" == 0                         ]]\n  [[ \"${lines[4]}\" =~ Added:                  ]]\n  [[ \"${lines[4]}\" =~ example:1               ]]\n  [[ \"${lines[4]}\" =~ example:title.txt       ]]\n  [[ -f \"${NB_DIR}/example/title.txt\"         ]]\n\n  [[ \"${lines[5]}\" =~ Added:                  ]]\n  [[ \"${lines[5]}\" =~ example:2               ]]\n  [[ \"${lines[5]}\" =~ example:stylesheet.css  ]]\n  [[ -f \"${NB_DIR}/example/stylesheet.css\"    ]]\n\n  [[ \"${lines[6]}\" =~ Added:                  ]]\n  [[ \"${lines[6]}\" =~ example:3               ]]\n  [[ \"${lines[6]}\" =~ example:01-chapter1.md  ]]\n  [[ -f \"${NB_DIR}/example/01-chapter1.md\"    ]]\n\n  [[ \"${lines[7]}\" =~ Ebook\\ initialized:     ]]\n  [[ \"${lines[7]}\" =~ example                 ]]\n}\n\n# `ebook publish` #############################################################\n\n@test \"'ebook publish' generates epub file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/ebook.nb-plugin\"\n    \"${_NB}\" ebook new \"example-ebook\"\n    \"${_NB}\" use \"example-ebook\"\n\n    # Add chapters out of order to validate final ordering.\n    \"${_NB}\" add                  \\\n      --filename \"03-chapter3.md\" \\\n      --title \"Chapter Three\"     \\\n      --content \"Content three.\"\n\n     \"${_NB}\" add                 \\\n      --filename \"02-chapter2.md\" \\\n      --title \"Chapter Two\"       \\\n      --content \"Content two.\"\n  }\n\n  run \"${_NB}\" ebook publish\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                  ]]\n  [[ \"${lines[0]}\" =~ Added\\:                         ]]\n  [[ \"${lines[0]}\" =~ example-ebook.epub              ]]\n  [[ -f \"${NB_DIR}/example-ebook/example-ebook.epub\"  ]]\n\n  _markdown=\"$(\n    pandoc -f epub -t html \"${NB_DIR}/example-ebook/example-ebook.epub\" \\\n      | pandoc -f html-native_divs-native_spans -t markdown_strict\n  )\"\n\n  printf \"\\${_markdown}: '%s'\\\\n\" \"${_markdown}\"\n  _expected=\"# Chapter One\n\n# Chapter Two\n\nContent two.\n\n# Chapter Three\n\nContent three.\"\n\n  [[ \"${_markdown}\" == \"${_expected}\" ]]\n}\n\n# help ########################################################################\n\n@test \"'ebook' with no argument exits with status 1 and prints usage.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/ebook.nb-plugin\"\n  }\n\n  run \"${_NB}\" ebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1              ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\:   ]]\n  [[ \"${lines[1]}\" =~ nb\\ ebook   ]]\n}\n\n@test \"'help ebook' exits with status 0 and prints usage.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/ebook.nb-plugin\"\n  }\n\n  run \"${_NB}\" help ebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${lines[0]}\" =~ Usage.*\\:   ]]\n  [[ \"${lines[1]}\" =~ nb\\ ebook   ]]\n}\n\n"
  },
  {
    "path": "test/plugin-example.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `example` ###################################################################\n\n@test \"'nb example' prints output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"\n  }\n\n  run \"${_NB}\" example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0               ]]\n  [[ \"${output}\"    ==  \"Hello, World!\" ]]\n}\n\n# help ########################################################################\n\n@test \"'help example' exits with status 0 and prints usage.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"\n  }\n\n  run \"${_NB}\" help example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\:       ]]\n  [[ \"${lines[1]}\"  =~  nb\\ example     ]]\n}\n"
  },
  {
    "path": "test/plugin-weather.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# help ########################################################################\n\n@test \"'help w' exits with status 0 and prints usage.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/weather.nb-plugin\"\n  }\n\n  run \"${_NB}\" help w\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\:       ]]\n  [[ \"${lines[1]}\"  =~  nb\\ weather     ]]\n}\n\n@test \"'help weather' exits with status 0 and prints usage.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/weather.nb-plugin\"\n  }\n\n  run \"${_NB}\" help weather\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\:       ]]\n  [[ \"${lines[1]}\"  =~  nb\\ weather     ]]\n}\n"
  },
  {
    "path": "test/plugins.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# help ########################################################################\n\n@test \"'help plugins' exits with 0 and prints help information.\" {\n  run \"${_NB}\" help plugins\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:       ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ plugins ]]\n}\n\n# `plugins` ###################################################################\n\n@test \"'plugins' lists sorted plugins installed as files and links.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/clip.nb-plugin\"\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/turquoise.nb-theme\"\n\n    ln -s                                                         \\\n      \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"         \\\n      \"${NB_DIR}/.plugins/example.nb-plugin\"\n\n    diff                                                          \\\n      <(cat \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\")  \\\n      <(cat \"${NB_DIR}/.plugins/example.nb-plugin\")\n  }\n\n  run \"${_NB}\" plugins\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${lines[0]}\"  =~  clip.nb-plugin      ]]\n  [[ \"${lines[1]}\"  =~  example.nb-plugin   ]]\n  [[ \"${lines[2]}\"  =~  turquoise.nb-theme  ]]\n}\n\n@test \"'plugins <name>' lists plugins.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/clip.nb-plugin\"\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/turquoise.nb-theme\"\n\n    ln -s                                                         \\\n      \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"         \\\n      \"${NB_DIR}/.plugins/example.nb-plugin\"\n\n    diff                                                          \\\n      <(cat \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\")  \\\n      <(cat \"${NB_DIR}/.plugins/example.nb-plugin\")\n  }\n\n  run \"${_NB}\" plugins clip.nb-plugin\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                   ]]\n  [[    \"${lines[0]}\" =~  clip.nb-plugin      ]]\n  [[ -z \"${lines[1]}\"                         ]]\n\n  run \"${_NB}\" plugins example.nb-plugin\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                   ]]\n  [[    \"${lines[0]}\" =~  example.nb-plugin   ]]\n  [[ -z \"${lines[1]}\"                         ]]\n\n\n  run \"${_NB}\" plugins turquoise.nb-theme\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                   ]]\n  [[    \"${lines[0]}\" =~  turquoise.nb-theme  ]]\n  [[ -z \"${lines[1]}\"                         ]]\n}\n\n@test \"'plugins <name>' with no matching exits with error.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/turquoise.nb-theme\"\n  }\n\n  run \"${_NB}\" plugins example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  1                     ]]\n  [[    \"${lines[0]}\" =~  No\\ matching\\ plugins ]]\n  [[ -z \"${lines[1]}\"                           ]]\n}\n\n@test \"'plugins' with no plugins exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" plugins\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  1           ]]\n  [[    \"${lines[0]}\" =~  No\\ plugins ]]\n  [[ -z \"${lines[1]}\"                 ]]\n}\n\n# `plugins install` ###########################################################\n\n@test \"'plugins install' with valid <path> argument installs a plugin.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                     ]]\n\n  [[    \"${lines[0]}\" =~  Plugin\\ installed     ]]\n  [[    \"${lines[1]}\" =~  example.nb-plugin     ]]\n\n  [[ -e \"${NB_DIR}/.plugins/example.nb-plugin\"  ]]\n\n\n  run \"${_NB}\" example\n\n  [[    \"${status}\"   ==  0                     ]]\n  [[    \"${lines[0]}\" =~  Hello,\\ World!        ]]\n}\n\n@test \"'plugins install' with valid <path> argument installs a theme plugin.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/turquoise.nb-theme\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                     ]]\n  [[    \"${lines[0]}\" =~  Plugin\\ installed     ]]\n  [[    \"${lines[1]}\" =~  turquoise.nb-theme    ]]\n\n  [[ -e \"${NB_DIR}/.plugins/turquoise.nb-theme\" ]]\n\n  run \"${_NB}\" settings colors themes\n\n  [[    \"${status}\"   ==  0                     ]]\n  [[    \"${output}\"   =~  turquoise             ]]\n}\n\n@test \"'plugins install' with valid <url> argument installs a plugin.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" plugins install file://\"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                     ]]\n  [[    \"${lines[0]}\" =~  Plugin\\ installed     ]]\n  [[    \"${lines[1]}\" =~  example.nb-plugin     ]]\n\n  [[ -e \"${NB_DIR}/.plugins/example.nb-plugin\"  ]]\n\n  run \"${_NB}\" example\n\n  [[    \"${status}\"   ==  0                     ]]\n  [[    \"${lines[0]}\" =~  Hello,\\ World!        ]]\n}\n\n@test \"'plugins install' with valid <url> argument installs a theme plugin.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" plugins install file://\"${NB_TEST_BASE_PATH}/../plugins/turquoise.nb-theme\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                     ]]\n  [[    \"${lines[0]}\" =~  Plugin\\ installed     ]]\n  [[    \"${lines[1]}\" =~  turquoise.nb-theme    ]]\n\n  [[ -e \"${NB_DIR}/.plugins/turquoise.nb-theme\" ]]\n\n  run \"${_NB}\" settings colors themes\n\n  [[    \"${status}\"   ==  0                     ]]\n  [[    \"${output}\"   =~  turquoise             ]]\n}\n\n@test \"'plugins install' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" plugins install \"invalid\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  1                     ]]\n  [[    \"${lines[0]}\" =~  Not\\ a\\ valid         ]]\n}\n\n@test \"'plugins install' with existing plugin reinstalls.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"\n  }\n\n  run \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  0                     ]]\n  [[    \"${output}\"   =~  already\\ installed    ]]\n  [[    \"${output}\"   =~  Plugin\\ installed     ]]\n  [[    \"${output}\"   =~  example.nb-plugin     ]]\n\n  [[ -e \"${NB_DIR}/.plugins/example.nb-plugin\"  ]]\n}\n\n# `plugins uninstall` #########################################################\n\n@test \"'plugins uninstall' with valid <name> argument uninstalls a plugin.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"\n  }\n\n  run \"${_NB}\" plugins uninstall \"example.nb-plugin\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   ==  0                                 ]]\n  [[      \"${lines[0]}\" =~  Plugin\\ successfully\\ uninstalled ]]\n  [[      \"${lines[1]}\" =~  example.nb-plugin                 ]]\n\n  [[ ! -e \"${NB_DIR}/.plugins/example.nb-plugin\"              ]]\n\n}\n\n@test \"'plugins uninstall' with valid <name> argument uninstalls a theme.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/turquoise.nb-theme\"\n  }\n\n  run \"${_NB}\" plugins uninstall \"turquoise.nb-theme\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${status}\"   ==  0                                 ]]\n  [[      \"${lines[0]}\" =~  Plugin\\ successfully\\ uninstalled ]]\n  [[      \"${lines[1]}\" =~  turquoise.nb-theme                ]]\n\n  [[ ! -e \"${NB_DIR}/.plugins/turquoise.nb-theme\"             ]]\n}\n\n@test \"'plugins uninstall' with invalid <name> argument exits with error.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" plugins install \"${NB_TEST_BASE_PATH}/../plugins/example.nb-plugin\"\n  }\n\n  run \"${_NB}\" plugins uninstall \"example\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   ==  1                     ]]\n  [[    \"${lines[0]}\" =~  Plugin\\ not\\ found    ]]\n  [[    \"${lines[0]}\" =~  example               ]]\n  [[ -z \"${lines[1]}\"                           ]]\n\n  [[ -e \"${NB_DIR}/.plugins/example.nb-plugin\"  ]]\n}\n"
  },
  {
    "path": "test/remote-delete.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# error handling ##############################################################\n\n@test \"'remote delete <branch>' with non-valid remote prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" git remote add origin \"https://example.test/example.git\"\n\n    diff                  \\\n      <(\"${_NB}\" remote)  \\\n      <(printf \"https://example.test/example.git (master)\\\\n\")\n  }\n\n  run \"${_NB}\" remote delete \"master\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                   ]]\n  [[ \"${#lines[@]}\" -eq 1                                   ]]\n\n  [[ \"${lines[0]}\"  =~  \\!.*\\ Unable\\ to\\ contact\\ remote\\. ]]\n}\n\n@test \"'remote delete <branch>' with no remote prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" remote delete \"master\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                               ]]\n  [[ \"${#lines[@]}\" -eq 1                               ]]\n\n  [[ \"${lines[0]}\"  =~  \\!.*\\ No\\ remote\\ configured\\.  ]]\n}\n\n@test \"'remote delete' with missing <remote-branch> prints help.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n  }\n\n  run \"${_NB}\" remote delete\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1           ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:   ]]\n  [[ \"${lines[1]}\"  =~  nb\\ remote  ]]\n}\n\n@test \"'remote delete <not-valid>' with missing <remote-branch> prints help.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n  }\n\n  run \"${_NB}\" remote delete \"example-branch\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1           ]]\n  [[ \"${#lines[@]}\" -eq 1           ]]\n\n  [[ \"${lines[0]}\"  =~  Remote\\ branch\\ not\\ found:\\ .*example-branch   ]]\n}\n\n# `remote delete` primary branch ##############################################\n\n@test \"'remote delete <remote-branch>' with primary current <remote-branch> resets remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _example_before_hashes=()\n    _example_before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_example_before_hashes[@]}\"  -eq 2                       ]]\n\n    \"${_NB}\" git log\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    declare _sample_before_hashes=()\n    _sample_before_hashes=($(\"${_NB}\" git rev-list origin/sample-notebook))\n\n    [[ \"${#_sample_before_hashes[@]}\"  -eq 2                        ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Sample\\ File\\.md  ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Demo Notebook\"   ]]\n\n    \"${_NB}\" add \"Demo File.md\" --content \"Demo content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote                  \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)              \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n    declare _demo_before_hashes=()\n    _demo_before_hashes=($(\"${_NB}\" git rev-list origin/demo-notebook))\n\n    [[ \"${#_demo_before_hashes[@]}\"  -eq 2                          ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Demo\\ File\\.md    ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n  }\n\n  run \"${_NB}\" remote delete master <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  Resetting\\ remote\\ branch:\\ .*master        ]]\n  [[ \"${lines[1]}\"  =~  [^-]------------------------[^-]            ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ reset\\.                     ]]\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master  ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/demo-notebook              ]]\n  [[    \"${lines[3]}\"  =~ remotes/origin/master                     ]]\n  [[    \"${lines[4]}\"  =~ remotes/origin/sample-notebook            ]]\n\n  declare _example_after_hashes=()\n  _example_after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  printf \"_example_after_hashes: %s\\\\n\" \"${_example_after_hashes[@]}\"\n\n  [[ \"${#_example_after_hashes[@]}\" -eq 1                             ]]\n\n  _contains \"${_example_after_hashes[0]}\" \"${_example_before_hashes[@]}\" || true\n\n  [[ \"${_example_after_hashes[0]}\"  != \"${_example_before_hashes[0]}\" ]]\n  [[ \"${_example_after_hashes[0]}\"  != \"${_example_before_hashes[1]}\" ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize  ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\n  remotes/origin/master\\\\n\")\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}2${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Example\\ Notebook.*\\.\\.\\.       ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[2]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[3]}\"  =~  Remote\\ branch\\ reset:\\ .*master            ]]\n  [[ \"${lines[4]}\"  =~  Remote\\ removed.                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]---------------[^-]                     ]]\n  [[ \"${lines[6]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n  [[ \"${lines[7]}\"  =~  Done\\!                                      ]]\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n}\n\n@test \"'remote reset <remote-branch>' with primary non-current <remote-branch> resets remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _example_before_hashes=()\n    _example_before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_example_before_hashes[@]}\"  -eq 2                       ]]\n\n    \"${_NB}\" git log\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    declare _sample_before_hashes=()\n    _sample_before_hashes=($(\"${_NB}\" git rev-list origin/sample-notebook))\n\n    [[ \"${#_sample_before_hashes[@]}\"  -eq 2                        ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Sample\\ File\\.md  ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Demo Notebook\"   ]]\n\n    \"${_NB}\" add \"Demo File.md\" --content \"Demo content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote                  \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)              \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n    declare _demo_before_hashes=()\n    _demo_before_hashes=($(\"${_NB}\" git rev-list origin/demo-notebook))\n\n    [[ \"${#_demo_before_hashes[@]}\"  -eq 2                          ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Demo\\ File\\.md    ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n  }\n\n  run \"${_NB}\" remote delete master <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  Resetting\\ remote\\ branch:\\ .*master        ]]\n  [[ \"${lines[1]}\"  =~  [^-]------------------------[^-]            ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ reset\\.                     ]]\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master  ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/demo-notebook              ]]\n  [[    \"${lines[3]}\"  =~ remotes/origin/master                     ]]\n  [[    \"${lines[4]}\"  =~ remotes/origin/sample-notebook            ]]\n\n  declare _example_after_hashes=()\n  _example_after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  printf \"_example_after_hashes: %s\\\\n\" \"${_example_after_hashes[@]}\"\n\n  [[ \"${#_example_after_hashes[@]}\" -eq 1                             ]]\n\n  _contains \"${_example_after_hashes[0]}\" \"${_example_before_hashes[@]}\" || true\n\n  [[ \"${_example_after_hashes[0]}\"  != \"${_example_before_hashes[0]}\" ]]\n  [[ \"${_example_after_hashes[0]}\"  != \"${_example_before_hashes[1]}\" ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize  ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" ls-remote                    \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\n  remotes/origin/sample-notebook\\\\n\")\n\n\n  \"${_NB}\" notebooks use \"Example Notebook\"\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}2${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Example\\ Notebook.*\\.\\.\\.       ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[2]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[3]}\"  =~  Remote\\ branch\\ reset:\\ .*master            ]]\n  [[ \"${lines[4]}\"  =~  Remote\\ removed.                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]---------------[^-]                     ]]\n  [[ \"${lines[6]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n  [[ \"${lines[7]}\"  =~  Done\\!                                      ]]\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n}\n\n# `remote delete` orphan branch ###############################################\n\n@test \"'remote delete <remote-branch>' with orphan current <remote-branch> deletes remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Demo Notebook\"   ]]\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote                  \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)              \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n  }\n\n  run \"${_NB}\" remote delete sample-notebook <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  Deleting\\ remote\\ branch:\\ .*sample-notebook  ]]\n  [[ \"${lines[1]}\"  =~  [^-]-----------------------[^-]               ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ deleted\\.                     ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" ls-remote                    \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n\")\n\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}2${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Sample\\ Notebook.*\\.\\.\\.        ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[2]}\"  =~  \\\nBranch\\ not\\ present\\ on\\ remote:\\ .*sample-notebook                ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*1.*].*\\ Merge\\ and\\ sync\\ with\\ an\\ existing\\ remote\\ branch\\. ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*2.*].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.    ]]\n  [[ \"${lines[5]}\"  =~  [^-]------------------------------[^-]      ]]\n  [[ \"${lines[6]}\"  =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\       ]]\n  [[ \"${lines[6]}\"  =~  \\\nname,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\.        ]]\n  [[ \"${lines[7]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[8]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[9]}\"  =~  Remote\\ removed.                            ]]\n  [[ \"${lines[10]}\" =~  [^-]---------------[^-]                     ]]\n  [[ \"${lines[11]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*sample-notebook.*\\)   ]]\n  [[ \"${lines[12]}\" =~  Done\\!                                      ]]\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n}\n\n@test \"'remote delete <remote-branch>' with orphan non-current <remote-branch> deletes remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Demo Notebook\"   ]]\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote                  \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)              \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n  }\n\n  run \"${_NB}\" remote delete sample-notebook <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  Deleting\\ remote\\ branch:\\ .*sample-notebook  ]]\n  [[ \"${lines[1]}\"  =~  [^-]-----------------------[^-]               ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ deleted\\.                     ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\n  remotes/origin/master\\\\n\")\n\n\n  \"${_NB}\" notebooks use \"Sample Notebook\"\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}2${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Sample\\ Notebook.*\\.\\.\\.        ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[2]}\"  =~  \\\nBranch\\ not\\ present\\ on\\ remote:\\ .*sample-notebook                ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*1.*].*\\ Merge\\ and\\ sync\\ with\\ an\\ existing\\ remote\\ branch\\. ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*2.*].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.    ]]\n  [[ \"${lines[5]}\"  =~  [^-]------------------------------[^-]      ]]\n  [[ \"${lines[6]}\"  =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\       ]]\n  [[ \"${lines[6]}\"  =~  \\\nname,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\.        ]]\n  [[ \"${lines[7]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[8]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[9]}\"  =~  Remote\\ removed.                            ]]\n  [[ \"${lines[10]}\" =~  [^-]---------------[^-]                     ]]\n  [[ \"${lines[11]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*sample-notebook.*\\)   ]]\n  [[ \"${lines[12]}\" =~  Done\\!                                      ]]\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n}\n"
  },
  {
    "path": "test/remote-remove.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# alias #######################################################################\n\n@test \"'unset remote' with no existing remote returns 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" unset remote\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                       ]]\n  [[ \"${lines[0]}\"  =~  No\\ remote\\ configured  ]]\n}\n\n# --skip-confirmation #########################################################\n\n@test \"'remote remove --skip-confirmation' with existing remote removes remote without resetting default branch and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    diff                                      \\\n      <(\"${_NB}\" remote)                      \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" branch --all) \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _before_hashes=()\n    _before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_before_hashes[@]}\"  -eq 2                                 ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md   ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initial\\ commit\\.                 ]]\n  }\n\n  run \"${_NB}\" remote remove --skip-confirmation <<< \"n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote && return 1\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\"  =~  No\\ remote\\ configured.           ]]\n\n  [[ \"${lines[0]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}       ]]\n  [[ \"${lines[1]}\"  =~  Remote\\ removed.                              ]]\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" branch --all)   \\\n    <(printf \"* master\\\\n\")\n\n  # does not reset remote\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"          \\\n        | sed \"s/.*\\///g\" || :)               \\\n    <(printf \"master\\\\n\")\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                  ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master    ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/master                       ]]\n\n  [[ -f \"${_TMP_DIR}/new-clone/Example File.md\"                       ]]\n\n  declare _after_hashes=()\n  _after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  [[ \"${#_after_hashes[@]}\" -eq 2                                     ]]\n\n  [[ \"${_after_hashes[0]}\"  ==  \"${_before_hashes[0]}\"                ]]\n  [[ \"${_after_hashes[1]}\"  ==  \"${_before_hashes[1]}\"                ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[    \"$(git -C \"${_TMP_DIR}/new-clone\" log)\" =~  \\\n          \\[nb\\]\\ Add:\\ Example\\ File\\.md             ]]\n  [[    \"$(git -C \"${_TMP_DIR}/new-clone\" log)\" =~  \\\n          Initial\\ commit\\.                           ]]\n  [[ !  \"$(git -C \"${_TMP_DIR}/new-clone\" log)\" =~  \\\n          \\[nb\\]\\ Initialize                          ]]\n}\n\n@test \"'remote remove --skip-confirmation' with existing remote removes remote, resets default branch, and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    diff                                      \\\n      <(\"${_NB}\" remote)                      \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" branch --all) \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _before_hashes=()\n    _before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_before_hashes[@]}\"  -eq 2                                 ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md   ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initial\\ commit\\.                 ]]\n  }\n\n  run \"${_NB}\" remote remove --skip-confirmation <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote && return 1\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\" =~ No\\ remote\\ configured.             ]]\n\n  [[ \"${lines[0]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}       ]]\n  [[ \"${lines[1]}\"  =~  Remote\\ branch\\ reset:\\ .*master              ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ removed.                              ]]\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" branch --all)   \\\n    <(printf \"* master\\\\n\")\n\n  # resets remote\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"          \\\n        | sed \"s/.*\\///g\" || :)               \\\n    <(printf \"master\\\\n\")\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${lines[0]}\"  =~ \\*\\ master                                  ]]\n  [[      \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master    ]]\n  [[      \"${lines[2]}\"  =~ remotes/origin/master                       ]]\n\n  [[ ! -e \"${_TMP_DIR}/new-clone/Example File.md\"                       ]]\n\n  declare _after_hashes=()\n  _after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  [[ \"${#_after_hashes[@]}\" -eq 1                                       ]]\n\n  _contains \"${_after_hashes[0]}\" \"${_before_hashes[@]}\" || true\n\n  [[ \"${_after_hashes[0]}\"  != \"${_before_hashes[0]}\"                   ]]\n  [[ \"${_after_hashes[0]}\"  != \"${_before_hashes[1]}\"                   ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize    ]]\n}\n\n# remote remove ###############################################################\n\n@test \"'remote remove' with no existing remote returns 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n  }\n\n  run \"${_NB}\" remote remove\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                       ]]\n  [[ \"${lines[0]}\"  =~  No\\ remote\\ configured  ]]\n}\n\n@test \"'remote remove' with existing remote removes remote without resetting default branch and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    diff                                      \\\n      <(\"${_NB}\" remote)                      \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" branch --all) \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _before_hashes=()\n    _before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_before_hashes[@]}\"  -eq 2                                 ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md   ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initial\\ commit\\.                 ]]\n  }\n\n  run \"${_NB}\" remote remove <<< \"y${_NEWLINE}n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote && return 1\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\"  =~  No\\ remote\\ configured.           ]]\n\n  [[ \"${lines[0]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}       ]]\n  [[ \"${lines[1]}\"  =~  Remote\\ removed.                              ]]\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" branch --all)   \\\n    <(printf \"* master\\\\n\")\n\n  # does not reset remote\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"          \\\n        | sed \"s/.*\\///g\" || :)               \\\n    <(printf \"master\\\\n\")\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                  ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master    ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/master                       ]]\n\n  [[ -f \"${_TMP_DIR}/new-clone/Example File.md\"                       ]]\n\n  declare _after_hashes=()\n  _after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  [[ \"${#_after_hashes[@]}\" -eq 2                                     ]]\n\n  [[ \"${_after_hashes[0]}\"  ==  \"${_before_hashes[0]}\"                ]]\n  [[ \"${_after_hashes[1]}\"  ==  \"${_before_hashes[1]}\"                ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[    \"$(git -C \"${_TMP_DIR}/new-clone\" log)\" =~  \\\n          \\[nb\\]\\ Add:\\ Example\\ File\\.md             ]]\n  [[    \"$(git -C \"${_TMP_DIR}/new-clone\" log)\" =~  \\\n          Initial\\ commit\\.                           ]]\n  [[ !  \"$(git -C \"${_TMP_DIR}/new-clone\" log)\" =~  \\\n          \\[nb\\]\\ Initialize                          ]]\n}\n\n@test \"'remote remove' with existing remote removes remote, resets default branch, and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    diff                                      \\\n      <(\"${_NB}\" remote)                      \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" branch --all) \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _before_hashes=()\n    _before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_before_hashes[@]}\"  -eq 2                                 ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md   ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initial\\ commit\\.                 ]]\n  }\n\n  run \"${_NB}\" remote remove <<< \"y${_NEWLINE}y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote && return 1\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\" =~ No\\ remote\\ configured.             ]]\n\n  [[ \"${lines[0]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}       ]]\n  [[ \"${lines[1]}\"  =~  Remote\\ branch\\ reset:\\ .*master              ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ removed.                              ]]\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" branch --all)   \\\n    <(printf \"* master\\\\n\")\n\n  # resets remote\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"          \\\n        | sed \"s/.*\\///g\" || :)               \\\n    <(printf \"master\\\\n\")\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${lines[0]}\"  =~ \\*\\ master                                  ]]\n  [[      \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master    ]]\n  [[      \"${lines[2]}\"  =~ remotes/origin/master                       ]]\n\n  [[ ! -e \"${_TMP_DIR}/new-clone/Example File.md\"                       ]]\n\n  declare _after_hashes=()\n  _after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  [[ \"${#_after_hashes[@]}\" -eq 1                                       ]]\n\n  _contains \"${_after_hashes[0]}\" \"${_before_hashes[@]}\" || true\n\n  [[ \"${_after_hashes[0]}\"  != \"${_before_hashes[0]}\"                   ]]\n  [[ \"${_after_hashes[0]}\"  != \"${_before_hashes[1]}\"                   ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize    ]]\n}\n\n@test \"'remote unset' with existing remote removes remote, resets default branch, and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    diff                                      \\\n      <(\"${_NB}\" remote)                      \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" branch --all) \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _before_hashes=()\n    _before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_before_hashes[@]}\"  -eq 2                                 ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md   ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initial\\ commit\\.                 ]]\n  }\n\n  run \"${_NB}\" remote unset <<< \"y${_NEWLINE}y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote && return 1\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\" =~ No\\ remote\\ configured.             ]]\n\n  [[ \"${lines[0]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}       ]]\n  [[ \"${lines[1]}\"  =~  Remote\\ branch\\ reset:\\ .*master              ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ removed.                              ]]\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" branch --all)   \\\n    <(printf \"* master\\\\n\")\n\n  # resets remote\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"          \\\n        | sed \"s/.*\\///g\" || :)               \\\n    <(printf \"master\\\\n\")\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[      \"${lines[0]}\"  =~ \\*\\ master                                  ]]\n  [[      \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master    ]]\n  [[      \"${lines[2]}\"  =~ remotes/origin/master                       ]]\n\n  [[ ! -e \"${_TMP_DIR}/new-clone/Example File.md\"                       ]]\n\n  declare _after_hashes=()\n  _after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  [[ \"${#_after_hashes[@]}\" -eq 1                                       ]]\n\n  _contains \"${_after_hashes[0]}\" \"${_before_hashes[@]}\" || true\n\n  [[ \"${_after_hashes[0]}\"  != \"${_before_hashes[0]}\"                   ]]\n  [[ \"${_after_hashes[0]}\"  != \"${_before_hashes[1]}\"                   ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize    ]]\n}\n\n@test \"'remote remove' with existing remote as orphan removes remote, removes branch and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                      \\\n      <(\"${_NB}\" remote)                      \\\n      <(printf \"%s (example-branch)\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" branch --all) \\\n      <(printf \"* example-branch\\\\n  remotes/origin/example-branch\\\\n\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" ls-remote     \\\n          --heads \"${_GIT_REMOTE_URL}\"        \\\n          | sed \"s/.*\\///g\" || :)             \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" remote remove <<< \"y${_NEWLINE}y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote && return 1\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\" =~ No\\ remote\\ configured.           ]]\n\n  [[ \"${lines[0]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[1]}\"  =~  Remote\\ branch\\ deleted:\\ .*example-branch  ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ removed.                            ]]\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"          \\\n        | sed \"s/.*\\///g\" || :)               \\\n    <(printf \"master\\\\n\")\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" branch --all)   \\\n    <(printf \"* example-branch\\\\n\")\n}\n\n@test \"'remote remove' with existing remote as orphan removes remote without removing remote branch and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                      \\\n      <(\"${_NB}\" remote)                      \\\n      <(printf \"%s (example-branch)\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" branch --all) \\\n      <(printf \"* example-branch\\\\n  remotes/origin/example-branch\\\\n\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" ls-remote     \\\n          --heads \"${_GIT_REMOTE_URL}\"        \\\n          | sed \"s/.*\\///g\" || :)             \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" remote remove <<< \"y${_NEWLINE}n${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote && return 1\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\" =~ No\\ remote\\ configured.         ]]\n\n  [[ \"${lines[0]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}   ]]\n  [[ \"${lines[1]}\"  =~  Remote\\ removed.                          ]]\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"          \\\n        | sed \"s/.*\\///g\" || :)               \\\n    <(printf \"example-branch\\\\nmaster\\\\n\")\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" branch --all)   \\\n    <(printf \"* example-branch\\\\n\")\n}\n"
  },
  {
    "path": "test/remote-rename.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# `remote rename` #############################################################\n\n@test \"'remote rename <remote-branch> <name>' with orphan <remote-branch> updates remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n  }\n\n  run \"${_NB}\" remote rename sample-notebook \"updated-branch-name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '\\\\n%s\\\\n'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  Renaming\\ remote\\ branch                    ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------[^-]              ]]\n  [[ \"${lines[2]}\"  =~  From:\\ sample-notebook                      ]]\n  [[ \"${lines[3]}\"  =~  To:\\ \\ \\ .*updated-branch-name.*$           ]]\n  [[ \"${lines[4]}\"  =~  [^-]-----------[^-]                         ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\nupdated-branch-name\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\n  remotes/origin/master\\\\n\")\n\n\n  \"${_NB}\" notebooks use \"Sample Notebook\"\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\nupdated-branch-name\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}1${_NEWLINE}2${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[2]}\"  =~  \\\nBranch\\ not\\ present\\ on\\ remote:\\ .*sample-notebook                ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*[.*1.*].*\\ Merge\\ and\\ sync\\ with\\ an\\ existing\\ remote\\ branch\\. ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*[.*2.*].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.    ]]\n  [[ \"${lines[5]}\"  =~  [^-]------------------------------[^-]      ]]\n  [[ \"${lines[6]}\"  =~  Remote\\ branches:                           ]]\n  [[ \"${lines[7]}\"  =~  .*[.*1.*].*\\ master                         ]]\n  [[ \"${lines[8]}\"  =~  .*[.*2.*].*\\ updated-branch-name            ]]\n  [[ \"${lines[9]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[10]}\" =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[11]}\" =~  Remote\\ removed.                            ]]\n  [[ \"${lines[12]}\" =~  [^-]---------------[^-]                     ]]\n  [[ \"${lines[13]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*updated-branch-name.*\\)  ]]\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\nupdated-branch-name\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (updated-branch-name)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* updated-branch-name\\\\n  remotes/origin/updated-branch-name\\\\n\")\n}\n\n@test \"'remote rename <name>' with orphan current branch updates local and remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n  }\n\n  run \"${_NB}\" remote rename \"updated-branch-name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 1                                             ]]\n\n  [[ \"${output}\"  =~  \\\n!.*\\ Only\\ orphan\\ branches\\ can\\ be\\ renamed\\.                     ]]\n\n  printf \"local branches:     '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:    '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch: '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n}\n\n# error handling ##############################################################\n\n@test \"'remote rename <remote-branch> <name>' with <remote-branch> as remote HEAD prints message without updating.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n  }\n\n  run \"${_NB}\" remote rename master \"updated-branch-name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 1                                             ]]\n\n  [[ \"${output}\"  =~  \\\n!.*\\ Only\\ orphan\\ branches\\ can\\ be\\ renamed\\.                     ]]\n\n  printf \"local branches:     '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:    '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" ls-remote                    \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch: '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n}\n\n@test \"'remote rename <name>' with current branch as remote HEAD prints message without updating.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n  }\n\n  run \"${_NB}\" remote rename \"updated-branch-name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 1                                             ]]\n\n  [[ \"${output}\"  =~  \\\n!.*\\ Only\\ orphan\\ branches\\ can\\ be\\ renamed\\.                     ]]\n\n  printf \"local branches:     '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:    '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                    \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch: '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n}\n\n@test \"'remote rename <remote-branch> <name>' with only one remote branch displays message without updating.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n  }\n\n  run \"${_NB}\" remote rename master \"updated-branch-name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 1                                             ]]\n\n  [[ \"${output}\"  =~  \\\n!.*\\ Only\\ orphan\\ branches\\ can\\ be\\ renamed\\.                     ]]\n\n  printf \"local branches:     '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:    '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch: '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n}\n\n@test \"'remote rename <name>' with only one remote branch displays message without updating.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n  }\n\n  run \"${_NB}\" remote rename \"updated-branch-name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 1                                             ]]\n\n  [[ \"${output}\"  =~  \\\n!.*\\ Only\\ orphan\\ branches\\ can\\ be\\ renamed\\.                     ]]\n\n  printf \"local branches:     '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:    '%s'\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch: '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n}\n\n@test \"'remote rename <name>' with no remote renames current branch.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/home\" branch --all)                       \\\n      <(printf \"* master\\\\n\")\n\n    [[ \"$(\"${_NB}\" remote 2>&1)\" =~  \\!.*\\ No\\ remote\\ configured\\. ]]\n  }\n\n  run \"${_NB}\" remote rename \"updated-branch-name\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  Renaming\\ current\\ branch                   ]]\n  [[ \"${lines[1]}\"  =~  [^-]-----------------------[^-]             ]]\n  [[ \"${lines[2]}\"  =~  From:\\ master                               ]]\n  [[ \"${lines[3]}\"  =~  To:\\ \\ \\ .*updated-branch-name.*$           ]]\n  [[ \"${lines[4]}\"  =~  [^-]-----------[^-]                         ]]\n  [[ \"${lines[5]}\"  =~  Renamed\\ to:\\ .*updated-branch-name.*$      ]]\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/home\" branch --all)                       \\\n      <(printf \"* updated-branch-name\\\\n\")\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\" =~  \\!.*\\ No\\ remote\\ configured\\.   ]]\n}\n\n@test \"'remote rename' with missing <name> prints help.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n  }\n\n  run \"${_NB}\" remote rename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                       ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:               ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ remote          ]]\n}\n"
  },
  {
    "path": "test/remote-reset.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# error handling ##############################################################\n\n@test \"'remote reset <branch>' with non-valid remote prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" git remote add origin \"https://example.test/example.git\"\n\n    diff                  \\\n      <(\"${_NB}\" remote)  \\\n      <(printf \"https://example.test/example.git (master)\\\\n\")\n  }\n\n  run \"${_NB}\" remote reset \"master\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                   ]]\n  [[ \"${#lines[@]}\" -eq 1                                   ]]\n\n  [[ \"${lines[0]}\"  =~  \\!.*\\ Unable\\ to\\ contact\\ remote\\. ]]\n}\n\n@test \"'remote reset <branch>' with no remote prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" remote reset \"master\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                               ]]\n  [[ \"${#lines[@]}\" -eq 1                               ]]\n\n  [[ \"${lines[0]}\"  =~  \\!.*\\ No\\ remote\\ configured\\.  ]]\n}\n\n@test \"'remote reset' with missing <remote-branch> prints help.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n  }\n\n  run \"${_NB}\" remote reset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1           ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:   ]]\n  [[ \"${lines[1]}\"  =~  nb\\ remote  ]]\n}\n\n@test \"'remote reset <not-valid>' with missing <remote-branch> prints help.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n  }\n\n  run \"${_NB}\" remote reset \"example-branch\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1           ]]\n  [[ \"${#lines[@]}\" -eq 1           ]]\n\n  [[ \"${lines[0]}\"  =~  Remote\\ branch\\ not\\ found:\\ .*example-branch   ]]\n}\n\n# `remote reset` primary branch ###############################################\n\n@test \"'remote reset <remote-branch>' with primary current <remote-branch> resets remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _example_before_hashes=()\n    _example_before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_example_before_hashes[@]}\"  -eq 2                       ]]\n\n    \"${_NB}\" git log\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    declare _sample_before_hashes=()\n    _sample_before_hashes=($(\"${_NB}\" git rev-list origin/sample-notebook))\n\n    [[ \"${#_sample_before_hashes[@]}\"  -eq 2                        ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Sample\\ File\\.md  ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Demo Notebook\"   ]]\n\n    \"${_NB}\" add \"Demo File.md\" --content \"Demo content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote                  \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)              \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n    declare _demo_before_hashes=()\n    _demo_before_hashes=($(\"${_NB}\" git rev-list origin/demo-notebook))\n\n    [[ \"${#_demo_before_hashes[@]}\"  -eq 2                          ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Demo\\ File\\.md    ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n  }\n\n  run \"${_NB}\" remote reset master <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  Resetting\\ remote\\ branch:\\ .*master        ]]\n  [[ \"${lines[1]}\"  =~  [^-]------------------------[^-]            ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ reset\\.                     ]]\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master  ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/demo-notebook              ]]\n  [[    \"${lines[3]}\"  =~ remotes/origin/master                     ]]\n  [[    \"${lines[4]}\"  =~ remotes/origin/sample-notebook            ]]\n\n  declare _example_after_hashes=()\n  _example_after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  printf \"_example_after_hashes: %s\\\\n\" \"${_example_after_hashes[@]}\"\n\n  [[ \"${#_example_after_hashes[@]}\" -eq 1                             ]]\n\n  _contains \"${_example_after_hashes[0]}\" \"${_example_before_hashes[@]}\" || true\n\n  [[ \"${_example_after_hashes[0]}\"  != \"${_example_before_hashes[0]}\" ]]\n  [[ \"${_example_after_hashes[0]}\"  != \"${_example_before_hashes[1]}\" ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize  ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\n  remotes/origin/master\\\\n\")\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}2${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Example\\ Notebook.*\\.\\.\\.       ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[2]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[3]}\"  =~  Remote\\ branch\\ reset:\\ .*master            ]]\n  [[ \"${lines[4]}\"  =~  Remote\\ removed.                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]---------------[^-]                     ]]\n  [[ \"${lines[6]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n  [[ \"${lines[7]}\"  =~  Done\\!                                      ]]\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n}\n\n@test \"'remote reset <remote-branch>' with primary non-current <remote-branch> resets remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _example_before_hashes=()\n    _example_before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_example_before_hashes[@]}\"  -eq 2                       ]]\n\n    \"${_NB}\" git log\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    declare _sample_before_hashes=()\n    _sample_before_hashes=($(\"${_NB}\" git rev-list origin/sample-notebook))\n\n    [[ \"${#_sample_before_hashes[@]}\"  -eq 2                        ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Sample\\ File\\.md  ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Demo Notebook\"   ]]\n\n    \"${_NB}\" add \"Demo File.md\" --content \"Demo content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote                  \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)              \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n    declare _demo_before_hashes=()\n    _demo_before_hashes=($(\"${_NB}\" git rev-list origin/demo-notebook))\n\n    [[ \"${#_demo_before_hashes[@]}\"  -eq 2                          ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Demo\\ File\\.md    ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n  }\n\n  run \"${_NB}\" remote reset master <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  Resetting\\ remote\\ branch:\\ .*master        ]]\n  [[ \"${lines[1]}\"  =~  [^-]------------------------[^-]            ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ reset\\.                     ]]\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master  ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/demo-notebook              ]]\n  [[    \"${lines[3]}\"  =~ remotes/origin/master                     ]]\n  [[    \"${lines[4]}\"  =~ remotes/origin/sample-notebook            ]]\n\n  declare _example_after_hashes=()\n  _example_after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  printf \"_example_after_hashes: %s\\\\n\" \"${_example_after_hashes[@]}\"\n\n  [[ \"${#_example_after_hashes[@]}\" -eq 1                             ]]\n\n  _contains \"${_example_after_hashes[0]}\" \"${_example_before_hashes[@]}\" || true\n\n  [[ \"${_example_after_hashes[0]}\"  != \"${_example_before_hashes[0]}\" ]]\n  [[ \"${_example_after_hashes[0]}\"  != \"${_example_before_hashes[1]}\" ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize  ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" ls-remote                    \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\n  remotes/origin/sample-notebook\\\\n\")\n\n\n  \"${_NB}\" notebooks use \"Example Notebook\"\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}2${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Example\\ Notebook.*\\.\\.\\.       ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[2]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[3]}\"  =~  Remote\\ branch\\ reset:\\ .*master            ]]\n  [[ \"${lines[4]}\"  =~  Remote\\ removed.                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]---------------[^-]                     ]]\n  [[ \"${lines[6]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n  [[ \"${lines[7]}\"  =~  Done\\!                                      ]]\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n}\n\n# `remote reset` orphan branch ################################################\n\n@test \"'remote reset <remote-branch>' with orphan current <remote-branch> resets remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _example_before_hashes=()\n    _example_before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_example_before_hashes[@]}\"  -eq 2                       ]]\n\n    \"${_NB}\" git log\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    declare _sample_before_hashes=()\n    _sample_before_hashes=($(\"${_NB}\" git rev-list origin/sample-notebook))\n\n    [[ \"${#_sample_before_hashes[@]}\"  -eq 2                        ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Sample\\ File\\.md  ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Demo Notebook\"   ]]\n\n    \"${_NB}\" add \"Demo File.md\" --content \"Demo content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote                  \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)              \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n    declare _demo_before_hashes=()\n    _demo_before_hashes=($(\"${_NB}\" git rev-list origin/demo-notebook))\n\n    [[ \"${#_demo_before_hashes[@]}\"  -eq 2                          ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Demo\\ File\\.md    ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n  }\n\n  run \"${_NB}\" remote reset sample-notebook <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  Resetting\\ remote\\ branch:\\ .*sample-notebook ]]\n  [[ \"${lines[1]}\"  =~  [^-]------------------------[^-]              ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ reset\\.                       ]]\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                  ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master    ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/demo-notebook                ]]\n  [[    \"${lines[3]}\"  =~ remotes/origin/master                       ]]\n  [[    \"${lines[4]}\"  =~ remotes/origin/sample-notebook              ]]\n\n  declare _sample_after_hashes=()\n  _sample_after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/sample-notebook))\n\n  printf \"_sample_after_hashes: %s\\\\n\" \"${_sample_after_hashes[@]}\"\n\n  [[ \"${#_sample_after_hashes[@]}\" -eq 1                              ]]\n\n  _contains \"${_sample_after_hashes[0]}\" \"${_sample_before_hashes[@]}\" || true\n\n  [[ \"${_sample_after_hashes[0]}\"  != \"${_sample_before_hashes[0]}\"   ]]\n  [[ \"${_sample_after_hashes[0]}\"  != \"${_sample_before_hashes[1]}\"   ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize  ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" ls-remote                    \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}2${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Sample\\ Notebook.*\\.\\.\\.        ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[2]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[3]}\"  =~  Remote\\ branch\\ deleted:\\ .*sample-notebook ]]\n  [[ \"${lines[4]}\"  =~  Remote\\ removed.                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]---------------[^-]                     ]]\n  [[ \"${lines[6]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*sample-notebook.*\\)   ]]\n  [[ \"${lines[7]}\"  =~  Done\\!                                      ]]\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n}\n\n@test \"'remote reset <remote-branch>' with orphan non-current <remote-branch> resets remote branch.\" {\n  {\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                                       ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"                      ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote               \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _example_before_hashes=()\n    _example_before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_example_before_hashes[@]}\"  -eq 2                       ]]\n\n    \"${_NB}\" git log\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Sample Notebook\" ]]\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)            \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    declare _sample_before_hashes=()\n    _sample_before_hashes=($(\"${_NB}\" git rev-list origin/sample-notebook))\n\n    [[ \"${#_sample_before_hashes[@]}\"  -eq 2                        ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Sample\\ File\\.md  ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name --no-color)\" == \"Demo Notebook\"   ]]\n\n    \"${_NB}\" add \"Demo File.md\" --content \"Demo content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"master\\\\n\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote                  \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")           \\\n      <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)              \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n    declare _demo_before_hashes=()\n    _demo_before_hashes=($(\"${_NB}\" git rev-list origin/demo-notebook))\n\n    [[ \"${#_demo_before_hashes[@]}\"  -eq 2                          ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Demo\\ File\\.md    ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initialize                      ]]\n\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n    diff                                                            \\\n      <(\"${_NB}\" remote)                                            \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)           \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n  }\n\n  run \"${_NB}\" remote reset sample-notebook <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  Resetting\\ remote\\ branch:\\ .*sample-notebook ]]\n  [[ \"${lines[1]}\"  =~  [^-]------------------------[^-]              ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ reset\\.                       ]]\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                  ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master    ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/demo-notebook                ]]\n  [[    \"${lines[3]}\"  =~ remotes/origin/master                       ]]\n  [[    \"${lines[4]}\"  =~ remotes/origin/sample-notebook              ]]\n\n  declare _sample_after_hashes=()\n  _sample_after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/sample-notebook))\n\n  printf \"_sample_after_hashes: %s\\\\n\" \"${_sample_after_hashes[@]}\"\n\n  [[ \"${#_sample_after_hashes[@]}\" -eq 1                              ]]\n\n  _contains \"${_sample_after_hashes[0]}\" \"${_sample_before_hashes[@]}\" || true\n\n  [[ \"${_sample_after_hashes[0]}\"  != \"${_sample_before_hashes[0]}\"   ]]\n  [[ \"${_sample_after_hashes[0]}\"  != \"${_sample_before_hashes[1]}\"   ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize  ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  diff                                                              \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD              \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}')   \\\n    <(printf \"master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote                 \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all)             \\\n    <(printf \"* master\\n  remotes/origin/master\\\\n\")\n\n\n  \"${_NB}\" notebooks use \"Sample Notebook\"\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}2${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local example branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" branch --all\n  )\"\n\n  printf \"local sample branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n  )\"\n\n  printf \"remote branches:\\\\n%s\\\\n\" \"$(\n    git -C \"${NB_DIR}/Example Notebook\" ls-remote                   \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  printf \"remote HEAD branch:     '%s'\\\\n\" \"$(\n    git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD                \\\n      | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}'\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Sample\\ Notebook.*\\.\\.\\.        ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[2]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}     ]]\n  [[ \"${lines[3]}\"  =~  Remote\\ branch\\ deleted:\\ .*sample-notebook ]]\n  [[ \"${lines[4]}\"  =~  Remote\\ removed.                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]---------------[^-]                     ]]\n  [[ \"${lines[6]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*sample-notebook.*\\)   ]]\n  [[ \"${lines[7]}\"  =~  Done\\!                                      ]]\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote                  \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (sample-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)              \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n}\n"
  },
  {
    "path": "test/remote-set.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# reassignment ################################################################\n\n@test \"'remote set <url>' to same existing remote branch sets remote and prints message and resets remote branch.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    diff                  \\\n      <(\"${_NB}\" remote)  \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                       ]]\n\n  [[ \"${lines[0]}\"  =~  Updating\\ remote\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~  From:\\ \\ \\ ${_GIT_REMOTE_URL}                           ]]\n  [[ \"${lines[2]}\"  =~  [^-]-------------------------[^-]                       ]]\n  [[ \"${lines[3]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}                        ]]\n  [[ \"${lines[4]}\"  =~  Branch:\\ .*master                                       ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                                  ]]\n  [[ \"${lines[6]}\"  =~  [^-]--------------[^-]                                  ]]\n  [[ \"${lines[7]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}                 ]]\n  [[ \"${lines[8]}\"  =~  Remote\\ branch\\ reset:\\ .*master                        ]]\n  [[ \"${lines[9]}\"  =~  Remote\\ removed\\.                                       ]]\n  [[ \"${lines[10]}\" =~  [^-]---------------[^-]                                 ]]\n  [[ \"${lines[11]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)                        ]]\n\n  diff                  \\\n    <(\"${_NB}\" remote)  \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n}\n\n# alias #######################################################################\n\n@test \"'set remote <url> <branch>' with no existing remote and no matching remote branch pushes branch as new orphan, sets remote, and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    [[ -f \"${NB_DIR}/home/Example File One.md\"                      ]]\n\n    _setup_remote_repo\n  }\n\n  run \"${_NB}\" set remote \"${_GIT_REMOTE_URL}\" \"example\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"remote:    '%s'\\\\n\" \"$(\"${_NB}\" remote)\"\n\n  [[ \"${status}\"    -eq 0                                               ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*home                     ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------[^-]                  ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}                ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*example                              ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                          ]]\n\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                          ]]\n  [[ \"${lines[6]}\"  =~  Branch\\ not\\ present\\ on\\ remote:\\ .*example    ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*[.*1.*].*\\ Merge\\ and\\ sync\\ with\\ an\\ existing\\ remote\\ branch\\.     ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*[.*2.*].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.        ]]\n  [[ \"${lines[9]}\"  =~  [^-]------------------------------[^-]          ]]\n  [[ \"${lines[10]}\" =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\           ]]\n  [[ \"${lines[10]}\" =~  \\\nname,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\.            ]]\n  [[ \"${lines[11]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*example.*\\)               ]]\n\n  diff                                                                  \\\n    <(git -C \"${NB_DIR}/home\" branch --all)                             \\\n    <(printf \"* example\\\\n  remotes/origin/example\\\\n\")\n\n  run \"${_NB}\" git branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\" =~ \\*\\ example                                    ]]\n  [[    \"${lines[1]}\" =~ remotes/origin/example                         ]]\n  [[ !  \"${output}\"   =~ remotes/origin/master                          ]]\n\n  git clone --branch \"example\" \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ example                                   ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master      ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/example                        ]]\n  [[    \"${lines[3]}\"  =~ remotes/origin/master                         ]]\n\n  [[ -f \"${_TMP_DIR}/new-clone/Example File One.md\"                     ]]\n\n  diff                                                                  \\\n    <(\"${_NB}\" remote)                                                  \\\n    <(printf \"%s (example)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  \"${_NB}\" git fetch origin\n  \"${_NB}\" git push origin\n\n  declare _master_branch_hashes=()\n  _master_branch_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n  [[ \"${#_master_branch_hashes[@]}\"   == \"1\"                            ]]\n\n  declare _example_branch_hashes=()\n  _example_branch_hashes=($(\"${_NB}\" git rev-list origin/example))\n\n  [[ \"${#_example_branch_hashes[@]}\"  == \"2\"                            ]]\n\n  [[ \"${_master_branch_hashes[0]}\"    != \"${_example_branch_hashes[0]}\" ]]\n  [[ \"${_master_branch_hashes[0]}\"    != \"${_example_branch_hashes[1]}\" ]]\n}\n\n# merge with existing branch ##################################################\n\n@test \"'remote set <url> <branch>' with unshared histories syncs to same branch.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n  }\n\n  # Notebook One\n\n  {\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Notebook One\"\n    cd \"${_TMP_DIR}/Notebook One\"\n\n    \"${_NB}\" add \"File One.md\" --content \"Content.\"\n\n    [[    -f \"${_TMP_DIR}/Notebook One/File One.md\"                 ]]\n    [[ !  -f \"${_TMP_DIR}/Notebook One/File Two.md\"                 ]]\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" \"shared-branch\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local branches:   '%s'\\\\n\" \"$(\n    git -C \"${_TMP_DIR}/Notebook One\" branch --all\n  )\"\n\n  printf \"remote branches:  '%s'\\\\n\" \"$(\n    git -C \"${_TMP_DIR}/Notebook One\" ls-remote                     \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*local                ]]\n  [[ \"${lines[1]}\"  =~  [^-]-----------------------[^-]             ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}            ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*shared-branch                    ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[5]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*shared-branch.*\\)     ]]\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (shared-branch)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${_TMP_DIR}/Notebook One\" branch --all)               \\\n    <(printf \"* shared-branch\\\\n  remotes/origin/shared-branch\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${_TMP_DIR}/Notebook One\" ls-remote                   \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"shared-branch\\\\n\")\n\n  # Notebook Two\n\n  {\n    sleep 1\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Notebook Two\"\n    cd \"${_TMP_DIR}/Notebook Two\"\n\n    \"${_NB}\" add \"File Two.md\" --content \"Content.\"\n\n    [[ !  -f \"${_TMP_DIR}/Notebook Two/File One.md\"                 ]]\n    [[    -f \"${_TMP_DIR}/Notebook Two/File Two.md\"                 ]]\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" \"shared-branch\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local branches:   '%s'\\\\n\" \"$(\n    git -C \"${_TMP_DIR}/Notebook Two\" branch --all\n  )\"\n\n  printf \"remote branches:  '%s'\\\\n\" \"$(\n    git -C \"${_TMP_DIR}/Notebook Two\" ls-remote                     \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*local                ]]\n  [[ \"${lines[1]}\"  =~  [^-]-----------------------[^-]             ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}            ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*shared-branch                    ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[6]}\"  =~  \\\nRemote\\ branch\\ has\\ existing\\ history:\\ .*shared-branch            ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Merge\\ and\\ sync\\ with\\ the\\ existing\\ remote\\ branch\\:\\ .*shared-branch ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*\\[.*2.*\\].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.                      ]]\n  [[ \"${lines[9]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*shared-branch.*\\)     ]]\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (shared-branch)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${_TMP_DIR}/Notebook Two\" branch --all)               \\\n    <(printf \"* shared-branch\\\\n  remotes/origin/shared-branch\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${_TMP_DIR}/Notebook Two\" ls-remote                   \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"shared-branch\\\\n\")\n\n  [[    -f \"${_TMP_DIR}/Notebook Two/File One.md\"                   ]]\n  [[    -f \"${_TMP_DIR}/Notebook Two/File Two.md\"                   ]]\n}\n\n@test \"'remote set <url>' with unshared histories syncs to same branch.\" {\n  {\n    \"${_NB}\" init\n\n    mkdir \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git init --bare &>/dev/null\n\n    cd \"${_TMP_DIR}\"\n  }\n\n  # Notebook One\n\n  {\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Notebook One\"\n    cd \"${_TMP_DIR}/Notebook One\"\n\n    \"${_NB}\" add \"File One.md\" --content \"Example content one.\"\n\n    [[    -f \"${_TMP_DIR}/Notebook One/File One.md\"                 ]]\n    [[ !  -f \"${_TMP_DIR}/Notebook One/File Two.md\"                 ]]\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local branches:   '%s'\\\\n\" \"$(\n    git -C \"${_TMP_DIR}/Notebook One\" branch --all\n  )\"\n\n  printf \"remote branches:  '%s'\\\\n\" \"$(\n    git -C \"${_TMP_DIR}/Notebook One\" ls-remote                     \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*local                ]]\n  [[ \"${lines[1]}\"  =~  [^-]-----------------------[^-]             ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}            ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                           ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[5]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${_TMP_DIR}/Notebook One\" branch --all)               \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${_TMP_DIR}/Notebook One\" ls-remote                   \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\n\")\n\n  # Notebook Two\n\n  {\n    sleep 1\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/Notebook Two\"\n    cd \"${_TMP_DIR}/Notebook Two\"\n\n    \"${_NB}\" add \"File Two.md\" --content \"Sample content two.\"\n\n    [[ !  -f \"${_TMP_DIR}/Notebook Two/File One.md\"                 ]]\n    [[    -f \"${_TMP_DIR}/Notebook Two/File Two.md\"                 ]]\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  printf \"local branches:   '%s'\\\\n\" \"$(\n    git -C \"${_TMP_DIR}/Notebook Two\" branch --all\n  )\"\n\n  printf \"remote branches:  '%s'\\\\n\" \"$(\n    git -C \"${_TMP_DIR}/Notebook Two\" ls-remote                     \\\n      --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\"\n  )\"\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*local                ]]\n  [[ \"${lines[1]}\"  =~  [^-]-----------------------[^-]             ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}            ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                           ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[6]}\"  =~  \\\nRemote\\ branch\\ has\\ existing\\ history:\\ .*master                   ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Merge\\ and\\ sync\\ with\\ the\\ existing\\ remote\\ branch\\:\\ .*master  ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*\\[.*2.*\\].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.                ]]\n  [[ \"${lines[9]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n\n  diff                                                              \\\n    <(\"${_NB}\" remote)                                              \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                              \\\n    <(git -C \"${_TMP_DIR}/Notebook Two\" branch --all)               \\\n    <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n  diff                                                              \\\n    <(git -C \"${_TMP_DIR}/Notebook Two\" ls-remote                   \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")             \\\n    <(printf \"master\\\\n\")\n\n  [[    -f \"${_TMP_DIR}/Notebook Two/File One.md\"                   ]]\n  [[    -f \"${_TMP_DIR}/Notebook Two/File Two.md\"                   ]]\n}\n\n# empty remote ################################################################\n\n@test \"'remote set' with empty remote pushes branch.\" {\n  {\n    mkdir \"${_TMP_DIR}/bare-repo\"\n    cd \"${_TMP_DIR}/bare-repo\"\n    git init\n    mv \"${_TMP_DIR}/bare-repo/.git\" \"${_GIT_REMOTE_PATH}\"\n    cd \"${_GIT_REMOTE_PATH}\"\n    git config --bool core.bare true\n\n    cd \"${_TMP_DIR}\"\n\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                   ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"  ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*Example\\ Notebook    ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------------------[^-]  ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}            ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                           ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[5]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n\n  diff                                                            \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n    <(printf \"master\\\\n\")\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote     \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\") \\\n    <(printf \"master\\\\n\")\n\n  diff                  \\\n    <(\"${_NB}\" remote)  \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n}\n\n# exiting #####################################################################\n\n@test \"'remote set' with exit on third prompt does not set new remote.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                   ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"  ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n\n    declare _example_hashes=()\n    _example_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" git branch -m \"sample-branch\"\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}q${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"                -eq 0                       ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\"  =~  No\\ remote\\ configured. ]]\n}\n\n@test \"'remote set' with exit on second prompt does not set new remote.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                   ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"  ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n\n    declare _example_hashes=()\n    _example_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" git branch -m \"sample-branch\"\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}q${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"                -eq 0                       ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\"  =~  No\\ remote\\ configured. ]]\n}\n\n# remote set ##################################################################\n\n@test \"'remote set' with unrelated histories displays prompt and merges with existing branch.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                               ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"              ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n\n    declare _example_hashes=()\n    _example_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                 ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*Sample\\ Notebook           ]]\n  [[ \"${lines[1]}\"  =~  [^-]---------------------------------[^-]         ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}                  ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                                 ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[6]}\"  =~  Remote\\ branch\\ has\\ existing\\ history:\\ .*master ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Merge\\ and\\ sync\\ with\\ the\\ existing\\ remote\\ branch\\:\\ .*master  ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*\\[.*2.*\\].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.                ]]\n  [[ \"${lines[9]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)                  ]]\n\n  diff                                                            \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n    <(printf \"master\\\\n\")\n\n  diff                                                    \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote        \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")   \\\n    <(printf \"master\\\\n\")\n\n  declare _sample_hashes=()\n  _sample_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n  [[ \"${#_example_hashes[@]}\" -eq 2                       ]]\n  [[ \"${#_sample_hashes[@]}\"  -eq 3                       ]]\n\n  [[ \"${_example_hashes[0]}\"  ==  \"${_sample_hashes[1]}\"  ]]\n  [[ \"${_example_hashes[1]}\"  ==  \"${_sample_hashes[2]}\"  ]]\n\n  _contains \"${_example_hashes[0]}\" \"${_sample_hashes[@]}\"\n  _contains \"${_example_hashes[1]}\" \"${_sample_hashes[@]}\"\n}\n\n@test \"'remote set' with unrelated histories displays prompts and merges with selected existing branch.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                               ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"              ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n\n    diff                                                    \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote       \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")   \\\n      <(printf \"master\\\\n\")\n\n    diff                                                    \\\n      <(\"${_NB}\" remote)                                    \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                    \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all)   \\\n      <(printf \"* master\\\\n  remotes/origin/HEAD -> origin/master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _example_hashes=()\n    _example_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    \"${_NB}\" add \"Demo File.md\" --content \"Demo content.\"\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    diff                                                    \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" ls-remote          \\\n          --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")   \\\n      <(printf \"demo-notebook\\\\nmaster\\\\n\")\n\n    diff                                                    \\\n      <(\"${_NB}\" remote)                                    \\\n      <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    diff                                                    \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)      \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n    declare _demo_hashes=()\n    _demo_hashes=($(\"${_NB}\" git rev-list origin/demo-notebook))\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                 ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*Sample\\ Notebook           ]]\n  [[ \"${lines[1]}\"  =~  [^-]---------------------------------[^-]         ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}                  ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                                 ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[6]}\"  =~  Remote\\ branch\\ has\\ existing\\ history:\\ .*master ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Merge\\ and\\ sync\\ with\\ the\\ existing\\ remote\\ branch\\:\\ .*master  ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*\\[.*2.*\\].*\\ Merge\\ and\\ sync\\ with\\ a\\ different\\ existing\\ remote\\ branch\\.   ]]\n  [[ \"${lines[9]}\"  =~  \\\n.*\\[.*3.*\\].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.                ]]\n\n  [[ \"${lines[10]}\"  =~  [^-]------------------------------[^-]           ]]\n  [[ \"${lines[11]}\" =~  Remote\\ branches:                                 ]]\n  [[ \"${lines[12]}\" =~  .*[.*1.*].*\\ demo-notebook                        ]]\n  [[ \"${lines[13]}\" =~  .*[.*2.*].*\\ master                               ]]\n\n  [[ \"${lines[14]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*demo-notebook.*\\)           ]]\n\n  diff                                                    \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" ls-remote        \\\n        --heads \"${_GIT_REMOTE_URL}\" | sed \"s/.*\\///g\")   \\\n    <(printf \"demo-notebook\\\\nmaster\\\\n\")\n\n  diff                                                    \\\n    <(\"${_NB}\" remote)                                    \\\n    <(printf \"%s (demo-notebook)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  diff                                                    \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)    \\\n    <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n  declare _sample_hashes=()\n  _sample_hashes=($(\"${_NB}\" git rev-list origin/demo-notebook))\n\n  printf \"\\${#_example_hashes[@]}:  '%s'\\\\n\" \"${#_example_hashes[@]}\"\n  printf \"\\${#_demo_hashes[@]}:     '%s'\\\\n\" \"${#_demo_hashes[@]}\"\n  printf \"\\${#_sample_hashes[@]}:   '%s'\\\\n\" \"${#_sample_hashes[@]}\"\n\n  [[ \"${#_example_hashes[@]}\" -eq 2                       ]]\n  [[ \"${#_demo_hashes[@]}\"    -eq 2                       ]]\n  [[ \"${#_sample_hashes[@]}\"  -eq 3                       ]]\n\n  [[ \"${_demo_hashes[0]}\"     ==  \"${_sample_hashes[1]}\"  ]]\n  [[ \"${_demo_hashes[1]}\"     ==  \"${_sample_hashes[2]}\"  ]]\n\n  _contains   \"${_demo_hashes[0]}\" \"${_sample_hashes[@]}\"\n  _contains   \"${_demo_hashes[1]}\" \"${_sample_hashes[@]}\"\n\n  _contains \"${_example_hashes[0]}\" \"${_sample_hashes[@]}\" || true\n  _contains \"${_example_hashes[1]}\" \"${_sample_hashes[@]}\" || true\n}\n\n@test \"'remote set' with unrelated histories displays prompt and creates new orphan branch with name from prompt.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                             ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"            ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n\n  diff                                                    \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"                      \\\n        | sed \"s/.*\\///g\" || :)                           \\\n    <(printf \"master\\\\n\")\n\n    declare _example_hashes=()\n    _example_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\"            \\\n    <<< \"y${_NEWLINE}3${_NEWLINE}branch-name-from-prompt${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                 ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*Sample\\ Notebook           ]]\n  [[ \"${lines[1]}\"  =~  [^-]---------------------------------[^-]         ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}                  ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                                 ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[6]}\"  =~  Remote\\ branch\\ has\\ existing\\ history:\\ .*master ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Merge\\ and\\ sync\\ with\\ the\\ existing\\ remote\\ branch\\:\\ .*master  ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*\\[.*2.*\\].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.                ]]\n  [[ \"${lines[9]}\"  =~  [^-]------------------------------[^-]            ]]\n  [[ \"${lines[10]}\" =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\             ]]\n  [[ \"${lines[10]}\" =~  \\\nname,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\.              ]]\n  [[ \"${lines[11]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*branch-name-from-prompt.*\\) ]]\n\n  diff                                                    \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"                      \\\n        | sed \"s/.*\\///g\" || :)                           \\\n    <(printf \"branch-name-from-prompt\\\\nmaster\\\\n\")\n\n  declare _sample_hashes=()\n  _sample_hashes=($(\"${_NB}\" git rev-list origin/branch-name-from-prompt))\n\n  [[ \"${#_example_hashes[@]}\" -eq 2                       ]]\n  [[ \"${#_sample_hashes[@]}\"  -eq 2                       ]]\n\n  _contains \"${_example_hashes[0]}\" \"${_sample_hashes[@]}\" || true\n  _contains \"${_example_hashes[1]}\" \"${_sample_hashes[@]}\" || true\n}\n\n@test \"'remote set' with unrelated histories displays prompt and creates new orphan branch named after notebook.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                             ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"            ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n\n  diff                                                    \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"                      \\\n        | sed \"s/.*\\///g\" || :)                           \\\n    <(printf \"master\\\\n\")\n\n    declare _example_hashes=()\n    _example_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                 ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*Sample\\ Notebook           ]]\n  [[ \"${lines[1]}\"  =~  [^-]---------------------------------[^-]         ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}                  ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                                 ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[6]}\"  =~  Remote\\ branch\\ has\\ existing\\ history:\\ .*master ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Merge\\ and\\ sync\\ with\\ the\\ existing\\ remote\\ branch\\:\\ .*master  ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*\\[.*2.*\\].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.                ]]\n  [[ \"${lines[9]}\"  =~  [^-]------------------------------[^-]            ]]\n  [[ \"${lines[10]}\" =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\             ]]\n  [[ \"${lines[10]}\" =~  \\\nname,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\.              ]]\n  [[ \"${lines[11]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*sample-notebook.*\\)         ]]\n\n  diff                                                    \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"                      \\\n        | sed \"s/.*\\///g\" || :)                           \\\n    <(printf \"master\\\\nsample-notebook\\\\n\")\n\n  declare _sample_hashes=()\n  _sample_hashes=($(\"${_NB}\" git rev-list origin/sample-notebook))\n\n  [[ \"${#_example_hashes[@]}\" -eq 2                       ]]\n  [[ \"${#_sample_hashes[@]}\"  -eq 2                       ]]\n\n  _contains \"${_example_hashes[0]}\" \"${_sample_hashes[@]}\" || true\n  _contains \"${_example_hashes[1]}\" \"${_sample_hashes[@]}\" || true\n}\n\n@test \"'remote set <url>' with no existing remote and matching branch name with no history sets remote and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*home                   ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------[^-]                ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}              ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                             ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                        ]]\n  [[ \"${lines[5]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)              ]]\n\n  diff                  \\\n    <(\"${_NB}\" remote)  \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n}\n\n@test \"'remote set <url>' with existing invalid remote sets remote and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" git remote add origin \"https://example.test/example.git\"\n\n    diff                  \\\n      <(\"${_NB}\" remote)  \\\n      <(printf \"https://example.test/example.git (master)\\\\n\")\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                       ]]\n\n  [[ \"${lines[0]}\"  =~  Updating\\ remote\\ for:\\ .*home                          ]]\n  [[ \"${lines[1]}\"  =~  From:\\ \\ \\ https://example.test/example.git             ]]\n  [[ \"${lines[2]}\"  =~  [^-]-------------------------[^-]                       ]]\n  [[ \"${lines[3]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}                        ]]\n  [[ \"${lines[4]}\"  =~  Branch:\\ .*master                                       ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                                  ]]\n  [[ \"${lines[6]}\"  =~  [^-]--------------[^-]                                  ]]\n  [[ \"${lines[7]}\"  =~  Removing\\ remote:\\ .*https://example.test/example.git   ]]\n  [[ \"${lines[8]}\"  =~  \\!.*\\ Unable\\ to\\ contact\\ remote\\.                     ]]\n  [[ \"${lines[9]}\"  =~  Remote\\ removed\\.                                       ]]\n  [[ \"${lines[10]}\" =~  [^-]---------------[^-]                                 ]]\n  [[ \"${lines[11]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)                        ]]\n\n  diff                  \\\n    <(\"${_NB}\" remote)  \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n}\n\n@test \"'remote set <url>' to same URL and branch as existing remote with unshared history updates remote and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    _setup_remote_repo\n\n    \"${_NB}\" git remote add origin \"${_GIT_REMOTE_URL}\"\n\n    run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"    -eq 0                                         ]]\n\n    [[ \"${lines[0]}\"  =~  Updating\\ remote\\ for:\\ .*home            ]]\n    [[ \"${lines[1]}\"  =~  From:\\ \\ \\ ${_GIT_REMOTE_URL}             ]]\n    [[ \"${lines[2]}\"  =~  [^-]-------------------------[^-]         ]]\n    [[ \"${lines[3]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}          ]]\n    [[ \"${lines[4]}\"  =~  Branch:\\ .*master                         ]]\n    [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                    ]]\n    [[ \"${lines[6]}\"  =~  [^-]--------------[^-]                    ]]\n    [[ \"${lines[7]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}   ]]\n    [[ \"${lines[8]}\"  =~  Remote\\ removed.                          ]]\n    [[ \"${lines[9]}\"  =~  [^-]---------------[^-]                   ]]\n    [[ \"${lines[10]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n\n    diff                  \\\n      <(\"${_NB}\" remote)  \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    declare _remote_hashes=()\n    _remote_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    \"${_NB}\" git log\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*Sample\\ Notebook     ]]\n  [[ \"${lines[1]}\"  =~  [^-]---------------------------------[^-]   ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}            ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                           ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[6]}\"  =~  \\\nRemote\\ branch\\ has\\ existing\\ history:\\ .*master                   ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Merge\\ and\\ sync\\ with\\ the\\ existing\\ remote\\ branch\\:\\ .*master  ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*\\[.*2.*\\].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.                ]]\n  [[ \"${lines[9]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n\n  declare _new_hashes=()\n  _new_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n  printf \"remote hashes:  %s\\\\n\" \"${_remote_hashes[@]}\"\n  printf \"new hashes:     %s\\\\n\" \"${_new_hashes[@]}\"\n  \"${_NB}\" git log\n\n  [[ \"${#_remote_hashes[@]}\"  -eq 2                                 ]]\n  [[ \"${#_new_hashes[@]}\"     -eq 3                                 ]]\n\n  [[ \"${_remote_hashes[0]}\"   ==  \"${_new_hashes[1]}\"               ]]\n  [[ \"${_remote_hashes[1]}\"   ==  \"${_new_hashes[2]}\"               ]]\n}\n\n@test \"'remote set <url>' to same URL and branch as existing remote with shared history updates remote and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    _setup_remote_repo\n\n    \"${_NB}\" git remote add origin \"${_GIT_REMOTE_URL}\"\n\n    run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ \"${status}\"    -eq 0                                         ]]\n\n    [[ \"${lines[0]}\"  =~  Updating\\ remote\\ for:\\ .*home            ]]\n    [[ \"${lines[1]}\"  =~  From:\\ \\ \\ ${_GIT_REMOTE_URL}             ]]\n    [[ \"${lines[2]}\"  =~  [^-]-------------------------[^-]         ]]\n    [[ \"${lines[3]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}          ]]\n    [[ \"${lines[4]}\"  =~  Branch:\\ .*master                         ]]\n    [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                    ]]\n    [[ \"${lines[6]}\"  =~  [^-]--------------[^-]                    ]]\n    [[ \"${lines[7]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}   ]]\n    [[ \"${lines[8]}\"  =~  Remote\\ removed.                          ]]\n    [[ \"${lines[9]}\"  =~  [^-]---------------[^-]                   ]]\n    [[ \"${lines[10]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n\n    diff                  \\\n      <(\"${_NB}\" remote)  \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n    declare _remote_hashes=()\n    _remote_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    \"${_NB}\" git log\n\n    \"${_NB}\" remote unset \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}n${_NEWLINE}\"\n\n    [[ \"$(\"${_NB}\" remote 2>&1)\"  =~  No\\ remote\\ configured.       ]]\n\n    \"${_NB}\" add \"Example File Two.md\" --content \"Example content two.\"\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*home                 ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------[^-]              ]]\n\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}            ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                           ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                      ]]\n  [[ \"${lines[5]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)            ]]\n\n  declare _new_hashes=()\n  _new_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n  printf \"remote hashes:  %s\\\\n\" \"${_remote_hashes[@]}\"\n  printf \"new hashes:     %s\\\\n\" \"${_new_hashes[@]}\"\n  \"${_NB}\" git log\n\n  [[ \"${#_remote_hashes[@]}\"  -eq 2                                 ]]\n  [[ \"${#_new_hashes[@]}\"     -eq 3                                 ]]\n\n  [[ \"${_remote_hashes[0]}\"   ==  \"${_new_hashes[1]}\"               ]]\n  [[ \"${_remote_hashes[1]}\"   ==  \"${_new_hashes[2]}\"               ]]\n}\n\n@test \"'remote set <url> <branch>' with no existing remote and no matching remote branch pushes branch as new orphan, sets remote, and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    [[ -f \"${NB_DIR}/home/Example File One.md\"                      ]]\n\n    _setup_remote_repo\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" \"example\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"remote:    '%s'\\\\n\" \"$(\"${_NB}\" remote)\"\n\n  [[ \"${status}\"    -eq 0                                               ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*home                     ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------[^-]                  ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}                ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*example                              ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                          ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                          ]]\n  [[ \"${lines[6]}\"  =~  Branch\\ not\\ present\\ on\\ remote:\\ .*example    ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*[.*1.*].*\\ Merge\\ and\\ sync\\ with\\ an\\ existing\\ remote\\ branch\\.     ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*[.*2.*].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.        ]]\n  [[ \"${lines[9]}\"  =~  [^-]------------------------------[^-]          ]]\n  [[ \"${lines[10]}\" =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\           ]]\n  [[ \"${lines[10]}\" =~  \\\nname,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\.            ]]\n  [[ \"${lines[11]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*example.*\\)               ]]\n\n  diff                                                                  \\\n    <(git -C \"${NB_DIR}/home\" branch --all)                             \\\n    <(printf \"* example\\\\n  remotes/origin/example\\\\n\")\n\n  run \"${_NB}\" git branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\" =~ \\*\\ example                                    ]]\n  [[    \"${lines[1]}\" =~ remotes/origin/example                         ]]\n  [[ !  \"${output}\"   =~ remotes/origin/master                          ]]\n\n  git clone --branch \"example\" \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ example                                   ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master      ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/example                        ]]\n  [[    \"${lines[3]}\"  =~ remotes/origin/master                         ]]\n\n  [[ -f \"${_TMP_DIR}/new-clone/Example File One.md\"                     ]]\n\n  diff                                                                  \\\n    <(\"${_NB}\" remote)                                                  \\\n    <(printf \"%s (example)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  \"${_NB}\" git fetch origin\n  \"${_NB}\" git push origin\n\n  declare _master_branch_hashes=()\n  _master_branch_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n  [[ \"${#_master_branch_hashes[@]}\"   == \"1\"                            ]]\n\n  declare _example_branch_hashes=()\n  _example_branch_hashes=($(\"${_NB}\" git rev-list origin/example))\n\n  [[ \"${#_example_branch_hashes[@]}\"  == \"2\"                            ]]\n\n  [[ \"${_master_branch_hashes[0]}\"    != \"${_example_branch_hashes[0]}\" ]]\n  [[ \"${_master_branch_hashes[0]}\"    != \"${_example_branch_hashes[1]}\" ]]\n}\n\n@test \"'remote set <url> <branch>' with no existing remote and no matching remote branch updates local branch, sets remote, and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    _setup_remote_repo\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" \"example\" <<< \"y${_NEWLINE}1${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*home                   ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------[^-]                ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}              ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*example                            ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                        ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                        ]]\n  [[ \"${lines[6]}\"  =~  Branch\\ not\\ present\\ on\\ remote:\\ .*example  ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*[.*1.*].*\\ Merge\\ and\\ sync\\ with\\ an\\ existing\\ remote\\ branch\\.   ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*[.*2.*].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.      ]]\n  [[ \"${lines[9]}\"  =~  [^-]------------------------------[^-]        ]]\n  [[ \"${lines[10]}\" =~  Remote\\ branches:                             ]]\n  [[ \"${lines[11]}\" =~  .*[.*1.*].*\\ master                           ]]\n\n  [[ \"${lines[12]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)              ]]\n\n  diff                  \\\n    <(\"${_NB}\" remote)  \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n}\n\n@test \"'remote set <url>' with no existing remote and no matching remote branch pushes branch as new orphan, sets remote, and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" git branch -m example\n\n    _setup_remote_repo\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*home                   ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------[^-]                ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}              ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*example                            ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                        ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                        ]]\n  [[ \"${lines[6]}\"  =~  Branch\\ not\\ present\\ on\\ remote:\\ .*example  ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*[.*1.*].*\\ Merge\\ and\\ sync\\ with\\ an\\ existing\\ remote\\ branch\\.   ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*[.*2.*].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.      ]]\n  [[ \"${lines[9]}\"  =~  [^-]------------------------------[^-]        ]]\n  [[ \"${lines[10]}\" =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\         ]]\n  [[ \"${lines[10]}\" =~  \\\nname,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\.          ]]\n  [[ \"${lines[11]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*example.*\\)             ]]\n\n  diff                  \\\n    <(\"${_NB}\" remote)  \\\n    <(printf \"%s (example)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  \"${_NB}\" git fetch origin\n  \"${_NB}\" git push origin\n\n  declare _master_branch_hashes=()\n  _master_branch_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n  [[ \"${#_master_branch_hashes[@]}\"   == \"1\"                            ]]\n\n  declare _example_branch_hashes=()\n  _example_branch_hashes=($(\"${_NB}\" git rev-list origin/example))\n\n  [[ \"${#_example_branch_hashes[@]}\"  == \"2\"                            ]]\n\n  [[ \"${_master_branch_hashes[0]}\"    != \"${_example_branch_hashes[0]}\" ]]\n  [[ \"${_master_branch_hashes[0]}\"    != \"${_example_branch_hashes[1]}\" ]]\n}\n\n@test \"'remote set <url>' with no existing remote and no matching remote branch updates local branch, sets remote, and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File One.md\" --content \"Example content one.\"\n\n    \"${_NB}\" git branch -m example\n\n    _setup_remote_repo\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote\n\n  [[ \"${status}\"    -eq 0                                             ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*home                   ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------[^-]                ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}              ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*example                            ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                        ]]\n  [[ \"${lines[5]}\"  =~  [^-]--------------[^-]                        ]]\n  [[ \"${lines[6]}\"  =~  Branch\\ not\\ present\\ on\\ remote:\\ .*example  ]]\n  [[ \"${lines[7]}\"  =~  \\\n.*[.*1.*].*\\ Merge\\ and\\ sync\\ with\\ an\\ existing\\ remote\\ branch\\.   ]]\n  [[ \"${lines[8]}\"  =~  \\\n.*[.*2.*].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.      ]]\n  [[ \"${lines[9]}\"  =~  [^-]------------------------------[^-]        ]]\n  [[ \"${lines[10]}\" =~  Remote\\ branches:                             ]]\n  [[ \"${lines[11]}\" =~  .*[.*1.*].*\\ master                           ]]\n  [[ \"${lines[12]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)              ]]\n\n  diff                  \\\n    <(\"${_NB}\" remote)  \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n}\n\n@test \"'remote set' with no URL exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" remote set\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1         ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\: ]]\n}\n"
  },
  {
    "path": "test/remote.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# remote remove and set #######################################################\n\n@test \"'remote remove' deletes remote branch and 'remote set' rebases onto initialized remote.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    diff                                      \\\n      <(\"${_NB}\" remote)                      \\\n      <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    diff                                      \\\n      <(git -C \"${NB_DIR}/home\" branch --all) \\\n      <(printf \"* master\\\\n  remotes/origin/master\\\\n\")\n\n    declare _before_hashes=()\n    _before_hashes=($(\"${_NB}\" git rev-list origin/master))\n\n    [[ \"${#_before_hashes[@]}\"  -eq 2                                 ]]\n\n    [[ \"$(\"${_NB}\" git log)\"    =~  \\[nb\\]\\ Add:\\ Example\\ File\\.md   ]]\n    [[ \"$(\"${_NB}\" git log)\"    =~  Initial\\ commit\\.                 ]]\n  }\n\n  run \"${_NB}\" remote remove <<< \"y${_NEWLINE}y${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote && return 1\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"$(\"${_NB}\" remote 2>&1)\" =~ No\\ remote\\ configured.             ]]\n\n  [[ \"${lines[0]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}       ]]\n  [[ \"${lines[1]}\"  =~  Remote\\ branch\\ reset:\\ .*master              ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ removed.                              ]]\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" branch --all)   \\\n    <(printf \"* master\\\\n\")\n\n  # resets remote\n\n  diff                                        \\\n    <(git -C \"${NB_DIR}/home\" ls-remote       \\\n        --heads \"${_GIT_REMOTE_URL}\"          \\\n        | sed \"s/.*\\///g\" || :)               \\\n    <(printf \"master\\\\n\")\n\n  git clone \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone\"\n\n  run git -C \"${_TMP_DIR}/new-clone\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                  ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master    ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/master                       ]]\n\n  declare _after_hashes=()\n  _after_hashes=($(git -C \"${_TMP_DIR}/new-clone\" rev-list origin/master))\n\n  printf \"_after_hashes: %s\\\\n\" \"${_after_hashes[@]}\"\n\n  [[ \"${#_after_hashes[@]}\" -eq 1                                     ]]\n\n  _contains \"${_after_hashes[0]}\" \"${_before_hashes[@]}\" || true\n\n  [[ \"${_after_hashes[0]}\"  != \"${_before_hashes[0]}\"                 ]]\n  [[ \"${_after_hashes[0]}\"  != \"${_before_hashes[1]}\"                 ]]\n\n  git -C \"${_TMP_DIR}/new-clone\" log\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone\" log)\"  =~  \\[nb\\]\\ Initialize  ]]\n\n  {\n    sleep 1\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    declare _new_before_hashes=()\n    _new_before_hashes=($(\"${_NB}\" git rev-list master))\n\n    printf \"_new_before_hashes: %s\\\\n\" \"${_new_before_hashes[@]}\"\n\n    [[ \"${#_new_before_hashes[@]}\"  -eq 2                                 ]]\n\n    [[ \"$(\"${_NB}\" git log)\"        =~  \\[nb\\]\\ Add:\\ Sample\\ File\\.md    ]]\n    [[ \"$(\"${_NB}\" git log)\"        =~  Initialize                        ]]\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" remote\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*Sample\\ Notebook           ]]\n  [[ \"${lines[1]}\"  =~  [^-]---------------------------------[^-]         ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}                  ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                                 ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[5]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)                  ]]\n\n  diff                  \\\n    <(\"${_NB}\" remote)  \\\n    <(printf \"%s (master)\\\\n\" \"${_GIT_REMOTE_URL:-}\")\n\n  git clone  \"${_GIT_REMOTE_URL}\" \"${_TMP_DIR}/new-clone-2\"\n\n  run git -C \"${_TMP_DIR}/new-clone-2\" branch --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${lines[0]}\"  =~ \\*\\ master                                  ]]\n  [[    \"${lines[1]}\"  =~ remotes/origin/HEAD\\ \\-\\>\\ origin/master    ]]\n  [[    \"${lines[2]}\"  =~ remotes/origin/master                       ]]\n\n  [[ -f \"${_TMP_DIR}/new-clone-2/Sample File.md\" ]]\n\n  declare _new_after_hashes=()\n  _new_after_hashes=($(git -C \"${_TMP_DIR}/new-clone-2\" rev-list origin/master))\n\n  printf \"_new_after_hashes: %s\\\\n\" \"${_new_after_hashes[@]}\"\n\n  git -C \"${_TMP_DIR}/new-clone-2\" log\n\n  [[ \"${#_new_after_hashes[@]}\" -eq 2                                   ]]\n\n  _contains \"${_new_after_hashes[0]}\" \"${_new_before_hashes[@]}\" || true\n\n  [[ \"${_new_after_hashes[1]}\"  == \"${_after_hashes[0]}\"                ]]\n  [[ \"${_new_after_hashes[0]}\"  != \"${_new_before_hashes[1]}\"           ]]\n  [[ \"${_new_after_hashes[0]}\"  != \"${_new_before_hashes[0]}\"           ]]\n\n  [[ \"$(git -C \"${_TMP_DIR}/new-clone-2\" log)\"  =~  \\[nb\\]\\ Initialize  ]]\n}\n\n# remote branches #############################################################\n\n@test \"'remote branches' with no existing remote prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" remote branches\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n\n  [[ \"${status}\"    -eq 1                       ]]\n  [[ \"${#lines[@]}\" -eq 1                       ]]\n\n  [[ \"${lines[0]}\"  =~  No\\ remote\\ configured. ]]\n}\n\n@test \"'remote branches <url>' with no existing remote prints remote branches with current branch highlighted.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n  }\n\n  run \"${_NB}\" remote branches \"${_GIT_REMOTE_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n\n  [[ \"${status}\"    -eq 0                       ]]\n  [[ \"${#lines[@]}\" -eq 1                       ]]\n\n  [[ \"${lines[0]}\"  =~  .*master.*              ]]\n}\n\n@test \"'remote branches' with existing remote as orphan prints branches with current branch highlighted.\" {\n  {\n    \"${_NB}\" init\n\n    _setup_remote_repo\n\n    \"${_NB}\" git branch -m \"example-branch\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}2${_NEWLINE}\"\n\n    diff                                  \\\n      <(git -C \"${NB_DIR}/home\" ls-remote \\\n          --heads \"${_GIT_REMOTE_URL}\"    \\\n          | sed \"s/.*\\///g\" || :)         \\\n      <(printf \"example-branch\\\\nmaster\\\\n\")\n  }\n\n  run \"${_NB}\" remote branches\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n\n  [[ \"${status}\"    -eq 0                       ]]\n  [[ \"${#lines[@]}\" -eq 2                       ]]\n\n  [[ \"${lines[0]}\"  =~  .*example-branch.*      ]]\n  [[ \"${lines[1]}\"  ==  \"master\"                ]]\n}\n# remote ######################################################################\n\n@test \"'remote' with no arguments and no remote prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" remote\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                       ]]\n  [[ \"${lines[0]}\"  =~  No\\ remote\\ configured  ]]\n}\n\n@test \"'remote --url' with existing remote prints url.\" {\n  {\n    \"${_NB}\" init\n\n    cd \"${NB_DIR}/home\" &&\n      git remote add origin \"${_GIT_REMOTE_URL}\"\n  }\n\n  run \"${_NB}\" remote --url\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                     ]]\n  [[ \"${lines[0]}\"  ==  \"${_GIT_REMOTE_URL}\"  ]]\n}\n\n@test \"'remote' with no arguments and existing remote prints url and branch.\" {\n  {\n    \"${_NB}\" init\n\n    cd \"${NB_DIR}/home\" &&\n      git remote add origin \"${_GIT_REMOTE_URL}\"\n  }\n\n  run \"${_NB}\" remote\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${lines[0]}\"  ==  \"${_GIT_REMOTE_URL} (master)\" ]]\n}\n\n@test \"'remote' with no arguments does not trigger git commit.\" {\n  {\n    \"${_NB}\" init\n    cd \"${NB_DIR}/home\" &&\n      git remote add origin \"${_GIT_REMOTE_URL}\"\n\n    touch \"${NB_DIR}/home/example.md\"\n\n    [[ -f \"${NB_DIR}/home/example.md\"   ]]\n\n    \"${_NB}\" git dirty\n  }\n\n  run \"${_NB}\" remote\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n\n  [[ \"${lines[0]}\"  ==  \"${_GIT_REMOTE_URL} (master)\" ]]\n\n  [[ -f \"${NB_DIR}/home/example.md\"                   ]]\n\n  \"${_NB}\" git dirty\n\n  # does not create git commit\n\n  cd \"${NB_DIR}/home\" || return 1\n  if [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  then\n    sleep 1\n  fi\n\n  git log | grep -q -v '\\[nb\\] Commit'\n  git log | grep -q -v '\\[nb\\] Sync'\n}\n\n# help ########################################################################\n\n@test \"'help remote' exits with 0 and prints help information.\" {\n  run \"${_NB}\" help remote\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:       ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ remote  ]]\n}\n"
  },
  {
    "path": "test/run.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'run' exits with status 0 and prints output.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"one.md\" --title \"one\"\n    \"${_NB}\" add \"two.md\" --title \"two\"\n    \"${_NB}\" add \"three.md\" --title \"three\"\n\n    _files=\"$(ls \"${NB_DIR}/home/\")\"\n  }\n\n  run \"${_NB}\" run ls\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0           ]]\n  [[ \"${output}\"  ==  \"${_files}\" ]]\n}\n\n@test \"'run' with no command exits with status 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" run\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 1                   ]]\n  [[ \"${output}\"  =~  Command\\ required\\. ]]\n}\n\n@test \"'run' with non-existent command exits with status 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run -127 \"${_NB}\" run not-a-valid-command\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 127 ]]\n  [[ \"${output}\"  =~  Command\\ not\\ found:\\ .*not-a-valid-command ]] ||\n    [[ \"${output}\"  =~  bash:\\ line\\ 1:\\ not-a-valid-command:\\ command\\ not\\ found ]]\n}\n"
  },
  {
    "path": "test/scope.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_scope() {\n  \"${_NB}\" init\n  \"${_NB}\" notebooks add one\n  \"${_NB}\" use one\n  \"${_NB}\" add \"# first\"\n  \"${_NB}\" use home\n  \"${_NB}\" notebooks add two\n}\n\n# `nb <notebook>:--option` ####################################################\n\n@test \"'nb one:-<limit>' (no space) detects notebook and option.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" notebooks use \"Example Notebook\"\n\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n\n    \"${_NB}\" set footer 0\n\n    \"${_NB}\" notebooks use \"home\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:-7\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[  \"${status}\"     -eq 0                                             ]]\n  [[  \"${#lines[@]}\"  -eq 10                                            ]]\n  [[  \"${lines[0]}\"   =~  Example\\ Notebook.*home                       ]]\n  [[  \"${lines[1]}\"   =~  -------                                       ]]\n  [[  \"${lines[2]}\"   =~  .*[.*Example\\ Notebook:10.*].*\\ Title\\ Ten    ]]\n  [[  \"${lines[3]}\"   =~  .*[.*Example\\ Notebook:9.*].*\\ \\ Title\\ Nine  ]]\n  [[  \"${lines[4]}\"   =~  .*[.*Example\\ Notebook:8.*].*\\ \\ Title\\ Eight ]]\n  [[  \"${lines[5]}\"   =~  .*[.*Example\\ Notebook:7.*].*\\ \\ Title\\ Seven ]]\n  [[  \"${lines[6]}\"   =~  .*[.*Example\\ Notebook:6.*].*\\ \\ Title\\ Six   ]]\n  [[  \"${lines[7]}\"   =~  .*[.*Example\\ Notebook:5.*].*\\ \\ Title\\ Five  ]]\n  [[  \"${lines[8]}\"   =~  .*[.*Example\\ Notebook:4.*].*\\ \\ Title\\ Four  ]]\n  [[  \"${lines[9]}\"   =~  3\\ omitted\\.\\ 10\\ total\\.                     ]]\n\n  run \"${_NB}\" Example\\ Notebook:-3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[  \"${status}\"     -eq 0                                             ]]\n  [[  \"${#lines[@]}\"  -eq 6                                             ]]\n  [[  \"${lines[0]}\"   =~  Example\\ Notebook.*home                       ]]\n  [[  \"${lines[1]}\"   =~  -------                                       ]]\n  [[  \"${lines[2]}\"   =~  .*[.*Example\\ Notebook:10.*].*\\ Title\\ Ten    ]]\n  [[  \"${lines[3]}\"   =~  .*[.*Example\\ Notebook:9.*].*\\ \\ Title\\ Nine  ]]\n  [[  \"${lines[4]}\"   =~  .*[.*Example\\ Notebook:8.*].*\\ \\ Title\\ Eight ]]\n  [[  \"${lines[5]}\"   =~  7\\ omitted\\.\\ 10\\ total\\.                     ]]\n}\n\n# `nb <name>:notebook` ########################################################\n\n@test \"'nb one:notebook' exits with 0 and scoped 'notebook' output.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" one:notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0      ]]\n  [[ \"${output}\" =~ \"one\" ]]\n}\n\n@test \"'nb two:notebook' exits with 0 and scoped 'notebook' output.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" two:notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0      ]]\n  [[ \"${output}\" =~ \"two\" ]]\n}\n\n@test \"'nb one:invalid' exits with 0 and scoped 'ls' output.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" one:invalid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                                    ]]\n  [[ \"${lines[0]}\" =~ Not\\ found:\\ .*one:.*\\ .*invalid  ]]\n}\n\n@test \"'nb one:1' exits with 0 and scoped 'ls' output.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" one:1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0          ]]\n  [[ \"${lines[0]}\" =~ \"first\" ]]\n}\n\n# `nb <name>:` ################################################################\n# NOTE: Additional tests in ls.bats ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n@test \"'nb one:' exits with 0 and scoped 'ls' output.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" one:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0          ]]\n  [[ \"${lines[2]}\" =~ \"first\" ]]\n}\n\n@test \"'nb one: --no-id' exits with 0 and scoped 'ls' output.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" one: --no-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0          ]]\n  [[ \"${lines[0]}\" = \"first\"  ]]\n}\n\n@test \"'nb two:' exits with 0 and scoped 'ls' output.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" two:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${lines[2]}\" =~ 0\\ items\\.  ]]\n}\n\n@test \"'nb invalid:' exits with 1 and prints error.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" invalid:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                        ]]\n  [[ \"${lines[0]}\" =~ Notebook\\ not\\ found  ]]\n  [[ \"${lines[0]}\" =~ invalid               ]]\n}\n\n# `nb <url>` ##################################################################\n\n@test \"'nb <name>: <url>' creates bookmark.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" two: \"${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${NB_DIR}/two/\"\n\n  _files=($(ls \"${NB_DIR}/two/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0                            ]]\n\n  # Creates new note with bookmark filename\n  printf \"\\${_filename}: '%s'\\\\n\" \"${_filename}\"\n  [[ \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md ]]\n\n  # Creates new note file with content\n  [[ \"${#_files[@]}\" -eq 1                      ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/two/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/two/${_filename}\")\" == \"${_bookmark_content}\" ]]\n\n  grep -q '# Example Domain' \"${NB_DIR}/two\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/one\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/two/.index\"                                  ]]\n  [[ \"$(ls \"${NB_DIR}/two\")\" == \"$(cat \"${NB_DIR}/two/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n@test \"'nb <name>:<url>' (no space) creates bookmark.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" \"two:${_BOOKMARK_URL}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls \"${NB_DIR}/two/\"\n\n  _files=($(ls \"${NB_DIR}/two/\")) && _filename=\"${_files[0]}\"\n\n  # Returns status 0\n  [[ ${status} -eq 0                            ]]\n\n  # Creates new note with bookmark filename\n  printf \"\\${_filename}: '%s'\\\\n\" \"${_filename}\"\n  [[ \"${_filename}\" =~ [A-Za-z0-9]+.bookmark.md ]]\n\n  # Creates new note file with content\n  [[ \"${#_files[@]}\" -eq 1                      ]]\n\n  _bookmark_content=\"\\\n# Example Domain\n\n<file://${NB_TEST_BASE_PATH}/fixtures/example.com.html>\n\n## Description\n\nExample description.\n\n## Content\n\n$(cat \"${NB_TEST_BASE_PATH}/fixtures/example.com.md\")\"\n\n  printf \"cat file: '%s'\\\\n\" \"$(cat \"${NB_DIR}/two/${_filename}\")\"\n  printf \"\\${_bookmark_content}: '%s'\\\\n\" \"${_bookmark_content}\"\n\n  [[ \"$(cat \"${NB_DIR}/two/${_filename}\")\" == \"${_bookmark_content}\" ]]\n\n  grep -q '# Example Domain' \"${NB_DIR}/two\"/*\n\n  # Creates git commit\n  cd \"${NB_DIR}/one\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Add'\n\n  # Adds to index\n  [[ -e \"${NB_DIR}/two/.index\"                                  ]]\n  [[ \"$(ls \"${NB_DIR}/two\")\" == \"$(cat \"${NB_DIR}/two/.index\")\" ]]\n\n  # Prints output\n  [[ \"${output}\" =~ Added:                    ]]\n  [[ \"${output}\" =~ [0-9]+                    ]]\n  [[ \"${output}\" =~ [A-Za-z0-9]+.bookmark.md  ]]\n}\n\n# `nb show <notebook>:<identifier>` ########################################\n\n@test \"'nb show one:first --dump' exits with 0 and prints scoped file content.\" {\n  {\n    _setup_scope &>/dev/null\n  }\n\n  run \"${_NB}\" show one:first --dump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0        ]]\n  [[ \"${output}\" =~ \"first\" ]]\n}\n\n@test \"'nb show <current>:first --dump' exits with 0 and prints scoped file content.\" {\n  {\n    _setup_scope &>/dev/null\n    run \"${_NB}\" use one\n  }\n\n  run \"${_NB}\" show one:first --dump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0        ]]\n  [[ \"${output}\" =~ \"first\" ]]\n}\n"
  },
  {
    "path": "test/search-list-tags.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_tagged_items() {\n  \"${_NB}\" init\n\n  \"${_NB}\" add  \"File One.md\"                       \\\n    --title     \"Title One\"                         \\\n    --content   \"Sample Content One #tag1 Sample Phrase.\"\n\n  \"${_NB}\" add  \"File Two.bookmark.md\"              \\\n    --title     \"Title Two\"                         \\\n    --content   \"$(cat <<HEREDOC\nExample Title with #title-tag and #123 Hello\n\n## Comment\n\nExample Content Two #tag3 Example #tag1 Phrase.\n\nMore content.\n\n#lõw-tag\n\nEven more content with #parent-tag/child-tag/grandchild-tag in the middle.\n\n## Content\n\n#content-tag\nHEREDOC\n)\"\n\n  \"${_NB}\" add  \"File Three.bookmark.md\"            \\\n    --title     \"Title Three\"                       \\\n    --content   \"$(cat <<HEREDOC\nExample Content Three #out-of-bounds-tag Example Phrase.\n\n## Tags\n\n#tag2\n\n## Source\n\n#source-tag\nHEREDOC\n)\"\n\n  \"${_NB}\" add  \"Example Folder/Nested File One.md\" \\\n    --title     \"Title One\"                         \\\n    --content   \"Example Content One #nested-tag1 Example Phrase.\"\n\n  \"${_NB}\" add  \"Example Folder/Nested File Two.md\" \\\n    --title     \"Title Two\"                         \\\n    --content   \"#nested-tag2\"\n\n  \"${_NB}\" notebooks add \"Example Notebook\"\n\n  \"${_NB}\" add  \"Example Notebook:File One.md\"      \\\n    --title     \"Title One\"                         \\\n    --content   \"Sample Content One #other-tag1 Sample Phrase.\"\n}\n\n# filename handlng ############################################################\n\n@test \"'--tags' with uncommon filenames lists all unique, readable tags in current notebook.\" {\n  {\n    _setup_tagged_items\n\n    \"${_NB}\" rename \"File One.md\"           \"File [] One.md\"          --force\n    \"${_NB}\" rename \"File Two.bookmark.md\"  \"File ] Two.bookmark.md\"  --force\n  }\n\n  run \"${_NB}\" --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 7                                     ]]\n\n  [[ \"${output}\"    =~  \\#nested-tag1                         ]]\n  [[ \"${output}\"    =~  \\#nested-tag2                         ]]\n  [[ \"${output}\"    =~  \\#tag1                                ]]\n  [[ \"${output}\"    =~  \\#tag2                                ]]\n  [[ \"${output}\"    =~  \\#tag3                                ]]\n  [[ \"${output}\"    =~  \\#lõw-tag                             ]]\n  [[ \"${output}\"    =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n# _GIT_ENABLED=0 ##############################################################\n\n@test \"'--tags' with _GIT_ENABLED=0 lists all unique, readable tags in <item>.\" {\n  {\n    _setup_tagged_items\n  }\n\n  _GIT_ENABLED=0 run \"${_NB}\" --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 7                                     ]]\n\n  [[ \"${output}\"    =~  \\#nested-tag1                         ]]\n  [[ \"${output}\"    =~  \\#nested-tag2                         ]]\n  [[ \"${output}\"    =~  \\#tag1                                ]]\n  [[ \"${output}\"    =~  \\#tag2                                ]]\n  [[ \"${output}\"    =~  \\#tag3                                ]]\n  [[ \"${output}\"    =~  \\#lõw-tag                             ]]\n  [[ \"${output}\"    =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n# edge cases ##################################################################\n\n@test \"'--tags' skips URI fragments.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"$(\n        cat <<HEREDOC\n#tag1\n\nhttps://example.com/example#fragment\n\n#tag2 #tag3\nHEREDOC\n      )\"\n  }\n\n  run \"${_NB}\" --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 3             ]]\n\n  [[ \"${lines[0]}\"  =~  \\#tag1        ]]\n  [[ \"${lines[1]}\"  =~  \\#tag2        ]]\n  [[ \"${lines[2]}\"  =~  \\#tag3        ]]\n\n}\n\n# https://github.com/xwmx/nb/issues/154\n@test \"'<item> --tags' and '--tags' with note lists tags in <item>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add --tags foo,bar --title baz \"foo bar baz\" foo.md\n  }\n\n  run \"${_NB}\" --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/foo.md\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 2             ]]\n\n  [[ \"${lines[0]}\"  =~  \\#foo         ]]\n  [[ \"${lines[1]}\"  =~  \\#bar         ]]\n\n  run \"${_NB}\" ls --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/foo.md\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 2             ]]\n\n  [[ \"${lines[0]}\"  =~  \\#foo         ]]\n  [[ \"${lines[1]}\"  =~  \\#bar         ]]\n\n  run \"${_NB}\" list --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/foo.md\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 2             ]]\n\n  [[ \"${lines[0]}\"  =~  \\#foo         ]]\n  [[ \"${lines[1]}\"  =~  \\#bar         ]]\n\n  run \"${_NB}\" search --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/foo.md\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 2             ]]\n\n  [[ \"${lines[0]}\"  =~  \\#foo         ]]\n  [[ \"${lines[1]}\"  =~  \\#bar         ]]\n\n  run \"${_NB}\" 1 --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/foo.md\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 2             ]]\n\n  [[ \"${lines[0]}\"  =~  \\#foo         ]]\n  [[ \"${lines[1]}\"  =~  \\#bar         ]]\n}\n\n# `nb` (`ls`) #################################################################\n\n@test \"'<item> --tags' lists all unique, readable tags in <item>.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" 2 --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 4                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\#tag3                                ]]\n  [[ \"${lines[1]}\"  =~  \\#tag1                                ]]\n  [[ \"${lines[2]}\"  =~  \\#lõw-tag                             ]]\n  [[ \"${output}\"    =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n@test \"'<folder>/ --tags' lists all unique tags in <folder>.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" Example\\ Folder/ --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 2             ]]\n\n  [[ \"${lines[0]}\"  =~  \\#nested-tag1 ]]\n  [[ \"${lines[1]}\"  =~  \\#nested-tag2 ]]\n}\n\n@test \"'--tags' lists all unique tags in the current notebook.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 7                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\#nested-tag1                         ]]\n  [[ \"${lines[1]}\"  =~  \\#nested-tag2                         ]]\n  [[ \"${lines[2]}\"  =~  \\#tag1                                ]]\n  [[ \"${lines[3]}\"  =~  \\#tag2                                ]]\n  [[ \"${lines[4]}\"  =~  \\#tag3                                ]]\n  [[ \"${lines[5]}\"  =~  \\#lõw-tag                             ]]\n  [[ \"${lines[6]}\"  =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n@test \"'--tags --all' lists all unique tags in all notebooks.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" --tags --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 8                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\#other-tag1                          ]]\n  [[ \"${lines[1]}\"  =~  \\#nested-tag1                         ]]\n  [[ \"${lines[2]}\"  =~  \\#nested-tag2                         ]]\n  [[ \"${lines[3]}\"  =~  \\#tag1                                ]]\n  [[ \"${lines[4]}\"  =~  \\#tag2                                ]]\n  [[ \"${lines[5]}\"  =~  \\#tag3                                ]]\n  [[ \"${lines[6]}\"  =~  \\#lõw-tag                             ]]\n  [[ \"${lines[7]}\"  =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n# `list` ######################################################################\n\n@test \"'list <item> --tags' lists all unique, readable tags in <item>.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" list 2 --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 4                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\#tag3                                ]]\n  [[ \"${lines[1]}\"  =~  \\#tag1                                ]]\n  [[ \"${lines[2]}\"  =~  \\#lõw-tag                             ]]\n  [[ \"${lines[3]}\"  =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n@test \"'list <folder>/ --tags' lists all unique tags in <folder>.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" list Example\\ Folder/ --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 2             ]]\n\n  [[ \"${lines[0]}\"  =~  \\#nested-tag1 ]]\n  [[ \"${lines[1]}\"  =~  \\#nested-tag2 ]]\n}\n\n@test \"'list --tags' lists all unique tags in the current notebook.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" list --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 7                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\#nested-tag1                         ]]\n  [[ \"${lines[1]}\"  =~  \\#nested-tag2                         ]]\n  [[ \"${lines[2]}\"  =~  \\#tag1                                ]]\n  [[ \"${lines[3]}\"  =~  \\#tag2                                ]]\n  [[ \"${lines[4]}\"  =~  \\#tag3                                ]]\n  [[ \"${lines[5]}\"  =~  \\#lõw-tag                             ]]\n  [[ \"${lines[6]}\"  =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n@test \"'list --tags --all' lists all unique tags in all notebooks.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" list --tags --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 8                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\#other-tag1                          ]]\n  [[ \"${lines[1]}\"  =~  \\#nested-tag1                         ]]\n  [[ \"${lines[2]}\"  =~  \\#nested-tag2                         ]]\n  [[ \"${lines[3]}\"  =~  \\#tag1                                ]]\n  [[ \"${lines[4]}\"  =~  \\#tag2                                ]]\n  [[ \"${lines[5]}\"  =~  \\#tag3                                ]]\n  [[ \"${lines[6]}\"  =~  \\#lõw-tag                             ]]\n  [[ \"${lines[7]}\"  =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n# `search` ####################################################################\n\n@test \"'search <item> --tags' lists all unique, readable tags in <item>.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" search 2 --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 4                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\#tag3                                ]]\n  [[ \"${lines[1]}\"  =~  \\#tag1                                ]]\n  [[ \"${lines[2]}\"  =~  \\#lõw-tag                             ]]\n  [[ \"${lines[3]}\"  =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n@test \"'search <folder>/ --tags' lists all unique tags in <folder>.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" search Example\\ Folder/ --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n  [[ \"${#lines[@]}\" -eq 2             ]]\n\n  [[ \"${lines[0]}\"  =~  \\#nested-tag1 ]]\n  [[ \"${lines[1]}\"  =~  \\#nested-tag2 ]]\n}\n\n@test \"'search --tags' lists all unique tags in the current notebook.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" search --tags\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 7                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\#nested-tag1                         ]]\n  [[ \"${lines[1]}\"  =~  \\#nested-tag2                         ]]\n  [[ \"${lines[2]}\"  =~  \\#tag1                                ]]\n  [[ \"${lines[3]}\"  =~  \\#tag2                                ]]\n  [[ \"${lines[4]}\"  =~  \\#tag3                                ]]\n  [[ \"${lines[5]}\"  =~  \\#lõw-tag                             ]]\n  [[ \"${lines[6]}\"  =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n\n@test \"'search --tags --all' lists all unique tags in all notebooks.\" {\n  {\n    _setup_tagged_items\n  }\n\n  run \"${_NB}\" search --tags --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                     ]]\n  [[ \"${#lines[@]}\" -eq 8                                     ]]\n\n  [[ \"${lines[0]}\"  =~  \\#other-tag1                          ]]\n  [[ \"${lines[1]}\"  =~  \\#nested-tag1                         ]]\n  [[ \"${lines[2]}\"  =~  \\#nested-tag2                         ]]\n  [[ \"${lines[3]}\"  =~  \\#tag1                                ]]\n  [[ \"${lines[4]}\"  =~  \\#tag2                                ]]\n  [[ \"${lines[5]}\"  =~  \\#tag3                                ]]\n  [[ \"${lines[6]}\"  =~  \\#lõw-tag                             ]]\n  [[ \"${lines[7]}\"  =~  \\#parent-tag/child-tag/grandchild-tag ]]\n}\n"
  },
  {
    "path": "test/search-logic.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_search() {\n  \"${_NB}\" init\n\n  \"${_NB}\" add  \"File One.md\"   \\\n    --title     \"Title One\"     \\\n    --content   \"Sample Content One Sample Phrase.\"\n\n  \"${_NB}\" add  \"File Two.md\"   \\\n    --title     \"Title Two\"     \\\n    --content   \"Example Content Two Example Phrase.\"\n\n  \"${_NB}\" add  \"File Three.md\" \\\n    --title     \"Title Three\"   \\\n    --content   \"Example Content Three Example Phrase.\"\n}\n\n# -e flag #####################################################################\n\n@test \"'search <query1> --and -e <query2> --or -e <query3>' ignores -e flag.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"one\" --and -e \"two\" --or -e \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                                       ]]\n\n  [[    \"${#lines[@]}\"  -eq 7                                                       ]]\n\n  [[    \"${lines[0]}\"   =~  [.*3.*].*\\ .*Title\\ Three                               ]]\n  [[    \"${lines[1]}\"   =~  -*-                                                     ]]\n  [[    \"${lines[2]}\"   =~  3.*:.*Example.*\\ Content\\ Three\\ .*Example.*\\ Phrase.   ]]\n\n  [[    \"${lines[3]}\"   =~  [.*2.*].*\\ .*Title\\ Two                                 ]]\n  [[    \"${lines[4]}\"   =~  -*-                                                     ]]\n  [[    \"${lines[5]}\"   =~  1.*:.*#\\ Title\\ .*Two                                   ]]\n  [[    \"${lines[6]}\"   =~  3.*:.*Example.*\\ Content\\ .*Two.*\\ .*Example.*\\ Phrase. ]]\n}\n\n# --not option ################################################################\n\n@test \"'search --not <query>' lists items NOT matching query, omitting content.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"   \\\n      --title     \"Title One\"     \\\n      --content   \"Sample Content One Sample Phrase Alpha.\"\n\n    \"${_NB}\" add  \"File Two.md\"   \\\n      --title     \"Title Two\"     \\\n      --content   \"Example Content Two Example Phrase Beta.\"\n\n    \"${_NB}\" add  \"File Three.md\" \\\n      --title     \"Title Three\"   \\\n      --content   \"Example Content Three Example Phrase Alpha.\"\n\n    \"${_NB}\" add  \"File Four.md\"  \\\n      --title     \"Title Four\"    \\\n      --content   \"Example Content Four Example Phrase Beta.\"\n  }\n\n  run \"${_NB}\" search --not \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                                 ]]\n\n  [[    \"${#lines[@]}\"  -eq 1                                                 ]]\n\n  [[    \"${lines[0]}\"   =~ [.*1.*].*\\ Title\\ One                              ]]\n  [[ -z \"${lines[1]}\"                                                         ]]\n}\n\n@test \"'search --and <query1> --and <query2> --not <query3>' lists items matching query1 AND query2 and NOT query3.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"   \\\n      --title     \"Title One\"     \\\n      --content   \"Sample Content One Sample Phrase Alpha.\"\n\n    \"${_NB}\" add  \"File Two.md\"   \\\n      --title     \"Title Two\"     \\\n      --content   \"Example Content Two Example Phrase Beta.\"\n\n    \"${_NB}\" add  \"File Three.md\" \\\n      --title     \"Title Three\"   \\\n      --content   \"Example Content Three Example Phrase Alpha.\"\n\n    \"${_NB}\" add  \"File Four.md\"  \\\n      --title     \"Title Four\"    \\\n      --content   \"Example Content Four Example Phrase Beta.\"\n  }\n\n  run \"${_NB}\" search --and \"example\" --and \"beta\" --not \"four\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                                 ]]\n\n  [[    \"${#lines[@]}\"  -eq 3                                                 ]]\n\n  [[    \"${lines[0]}\"   =~ [.*2.*].*\\ Title\\ Two                              ]]\n  [[    \"${lines[1]}\"   =~  -*-                                               ]]\n  [[    \"${lines[2]}\"   =~  Example.*\\ Content\\ .*Two.*\\ .*Example.*\\ Phrase  ]]\n}\n\n# AND / OR query options ######################################################\n\n@test \"'search <query1> --and <query2> --or <query3>' lists items matching (query1 OR query3) AND (query2 OR query3).\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"one\" --and \"two\" --or \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                                       ]]\n\n  [[    \"${#lines[@]}\"  -eq 7                                                       ]]\n\n  [[    \"${lines[0]}\"   =~  [.*3.*].*\\ .*Title\\ Three                               ]]\n  [[    \"${lines[1]}\"   =~  -*-                                                     ]]\n  [[    \"${lines[2]}\"   =~  3.*:.*Example.*\\ Content\\ Three\\ .*Example.*\\ Phrase.   ]]\n\n  [[    \"${lines[3]}\"   =~  [.*2.*].*\\ .*Title\\ Two                                 ]]\n  [[    \"${lines[4]}\"   =~  -*-                                                     ]]\n  [[    \"${lines[5]}\"   =~  1.*:.*#\\ Title\\ .*Two                                   ]]\n  [[    \"${lines[6]}\"   =~  3.*:.*Example.*\\ Content\\ .*Two.*\\ .*Example.*\\ Phrase. ]]\n}\n\n@test \"'search --and <query1> --and <query2> --and <query3>' with no matches prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File Example One.md\"   \\\n      --title     \"Title One\"             \\\n      --content   \"Sample Content One Sample Phrase.\"\n\n    \"${_NB}\" add  \"File Example Two.md\"   \\\n      --title     \"Title Two\"             \\\n      --content   \"Example Content Two Example Phrase.\"\n\n    \"${_NB}\" add  \"File Example Three.md\" \\\n      --title     \"Title Three\"           \\\n      --content   \"Example Content Three Example Phrase.\"\n  }\n\n  run \"${_NB}\" search --add \"no match\" --add \"unmatching\" --add \"unmatchable\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 1                                                     ]]\n\n  [[    \"${#lines[@]}\"  -eq 1                                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          Not\\ found\\ in\\ .*home.*:\\ .*no\\ match\\ \\+\\ unmatching\\ \\+\\ unmatchable ]]\n\n}\n\n@test \"'search --and <query1> --and <query2>' lists items matching query1 AND query2 with matching filename.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File Example One.md\"   \\\n      --title     \"Title One\"             \\\n      --content   \"Sample Content One Sample Phrase.\"\n\n    \"${_NB}\" add  \"File Example Two.md\"   \\\n      --title     \"Title Two\"             \\\n      --content   \"Example Content Two Example Phrase.\"\n\n    \"${_NB}\" add  \"File Example Three.md\" \\\n      --title     \"Title Three\"           \\\n      --content   \"Example Content Three Example Phrase.\"\n  }\n\n  run \"${_NB}\" search --and \"one\" --and \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                       ]]\n\n  [[    \"${#lines[@]}\"  -eq 3                                       ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*1.*].*\\ .*File\\ .*Example.*\\ .*One.*.md\\ ·\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  -*-                                     ]]\n  [[    \"${lines[2]}\"   =~  \\\n          Filename\\ Match:.*\\ .*File\\ .*Example.*\\ .*One.*.md       ]]\n}\n\n@test \"'search --and <query1> --and <query2>' lists items matching query1 AND query2.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search --and \"example\" --and \"two\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                                 ]]\n\n  [[    \"${#lines[@]}\"  -eq 4                                                 ]]\n\n  [[    \"${lines[0]}\"   =~ [.*2.*].*\\ Title\\ Two                              ]]\n  [[    \"${lines[1]}\"   =~  -*-                                               ]]\n  [[    \"${lines[2]}\"   =~  \\#\\ Title\\ .*Two                                  ]]\n  [[    \"${lines[3]}\"   =~  Example.*\\ Content\\ .*Two.*\\ .*Example.*\\ Phrase  ]]\n}\n\n@test \"'search <query1> --or <query2>' lists items matching query1 OR query2.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"one\" --or \"two\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                             ]]\n\n  [[    \"${#lines[@]}\"  -eq 14                                            ]]\n\n  [[    \"${lines[0]}\"   =~  [.*1.*].*\\ .*File\\ .*One.*.md\\ ·\\ Title\\ One  ]]\n  [[    \"${lines[1]}\"   =~  -*-                                           ]]\n  [[    \"${lines[2]}\"   =~  Filename\\ Match:.*\\ .*File\\ .*One.*.md        ]]\n\n  [[    \"${lines[3]}\"   =~  [.*2.*].*\\ .*File\\ .*Two.*.md\\ ·\\ Title\\ Two  ]]\n  [[    \"${lines[4]}\"   =~  -*-                                           ]]\n  [[    \"${lines[5]}\"   =~  Filename\\ Match:.*\\ .*File\\ .*Two.*.md        ]]\n\n  [[    \"${lines[6]}\"   =~  Title\\ One                                    ]]\n  [[    \"${lines[7]}\"   =~  -*-                                           ]]\n  [[    \"${lines[8]}\"   =~  \\#\\ Title\\ .*One                              ]]\n  [[    \"${lines[9]}\"   =~  Sample\\ Content\\ .*One.*\\ Sample\\ Phrase      ]]\n\n  [[    \"${lines[10]}\"   =~  Title\\ Two                                   ]]\n  [[    \"${lines[11]}\"  =~  -*-                                           ]]\n  [[    \"${lines[12]}\"   =~  \\#\\ Title\\ .*Two                             ]]\n  [[    \"${lines[13]}\"  =~  Example\\ Content\\ .*Two.*\\ Example\\ Phrase    ]]\n}\n\n# AND / OR query arguments ####################################################\n\n@test \"'search <query1> <query2> <query3>' with no matches prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File Example One.md\"   \\\n      --title     \"Title One\"             \\\n      --content   \"Sample Content One Sample Phrase.\"\n\n    \"${_NB}\" add  \"File Example Two.md\"   \\\n      --title     \"Title Two\"             \\\n      --content   \"Example Content Two Example Phrase.\"\n\n    \"${_NB}\" add  \"File Example Three.md\" \\\n      --title     \"Title Three\"           \\\n      --content   \"Example Content Three Example Phrase.\"\n  }\n\n  run \"${_NB}\" search \"no match\" \"unmatching\" \"unmatchable\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 1                                                     ]]\n\n  [[    \"${#lines[@]}\"  -eq 1                                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          Not\\ found\\ in\\ .*home.*:\\ .*no\\ match\\ \\+\\ unmatching\\ \\+\\ unmatchable ]]\n\n}\n\n@test \"'search <query1> <query2>' lists items matching query1 AND query2 with matching filename.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File Example One.md\"   \\\n      --title     \"Title One\"             \\\n      --content   \"Sample Content One Sample Phrase.\"\n\n    \"${_NB}\" add  \"File Example Two.md\"   \\\n      --title     \"Title Two\"             \\\n      --content   \"Example Content Two Example Phrase.\"\n\n    \"${_NB}\" add  \"File Example Three.md\" \\\n      --title     \"Title Three\"           \\\n      --content   \"Example Content Three Example Phrase.\"\n  }\n\n  run \"${_NB}\" search \"one\" \"example\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                       ]]\n\n  [[    \"${#lines[@]}\"  -eq 3                                       ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n          [.*1.*].*\\ .*File\\ .*Example.*\\ .*One.*.md\\ ·\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  -*-                                     ]]\n  [[    \"${lines[2]}\"   =~  \\\n          Filename\\ Match:.*\\ .*File\\ .*Example.*\\ .*One.*.md       ]]\n}\n\n@test \"'search <query1> <query2>' lists items matching query1 AND query2.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"example\" \"two\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                                 ]]\n\n  [[    \"${#lines[@]}\"  -eq 4                                                 ]]\n\n  [[    \"${lines[0]}\"   =~ [.*2.*].*\\ Title\\ Two                              ]]\n  [[    \"${lines[1]}\"   =~  -*-                                               ]]\n  [[    \"${lines[2]}\"   =~  \\#\\ Title\\ .*Two                                  ]]\n  [[    \"${lines[3]}\"   =~  Example.*\\ Content\\ .*Two.*\\ .*Example.*\\ Phrase  ]]\n}\n\n@test \"'search <query1|query2>' lists items matching query1 OR query2.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"one|two\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                                             ]]\n\n  [[    \"${#lines[@]}\"  -eq 14                                            ]]\n\n  [[    \"${lines[0]}\"   =~  [.*1.*].*\\ .*File\\ .*One.*.md\\ ·\\ Title\\ One  ]]\n  [[    \"${lines[1]}\"   =~  -*-                                           ]]\n  [[    \"${lines[2]}\"   =~  Filename\\ Match:.*\\ .*File\\ .*One.*.md        ]]\n\n  [[    \"${lines[3]}\"   =~  [.*2.*].*\\ .*File\\ .*Two.*.md\\ ·\\ Title\\ Two  ]]\n  [[    \"${lines[4]}\"   =~  -*-                                           ]]\n  [[    \"${lines[5]}\"   =~  Filename\\ Match:.*\\ .*File\\ .*Two.*.md        ]]\n\n  [[    \"${lines[6]}\"   =~  Title\\ One                                    ]]\n  [[    \"${lines[7]}\"   =~  -*-                                           ]]\n  [[    \"${lines[8]}\"   =~  \\#\\ Title\\ .*One                              ]]\n  [[    \"${lines[9]}\"   =~  Sample\\ Content\\ .*One.*\\ Sample\\ Phrase      ]]\n\n  [[    \"${lines[10]}\"   =~  Title\\ Two                                   ]]\n  [[    \"${lines[11]}\"  =~  -*-                                           ]]\n  [[    \"${lines[12]}\"   =~  \\#\\ Title\\ .*Two                             ]]\n  [[    \"${lines[13]}\"  =~  Example\\ Content\\ .*Two.*\\ Example\\ Phrase    ]]\n}\n"
  },
  {
    "path": "test/search-pagination.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'list --limit <limit> [--page <number>]' paginates list.\" {\n  {\n    \"${_NB}\" init\n\n    local __number=\n    for   __number in One Two Three Four Five Six Seven Eight Nine Ten\n    do\n      \"${_NB}\" add \"File ${__number}.md\" --title \"Title ${__number}\"\n    done\n  }\n\n  # --limit 3, first page\n\n  run \"${_NB}\" search \"title\" --list --limit 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[1]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n\n  run \"${_NB}\" search \"title\" --list --limit 3 --page 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[1]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n\n  run \"${_NB}\" search \"title\" --list --limit 3 --page 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[1]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n\n  # --limit 3 --page 2+\n\n  run \"${_NB}\" search \"title\" --list --limit 3 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n  [[ \"${#lines[@]}\" -eq 3                           ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*9.*].*\\ Title\\ Nine    ]]\n  [[ \"${lines[1]}\"  =~  .*[.*1.*].*\\ Title\\ One     ]]\n  [[ \"${lines[2]}\"  =~  .*[.*7.*].*\\ Title\\ Seven   ]]\n\n  run \"${_NB}\" search \"title\" --list --limit 3 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 3                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[1]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n\n  run \"${_NB}\" search \"title\" --list --limit 3 --page 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 1                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  # --limit 5\n\n  run \"${_NB}\" search \"title\" --list --limit 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*8.*].*\\ Title\\ Eight ]]\n  [[ \"${lines[1]}\"  =~  .*[.*5.*].*\\ Title\\ Five  ]]\n  [[ \"${lines[2]}\"  =~  .*[.*4.*].*\\ Title\\ Four  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*9.*].*\\ Title\\ Nine  ]]\n  [[ \"${lines[4]}\"  =~  .*[.*1.*].*\\ Title\\ One   ]]\n\n  run \"${_NB}\" search \"title\" --list --limit 5 --page 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 5                         ]]\n\n  [[ \"${lines[0]}\"  =~  .*[.*7.*].*\\ Title\\ Seven ]]\n  [[ \"${lines[1]}\"  =~  .*[.*6.*].*\\ Title\\ Six   ]]\n  [[ \"${lines[2]}\"  =~  .*[.*10.*].*\\ Title\\ Ten  ]]\n  [[ \"${lines[3]}\"  =~  .*[.*3.*].*\\ Title\\ Three ]]\n  [[ \"${lines[4]}\"  =~  .*[.*2.*].*\\ Title\\ Two   ]]\n\n  run \"${_NB}\" search \"title\" --list --limit 5 --page 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                         ]]\n  [[ \"${#lines[@]}\" -eq 0                         ]]\n}\n"
  },
  {
    "path": "test/search-tags.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'search -t tag2/child-2/grandchild-2' and similar exits with status 0 and print matches.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2/child-2/grandchild-2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five. #tag3ButNotReally #tag4\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2/child-2/grandchild-2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2/child-2/grandchild-2 Seven. #tag3/child-3/grandchild-3 #tag1/child-1/grandchild-1\"\n    \"${_NB}\" add \"File Eight.md\"  --content \"Content eight. #tag2/grandchild-2/child-2\"\n    \"${_NB}\" add \"File Nine.md\"   --content \"Content nine. #tag2/grandchild-2\"\n    \"${_NB}\" add \"File Ten.md\"    --content \"Content ten. #tag2/child-2\"\n  }\n\n  run \"${_NB}\" search -t tag2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${lines[0]}:   '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 21  ]]\n\n[[    \"${lines[0]}\"   =~  \\\n.*\\[.*8.*\\].*File\\ Eight.md\\ ·\\ \\\"Content\\ eight.\\ #tag2/grandchild-2/child-2\\\" ]]\n[[    \"${lines[1]}\"   =~  ^.*\\-{63,}.*$                                         ]]\n[[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ eight.\\ .*#tag2.*/grandchild-2/child-2                           ]]\n\n[[    \"${lines[3]}\"   =~  \\\n.*\\[.*4.*\\].*File\\ Four.md\\ ·\\ \\\"Content\\ #tag1\\ four.\\ #tag2/child-2/grandchild-2\\\"  ]]\n[[    \"${lines[4]}\"   =~  ^.*\\-{67,}.*$                                               ]]\n[[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ #tag1\\ four.\\ .*#tag2.*/child-2/grandchild-2                           ]]\n\n[[    \"${lines[6]}\"   =~  \\\n.*\\[.*9.*\\].*File\\ Nine.md\\ ·\\ \\\"Content\\ nine.\\ #tag2/grandchild-2\\\" ]]\n[[    \"${lines[7]}\"   =~  ^.*\\-{53,}.*$                               ]]\n[[    \"${lines[8]}\"   =~  \\\n1.*:.*Content\\ nine.\\ .*#tag2.*/grandchild-2                          ]]\n\n[[    \"${lines[9]}\"   =~  \\\n.*\\[.*7.*\\].*File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2/child-2/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ #tag1/child-1/grandchild-1\\\" ]]\n[[    \"${lines[10]}\"  =~  ^.*\\-{117,}.*$                                                                                                ]]\n[[    \"${lines[11]}\"  =~  \\\n1.*:.*Content\\ .*#tag2.*/child-2/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ #tag1/child-1/grandchild-1                           ]]\n\n[[    \"${lines[12]}\"  =~  \\\n.*\\[.*6*\\].*File\\ Six.md\\ ·\\ \\\"Content\\ six.\\ #tag2/child-2/grandchild-2\\\"  ]]\n[[    \"${lines[13]}\"  =~  ^.*\\-{59,}.*$                                     ]]\n[[    \"${lines[14]}\"  =~  \\\n1.*:.*Content\\ six.\\ .*#tag2.*/child-2/grandchild-2                         ]]\n\n[[    \"${lines[15]}\"  =~  \\\n.*\\[.*6*\\].*File\\ Ten.md\\ ·\\ \\\"Content\\ ten.\\ #tag2/child-2\\\" ]]\n[[    \"${lines[16]}\"  =~  ^.*\\-{47,}.*$                       ]]\n[[    \"${lines[17]}\"  =~  \\\n1.*:.*Content\\ ten.\\ .*#tag2.*/child-2                        ]]\n\n[[    \"${lines[18]}\"  =~  \\\n.*\\[.*3*\\].*File\\ Three.md\\ ·\\ \\\"Content\\ three.\\ tag1\\ #tag2\\\" ]]\n[[    \"${lines[19]}\"  =~  ^.*\\-{47,}.*$                         ]]\n[[    \"${lines[20]}\"  =~  \\\n1.*:.*Content\\ three.\\ tag1\\ .*#tag2.*                          ]]\n\n\n  run \"${_NB}\" search -t tag2/child-2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${lines[0]}:   '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 12  ]]\n\n[[    \"${lines[0]}\"   =~  \\\n.*\\[.*4.*\\].*File\\ Four.md\\ ·\\ \\\"Content\\ #tag1\\ four.\\ #tag2/child-2/grandchild-2\\\"  ]]\n[[    \"${lines[1]}\"   =~  ^.*\\-{67,}.*$                                               ]]\n[[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ #tag1\\ four.\\ .*#tag2/child-2.*/grandchild-2                           ]]\n\n[[    \"${lines[3]}\"   =~  \\\n.*\\[.*7.*\\].*File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2/child-2/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ #tag1/child-1/grandchild-1\\\" ]]\n[[    \"${lines[4]}\"  =~  ^.*\\-{117,}.*$                                                                                                 ]]\n[[    \"${lines[5]}\"  =~  \\\n1.*:.*Content\\ .*#tag2/child-2.*/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ #tag1/child-1/grandchild-1                           ]]\n\n[[    \"${lines[6]}\"  =~  \\\n.*\\[.*6*\\].*File\\ Six.md\\ ·\\ \\\"Content\\ six.\\ #tag2/child-2/grandchild-2\\\"  ]]\n[[    \"${lines[7]}\"  =~  ^.*\\-{59,}.*$                                      ]]\n[[    \"${lines[8]}\"  =~  \\\n1.*:.*Content\\ six.\\ .*#tag2/child-2.*/grandchild-2                         ]]\n\n[[    \"${lines[9]}\"  =~  \\\n.*\\[.*6*\\].*File\\ Ten.md\\ ·\\ \\\"Content\\ ten.\\ #tag2/child-2\\\" ]]\n[[    \"${lines[10]}\"  =~  ^.*\\-{47,}.*$                       ]]\n[[    \"${lines[11]}\"  =~  \\\n1.*:.*Content\\ ten.\\ .*#tag2/child-2.*                        ]]\n\n}\n\n@test \"'search -t tag1/child-1/grandchild-1' exits with status 0 and prints matches.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2/child-2/grandchild-2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five. #tag3ButNotReally #tag4\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2/child-2/grandchild-2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2/child-2/grandchild-2 Seven. #tag3/child-3/grandchild-3 #tag1/child-1/grandchild-1\"\n    \"${_NB}\" add \"File Eight.md\"  --content \"Content eight. #tag2/grandchild-2/child-2\"\n    \"${_NB}\" add \"File Nine.md\"   --content \"Content nine. #tag2/grandchild-2\"\n    \"${_NB}\" add \"File Ten.md\"    --content \"Content ten. #tag2/child-2\"\n  }\n\n  run \"${_NB}\" search -t tag1\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 9 ]]\n\n[[    \"${lines[0]}\"   =~  \\\n.*\\[.*4.*\\].*File\\ Four.md\\ ·\\ \\\"Content\\ #tag1\\ four.\\ #tag2/child-2/grandchild-2\\\"  ]]\n[[    \"${lines[1]}\"   =~  ^.*\\-{67,}.*$                                               ]]\n[[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ .*#tag1.*\\ four.\\ #tag2/child-2/grandchild-2                           ]]\n\n[[    \"${lines[3]}\"   =~  \\\n.*\\[.*7.*\\].*File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2/child-2/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ #tag1/child-1/grandchild-1\\\" ]]\n[[    \"${lines[4]}\"   =~  ^.*\\-{99,}.*$                                                                                                 ]]\n[[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ #tag2/child-2/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ .*#tag1.*/child-1/grandchild-1                           ]]\n\n[[    \"${lines[6]}\"   =~  \\\n.*\\[.*2.*\\].*File\\ Two.md\\ ·\\ \\\"Content\\ two.\\ #tag1\\\"  ]]\n[[    \"${lines[7]}\"   =~  ^.*\\-{38,}.*$                 ]]\n[[    \"${lines[8]}\"   =~  \\\n1.*:.*Content\\ two.\\ .*#tag1.*                          ]]\n\n  run \"${_NB}\" search -t tag1/child-1\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 3 ]]\n\n[[    \"${lines[0]}\"   =~  \\\n.*\\[.*7.*\\].*File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2/child-2/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ #tag1/child-1/grandchild-1\\\" ]]\n[[    \"${lines[1]}\"   =~  ^.*\\-{99,}.*$                                                                                                 ]]\n[[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ #tag2/child-2/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ .*#tag1/child-1.*/grandchild-1                           ]]\n\n  run \"${_NB}\" search -t tag1/child-1/grandchild-1\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 3 ]]\n\n[[    \"${lines[0]}\"   =~  \\\n.*\\[.*7.*\\].*File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2/child-2/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ #tag1/child-1/grandchild-1\\\" ]]\n[[    \"${lines[1]}\"   =~  ^.*\\-{99,}.*$                                                                                                 ]]\n[[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ #tag2/child-2/grandchild-2\\ Seven.\\ #tag3/child-3/grandchild-3\\ .*#tag1/child-1/grandchild-1.*                           ]]\n}\n\n@test \"'search -t tag1 --and -t tag2,'#tag3' exits with status 0 and prints matches as an AND query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five. #tag3ButNotReally #tag4\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag3 #tag1\"\n  }\n\n  run \"${_NB}\" search -t tag1 --and -t tag2,'#tag3'\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                             ]]\n  [[    \"${#lines[@]}\"  -eq 3                                             ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*7.*].*\\ File\\ Seven.md\\ \\·\\ \\\"Content\\ #tag2\\ Seven.\\ #tag3\\ #tag1\\\" ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$                      ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ .*#tag2.*\\ Seven.\\ .*#tag3.*\\ .*#tag1                      ]]\n}\n\n@test \"'search -t tag1 --or -t tag2,'#tag3' exits with status 0 and prints matches as an OR query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five. #tag3ButNotReally #tag4\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag1\"\n  }\n\n  run \"${_NB}\" search -t tag1 --or -t tag2,'#tag3'\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 18                                    ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ #tag1\\ four.\\ #tag2\\\"  ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ .*#tag1.*\\ four.\\ .*#tag2                          ]]\n\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*1.*].*\\ File\\ One.md\\ ·\\ \\\"Content\\ one.\\ #tag3\\\"            ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ one.\\ .*#tag3                                      ]]\n\n  [[    \"${lines[6]}\"   =~  \\\n.*[.*7.*].*\\ File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2\\ Seven.\\ #tag1\\\" ]]\n  [[    \"${lines[7]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[8]}\"   =~  \\\n1.*:.*Content\\ .*#tag2.*\\ Seven.\\ .*#tag1                         ]]\n\n  [[    \"${lines[9]}\"   =~  \\\n.*[.*6.*].*\\ File\\ Six.md\\ ·\\ \\\"Content\\ six.\\ #tag2\\\"            ]]\n  [[    \"${lines[10]}\"  =~  ^.*------------------.*$              ]]\n  [[    \"${lines[11]}\"  =~  \\\n1.*:.*Content\\ six.\\ .*#tag2                                      ]]\n\n  [[    \"${lines[12]}\"  =~  \\\n.*[.*3.*].*\\ File\\ Three.md\\ ·\\ \\\"Content\\ three.\\ tag1\\ #tag2\\\"  ]]\n  [[    \"${lines[13]}\"  =~  ^.*------------------.*$              ]]\n  [[    \"${lines[14]}\"  =~  \\\n1.*:.*Content\\ three.\\ tag1\\ .*#tag2                              ]]\n\n  [[    \"${lines[15]}\"  =~  \\\n.*[.*2.*].*\\ File\\ Two.md\\ ·\\ \\\"Content\\ two.\\ #tag1\\\"            ]]\n  [[    \"${lines[16]}\"  =~  ^.*------------------.*$              ]]\n  [[    \"${lines[17]}\"  =~  \\\n1.*:.*Content\\ two.\\ .*#tag1                                      ]]\n}\n\n@test \"'search -t tag1 --or --tags tag2 exits with status 0 and prints matches as an OR query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one.   #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two.   #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content four.  #tag1\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five.  #tag3ButNotReally\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six.   #tag2\"\n  }\n\n  run \"${_NB}\" search -t tag1 --or --tags tag2\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                 ]]\n  [[    \"${#lines[@]}\"  -eq 9                                 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ four.\\ \\ #tag1\\\"   ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$          ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ four.\\ \\ .*#tag1                               ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*6.*].*\\ File\\ Six.md\\ ·\\ \\\"Content\\ six.\\ \\ \\ #tag2\\\"    ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$          ]]\n  [[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ six.\\ \\ .*#tag2                                ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*[.*2.*].*\\ File\\ Two.md\\ ·\\ \\\"Content\\ two.\\ \\ \\ #tag1\\\"    ]]\n  [[    \"${lines[7]}\"   =~  ^.*------------------.*$          ]]\n  [[    \"${lines[8]}\"   =~  \\\n1.*:.*Content\\ two.\\ \\ .*#tag1                                ]]\n}\n\n@test \"'search -t tag1 -t tag2 exits with status 0 and prints matches as an AND query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five. #tag3ButNotReally #tag4\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag1\"\n  }\n\n  run \"${_NB}\" search -t tag1 -t tag2\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 6                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ #tag1\\ four.\\ #tag2\\\"  ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ .*#tag1.*\\ four.\\ .*#tag2                          ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*7.*].*\\ File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2\\ Seven.\\ #tag1\\\" ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ .*#tag2.*\\ Seven.\\ .*#tag1                         ]]\n}\n\n@test \"'search --tags tag1,'#tag2' exits with status 0 and prints matches as an AND query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five. #tag3ButNotReally #tag4\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag1\"\n  }\n\n  run \"${_NB}\" search --tags tag1,'#tag2'\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 6                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ #tag1\\ four.\\ #tag2\\\"  ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ .*#tag1.*\\ four.\\ .*#tag2                          ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*7.*].*\\ File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2\\ Seven.\\ #tag1\\\" ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ .*#tag2.*\\ Seven.\\ .*#tag1                         ]]\n}\n\n@test \"'search --tag \\\"tag1\\\" --tag \\\"tag2\\\"' (no #) exits with status 0 and prints matches as an AND query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five. #tag3ButNotReally #tag4\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag1\"\n  }\n\n  run \"${_NB}\" search --tag \"tag1\" --tag \"tag2\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 6                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ #tag1\\ four.\\ #tag2\\\"  ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ .*#tag1.*\\ four.\\ .*#tag2                          ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*7.*].*\\ File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2\\ Seven.\\ #tag1\\\" ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ .*#tag2.*\\ Seven.\\ .*#tag1                         ]]\n}\n\n@test \"'search --tag \\\"#tag1\\\" --tag \\\"#tag2\\\"' (yes #) exits with status 0 and prints matches as an AND query.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five. #tag3ButNotReally #tag4\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n    \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag1\"\n  }\n\n  run \"${_NB}\" search --tag \"#tag1\" --tag \"#tag2\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 6                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ #tag1\\ four.\\ #tag2\\\"  ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ .*#tag1.*\\ four.\\ .*#tag2                          ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*7.*].*\\ File\\ Seven.md\\ ·\\ \\\"Content\\ #tag2\\ Seven.\\ #tag1\\\" ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$              ]]\n  [[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ .*#tag2.*\\ Seven.\\ .*#tag1                         ]]\n}\n\n@test \"'search --tag \\\"tag\\\"' (no #) exits with status 0 and prints matches.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one.   #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two.   #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content four.  #tag1\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five.  #tag2\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six.   #tag2\"\n  }\n\n  run \"${_NB}\" search --tag \"tag1\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 6                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ four.\\ \\ #tag1\\\" ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$        ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ four.\\ \\ .*#tag1                             ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*2.*].*\\ File\\ Two.md\\ ·\\ \\\"Content\\ two.\\ \\ \\ #tag1\\\"  ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$        ]]\n  [[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ two.\\ \\ .*#tag1                              ]]\n}\n\n@test \"'search --tag \\\"#tag\\\"' (yes #) exits with status 0 and prints matches.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one.   #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two.   #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content four.  #tag1\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five.  #tag2\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six.   #tag2\"\n  }\n\n  run \"${_NB}\" search --tag \"#tag1\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 6                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ four.\\ \\ #tag1\\\" ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$        ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ four.\\ \\ .*#tag1                             ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*2.*].*\\ File\\ Two.md\\ ·\\ \\\"Content\\ two.\\ \\ \\ #tag1\\\"  ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$        ]]\n  [[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ two.\\ \\ .*#tag1                              ]]\n}\n\n@test \"'search \\\"#tag\\\"' exits with status 0 and prints matches.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one.   #tag3\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two.   #tag1\"\n    \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1\"\n    \"${_NB}\" add \"File Four.md\"   --content \"Content four.  #tag1\"\n    \"${_NB}\" add \"File Five.md\"   --content \"Content five.  #tag2\"\n    \"${_NB}\" add \"File Six.md\"    --content \"Content six.   #tag2\"\n  }\n\n  run \"${_NB}\" search \"#tag1\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 6                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*4.*].*\\ File\\ Four.md\\ \\·\\ \\\"Content\\ four.\\ \\ #tag1\\\" ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$        ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ four.\\ \\ .*#tag1                             ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*2.*].*\\ File\\ Two.md\\ ·\\ \\\"Content\\ two.\\ \\ \\ #tag1\\\"  ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$        ]]\n  [[    \"${lines[5]}\"   =~  \\\n1.*:.*Content\\ two.\\ \\ .*#tag1                              ]]\n}\n"
  },
  {
    "path": "test/search.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_search() {\n  \"${_NB}\" init\n\n  \"${_NB}\" add  \"File One.md\"   \\\n    --title     \"Title One\"     \\\n    --content   \"Sample Content One Sample Phrase.\"\n\n  \"${_NB}\" add  \"File Two.md\"   \\\n    --title     \"Title Two\"     \\\n    --content   \"Example Content Two Example Phrase.\"\n\n  \"${_NB}\" add  \"File Three.md\" \\\n    --title     \"Title Three\"   \\\n    --content   \"Example Content Three Example Phrase.\"\n}\n\n_search_all_setup() {\n  _setup_search\n\n  \"${_NB}\" notebooks add one\n  \"${_NB}\" use one\n\n  \"${_NB}\" add  \"example.md\"    \\\n    --title     \"Example Title\" \\\n    --content   \"Example Phrase\"\n\n  \"${_NB}\" notebooks add two\n  \"${_NB}\" use two\n\n  \"${_NB}\" add  \"example.md\"    \\\n    --title     \"Example Title\" \\\n    --content   \"Example Phrase\"\n\n  \"${_NB}\" notebooks archive two\n\n  [[ -e \"${NB_DIR}/two/.archived\" ]]\n}\n\n# --replace ###################################################################\n\n# TODO\n# @test \"'search <pattern> --replace <replacement>' exits with status 0 and replaces <pattern> with <replacement>.\" {\n#   {\n#     \"${_NB}\" init\n\n#     \"${_NB}\" add \"File One.md\"    --content \"Content one. #tag3\"\n#     \"${_NB}\" add \"File Two.md\"    --content \"Content two. #tag1\"\n#     \"${_NB}\" add \"File Three.md\"  --content \"Content three. tag1 #tag2\"\n#     \"${_NB}\" add \"File Four.md\"   --content \"Content #tag1 four. #tag2\"\n#     \"${_NB}\" add \"File Five.md\"   --content \"Content tag2 five.\"\n#     \"${_NB}\" add \"File Six.md\"    --content \"Content six. #tag2\"\n#     \"${_NB}\" add \"File Seven.md\"  --content \"Content #tag2 Seven. #tag3 #tag1\"\n#   }\n\n#   run \"${_NB}\" search \\#tag2 --replace \\#example\n\n#   printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n#   printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n#   printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n#   [[    \"${status}\"     -eq 0             ]]\n\n#   # TODO\n\n\n#   # updates files\n\n#   diff                                    \\\n#     <(cat \"${NB_DIR}/home/File One.md\")   \\\n#     <(printf \"Content one. #tag3\")\n\n#   diff                                    \\\n#     <(cat \"${NB_DIR}/home/File Two.md\")   \\\n#     <(printf \"Content two. #tag1\")\n\n#   diff                                    \\\n#     <(cat \"${NB_DIR}/home/File Three.md\") \\\n#     <(printf \"Content three. tag1 #example\")\n\n#   diff                                    \\\n#     <(cat \"${NB_DIR}/home/File Four.md\")  \\\n#     <(printf \"Content #tag1 four. #example\")\n\n#   diff                                    \\\n#     <(cat \"${NB_DIR}/home/File Five.md\")  \\\n#     <(printf \"Content tag2 five.\")\n\n#   diff                                    \\\n#     <(cat \"${NB_DIR}/home/File Six.md\")   \\\n#     <(printf \"Content six. #example\")\n\n#   diff                                    \\\n#     <(cat \"${NB_DIR}/home/File Seven.md\") \\\n#     <(printf \"Content #example Seven. #tag3 #tag1\")\n# }\n\n# encoding ####################################################################\n\n@test \"'search <query>' with non-ASCII filename and query succeeds.\" {\n  {\n    \"${_NB}\" init\n\n    # NOTE: filename is in decomposed format for normalization testing.\n    \"${_NB}\" add            \\\n        --content   \"#тест\" \\\n        --filename  \"тестовый.md\"\n  }\n\n  run \"${_NB}\" search \"#тест\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                         ]]\n\n  [[    \"${#lines[@]}\"  -eq 3                         ]]\n\n  [[    \"${lines[0]}\"   =~  .*[.*1.*].*\\ тестовый.md  ]]\n  [[    \"${lines[1]}\"   =~  -*-                       ]]\n  [[    \"${lines[2]}\"   =~  1.*:.*\\#тест              ]]\n}\n\n# --type <type> ###############################################################\n\n@test \"'search <query> --type note' only searches items of type note.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n        --content   \"# Example File One Content\"    \\\n        --filename  \"File One.md\"\n\n    \"${_NB}\" add                                    \\\n        --content   \"<http://example.test/>\"        \\\n        --filename  \"File Two.bookmark.md\"\n\n    \"${_NB}\" add                                    \\\n        --content   \"# Example File Three Content\"  \\\n        --filename  \"File Three.md\"\n\n    \"${_NB}\" add                                    \\\n        --content   \"<http://example.test/>\"        \\\n        --filename  \"File Four.bookmark.md\"\n  }\n\n  run \"${_NB}\" search \"example\" --type note\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  # printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n\n  [[    \"${#lines[@]}\"  -eq 6                       ]]\n\n  [[    \"${lines[0]}\"   =~  Example\\ File\\ One      ]]\n  [[    \"${lines[1]}\"   =~  -*-                     ]]\n  [[    \"${lines[2]}\"   =~  Example.*\\ File\\ One    ]]\n\n  [[ !  \"${output}\"     =~ example.*\\.test          ]]\n}\n\n@test \"'search <query> --type text' only searches items of type text.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n        --content   \"# Example File One Content\"    \\\n        --filename  \"File One.md\"\n\n    \"${_NB}\" add                                    \\\n        --content   \"<http://example.test/>\"        \\\n        --filename  \"File Two.bookmark.md\"\n\n    \"${_NB}\" add                                    \\\n        --content   \"# Example File Three Content\"  \\\n        --filename  \"File Three.md\"\n\n    \"${_NB}\" add                                    \\\n        --content   \"<http://example.test/>\"        \\\n        --filename  \"File Four.bookmark.md\"\n  }\n\n  run \"${_NB}\" search \"example\" --type text\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  # printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                       ]]\n\n  [[    \"${#lines[@]}\"  -eq 12                      ]]\n\n  [[    \"${lines[0]}\"   =~  File\\ Four.bookmark.md  ]]\n  [[    \"${lines[1]}\"   =~  -*-                     ]]\n  [[    \"${lines[2]}\"   =~  example.*\\.test         ]]\n}\n\n@test \"'search <query> --type <type>' only searches items of type <type>.\" {\n  {\n    _setup_search\n\n    \"${_NB}\" rename \"File Two.md\" --to-todo --force\n  }\n\n  run \"${_NB}\" search \"example\" --type todo\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                             ]]\n\n  [[    \"${#lines[@]}\"  -eq 3                                             ]]\n\n  [[    \"${lines[0]}\"   =~  Title\\ Two                                    ]]\n  [[    \"${lines[1]}\"   =~  -*-                                           ]]\n  [[    \"${lines[2]}\"   =~  Example.*\\ Content\\ Two\\ .*Example.*\\ Phrase  ]]\n}\n\n# filename handling ###########################################################\n\n@test \"'search <query>' with uncommon filename exits with status 0 and prints output.\" {\n  {\n    _setup_search\n\n    \"${_NB}\" rename \"File One.md\" \"File [] One.md\"  --force\n    \"${_NB}\" rename \"File Two.md\" \"File ] Two.md\"   --force\n  }\n\n  run \"${_NB}\" search \"sample phrase\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n\n  [[ !  \"${lines[0]}\" =~  File\\ \\[\\]\\ One.md                      ]]\n  [[    \"${lines[0]}\" =~  Title\\ One                              ]]\n  [[    \"${lines[1]}\" =~  -*-                                     ]]\n  [[    \"${lines[2]}\" =~  Sample\\ Content\\ One\\ .*Sample\\ Phrase  ]]\n}\n\n# temporary files #############################################################\n\n@test \"'search' skips common temporary files.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"File One.md\"    --content \"Content one. example-query\"\n    \"${_NB}\" add \"File Two.md\"    --content \"Content two. sample-query\"\n\n    declare _temp_filenames=(\n      \"Example Temp One.md~\"\n      \"#Example Temp Two.md#\"\n      \"Example Temp Three.md.swp\"\n      \"Example Temp Four.md.swap\"\n      \".#Example Temp Five.md\"\n    )\n\n    declare __filename=\n    for     __filename in \"${_temp_filenames[@]:-}\"\n    do\n      printf \"sample-query\\\\n\" >> \"${NB_DIR}/home/${__filename:-}\"\n    done\n  }\n\n  run \"${_NB}\" search \"sample-query\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 3                                   ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*[.*2.*].*\\ File\\ Two.md\\ \\·\\ \\\"Content\\ two.\\ sample-query\\\"  ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$            ]]\n  [[    \"${lines[2]}\"   =~  \\\n1.*:.*Content\\ two.\\ .*sample-query                             ]]\n}\n\n# binary ######################################################################\n\n@test \"'search <query>' prints single match message when matching binary content.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" import \"${NB_TEST_BASE_PATH}/fixtures/example.pdf\"\n  }\n\n  run \"${_NB}\" search \"a\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0                                       ]]\n  [[    \"${#lines[@]}\"  -eq 6                                       ]]\n\n  [[    \"${lines[0]}\"   =~  .*\\[.*1.*\\].*\\ 📄\\ .*ex.*a.*mple.pdf    ]]\n  [[    \"${lines[1]}\"   =~  ^.*------------------.*$                ]]\n  [[    \"${lines[2]}\"   =~  Filename\\ Match:.*\\ .*ex.*a.*mple.pdf   ]]\n  [[    \"${lines[3]}\"   =~  .*\\[.*1.*\\].*\\ 📄\\ .*ex.*a.*mple.pdf    ]]\n  [[    \"${lines[4]}\"   =~  ^.*------------------.*$                ]]\n  [[    \"${lines[5]}\"   =~  Binary\\ file\\ matches.                  ]]\n  [[ -z \"${lines[6]}\"                                               ]]\n}\n\n# `search` ####################################################################\n\n@test \"'search' with no arguments exits with status 1 and prints help information.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1           ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:   ]]\n  [[ \"${lines[1]}\"  =~  nb\\ search  ]]\n}\n\n# notebook: selectors #########################################################\n\n@test \"'search <query> --notebook-selectors' includes notebook selectors for results in the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.md\" --content \"Example 123 content.\"\n    \"${_NB}\" add \"Example Two.md\" --content \"Example content.\"\n\n    \"${_NB}\" add \"Sample Folder/Sample One.md\" --content \"Sample content.\"\n    \"${_NB}\" add \"Sample Folder/Sample Two.md\" --content \"Sample 123 content.\"\n  }\n\n  run \"${_NB}\" search \"123\" -l --notebook-selectors\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*home:1.*\\].*\\ Example\\ One.md\\ ·\\ \\\"Example\\ 123\\ content.\\\"  ]]\n\n  [[    \"${lines[1]}\" =~  \\\n.*\\[.*home:Sample\\ Folder/2.*\\].*\\ Sample\\ Two.md\\ ·\\ \\\"Sample\\ 123\\ content.\\\" ]]\n}\n\n@test \"'search <query>' does not include notebook selectors for results in the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example One.md\" --content \"Example 123 content.\"\n    \"${_NB}\" add \"Example Two.md\" --content \"Example content.\"\n\n    \"${_NB}\" add \"Sample Folder/Sample One.md\" --content \"Sample content.\"\n    \"${_NB}\" add \"Sample Folder/Sample Two.md\" --content \"Sample 123 content.\"\n  }\n\n  run \"${_NB}\" search \"123\" -l\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*1.*\\].*\\ Example\\ One.md\\ ·\\ \\\"Example\\ 123\\ content.\\\"       ]]\n  [[ !  \"${lines[0]}\" =~  \\\n.*\\[.*home:1.*\\].*\\ Example\\ One.md\\ ·\\ \\\"Example\\ 123\\ content.\\\"  ]]\n\n  [[    \"${lines[1]}\" =~  \\\n.*\\[.*Sample\\ Folder/2.*\\].*\\ Sample\\ Two.md\\ ·\\ \\\"Sample\\ 123\\ content.\\\"      ]]\n  [[ !  \"${lines[1]}\" =~  \\\n.*\\[.*home:Sample\\ Folder/2.*\\].*\\ Sample\\ Two.md\\ ·\\ \\\"Sample\\ 123\\ content.\\\" ]]\n}\n\n@test \"'search notebook: <query> --notebook-selectors' includes notebook selectors for results in selected notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example One.md\" --content \"Example 123 content.\"\n    \"${_NB}\" add \"Example Notebook:Example Two.md\" --content \"Example content.\"\n\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample One.md\" --content \"Sample content.\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample Two.md\" --content \"Sample 123 content.\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:search \"123\" -l --notebook-selectors\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*1.*\\].*\\ Example\\ One.md\\ ·\\ \\\"Example\\ 123\\ content.\\\"       ]]\n  [[ !  \"${lines[0]}\" =~  \\\n.*\\[.*home:1.*\\].*\\ Example\\ One.md\\ ·\\ \\\"Example\\ 123\\ content.\\\"  ]]\n\n  [[    \"${lines[1]}\" =~  \\\n.*\\[.*Sample\\ Folder/2.*\\].*\\ Sample\\ Two.md\\ ·\\ \\\"Sample\\ 123\\ content.\\\"      ]]\n  [[ !  \"${lines[1]}\" =~  \\\n.*\\[.*home:Sample\\ Folder/2.*\\].*\\ Sample\\ Two.md\\ ·\\ \\\"Sample\\ 123\\ content.\\\" ]]\n}\n\n@test \"'search notebook: <query>' includes notebook selectors for results in selected notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example One.md\" --content \"Example 123 content.\"\n    \"${_NB}\" add \"Example Notebook:Example Two.md\" --content \"Example content.\"\n\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample One.md\" --content \"Sample content.\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample Two.md\" --content \"Sample 123 content.\"\n  }\n\n  run \"${_NB}\" Example\\ Notebook:search \"123\" -l\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*Example\\ Notebook:1.*\\].*\\ Example\\ One.md\\ ·\\ \\\"Example\\ 123\\ content.\\\"               ]]\n  [[    \"${lines[1]}\" =~  \\\n.*\\[.*Example\\ Notebook:Sample\\ Folder/2.*\\].*\\ Sample\\ Two.md\\ ·\\ \\\"Sample\\ 123\\ content.\\\"  ]]\n}\n\n@test \"'search <query> -la' includes notebook selectors for all results.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add \"Example Notebook:Example One.md\" --content \"Example 123 content.\"\n    \"${_NB}\" add \"Example Notebook:Example Two.md\" --content \"Example content.\"\n\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample One.md\" --content \"Sample content.\"\n    \"${_NB}\" add \"Example Notebook:Sample Folder/Sample Two.md\" --content \"Sample 123 content.\"\n\n\n    \"${_NB}\" add \"Demo One.md\" --content \"Demo 123 content.\"\n    \"${_NB}\" add \"Demo Two.md\" --content \"Demo content.\"\n\n    \"${_NB}\" add \"Test Folder/Test One.md\" --content \"Test content.\"\n    \"${_NB}\" add \"Test Folder/Test Two.md\" --content \"Test 123 content.\"\n  }\n\n  run \"${_NB}\" search \"123\" -la\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*Example\\ Notebook:1.*\\].*\\ Example\\ One.md\\ ·\\ \\\"Example\\ 123\\ content.\\\"               ]]\n  [[    \"${lines[1]}\" =~  \\\n.*\\[.*Example\\ Notebook:Sample\\ Folder/2.*\\].*\\ Sample\\ Two.md\\ ·\\ \\\"Sample\\ 123\\ content.\\\"  ]]\n  [[    \"${lines[2]}\" =~  \\\n.*\\[.*home:1.*\\].*\\ Demo\\ One.md\\ ·\\ \\\"Demo\\ 123\\ content.\\\"              ]]\n  [[    \"${lines[3]}\" =~  \\\n.*\\[.*home:Test\\ Folder/2.*\\].*\\ Test\\ Two.md\\ ·\\ \\\"Test\\ 123\\ content.\\\" ]]\n}\n\n# aliases #####################################################################\n\n@test \"'q <query>' exits with status 0 and prints output.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" q \"sample phrase\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n\n  [[ !  \"${lines[0]}\" =~  \\.md                                    ]]\n  [[    \"${lines[0]}\" =~  Title\\ One                              ]]\n  [[    \"${lines[1]}\" =~  -*-                                     ]]\n  [[    \"${lines[2]}\" =~  Sample\\ Content\\ One\\ .*Sample\\ Phrase  ]]\n}\n\n@test \"'grep <query>' exits with status 0 and prints output.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" grep \"sample phrase\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n\n  [[ !  \"${lines[0]}\" =~  \\.md                                    ]]\n  [[    \"${lines[0]}\" =~  Title\\ One                              ]]\n  [[    \"${lines[1]}\" =~  -*-                                     ]]\n  [[    \"${lines[2]}\" =~  Sample\\ Content\\ One\\ .*Sample\\ Phrase  ]]\n}\n\n# `search <no match>` #########################################################\n\n@test \"'search <query>' with no matches exits with status 1 and prints output.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"no match\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                       ]]\n  [[ \"${#lines[@]}\" -eq 1                                       ]]\n\n  [[ \"${lines[0]}\"  =~  Not\\ found\\ in.*home.*:\\ .*no\\ match.*  ]]\n}\n\n@test \"'search <query>...' with no matches exits with status 1 and prints output.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"no match\" \"matchless\" \"wont be found\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                               ]]\n  [[ \"${#lines[@]}\" -eq 1                                               ]]\n\n  [[ \"${lines[0]}\"  =~  \\\n        Not\\ found\\ in.*home.*:\\ .*no\\ match|matchless|wont\\ be\\ found  ]]\n}\n\n# `search <one match> [--path] [--list]` ######################################\n\n@test \"'search <one match>' exits with status 0 and prints output.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"sample phrase\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n\n  [[ !  \"${lines[0]}\" =~  \\.md                                    ]]\n  [[    \"${lines[0]}\" =~  Title\\ One                              ]]\n  [[    \"${lines[1]}\" =~  -*-                                     ]]\n  [[    \"${lines[2]}\" =~  Sample\\ Content\\ One\\ .*Sample\\ Phrase  ]]\n}\n\n@test \"'search <one match>' includes emoji indicator.\" {\n  {\n    _setup_search\n\n    \"${_NB}\" add                            \\\n      --filename  \"example.bookmark.md\"     \\\n      --content   \"<http://example.test/>\"  \\\n      --title     \"Example Title\"\n  }\n\n  run \"${_NB}\" search \"example.test\" --no-color\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0                   ]]\n\n  [[ !  \"${lines[0]}\" =~  example.bookmark.md ]]\n  [[    \"${lines[0]}\" =~  Example\\ Title      ]]\n  [[    \"${lines[0]}\" =~  \\]\\ 🔖              ]]\n  [[    \"${lines[1]}\" =~  -*-                 ]]\n  [[    \"${lines[2]}\" =~  example.test        ]]\n}\n\n@test \"'search <one match> --path' exits with status 0 and prints path.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"sample phrase\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n  [[ \"${lines[0]}\"  =~  ${NB_DIR}/home/File\\ One\\.md  ]]\n  [[ \"${#lines[@]}\" -eq 1                             ]]\n}\n\n@test \"'search <one match> --list' exits with status 0 and prints listing.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"sample phrase\" --list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n\n  [[ !  \"${lines[0]}\"   =~  \\.md                        ]]\n  [[    \"${lines[0]}\"   =~  [.*1.*].*\\ Title\\ One       ]]\n\n  [[    \"${#lines[@]}\"  -eq 1                           ]]\n}\n\n@test \"'search <one filename match>' exits with status 0 and prints output.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"1-example.md\"  \\\n      --title     \"One\"           \\\n      --content   \"Sample Content One Sample Phrase.\"\n\n    \"${_NB}\" add  \"sample.md\"     \\\n      --title     \"Two\"           \\\n      --content   \"Example Content Two Example Phrase.\"\n\n    \"${_NB}\" add  \"third.md\"      \\\n      --title     \"Three\"         \\\n      --content   \"Example Content Three Example Phrase.\"\n  }\n\n  run \"${_NB}\" search '1-example.md'\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[ \"${status}\"    -eq 0                                   ]]\n\n  [[ \"${lines[0]}\"  =~  [.*1.*].*\\ .*1-example.md.*\\ ·\\ One ]]\n  [[ \"${lines[1]}\"  =~  -*-                                 ]]\n  [[ \"${lines[2]}\"  =~  Filename\\ Match:\\ .*1-example.md    ]]\n}\n\n# -q / --query option #########################################################\n\n@test \"'search -q <query>' exits with status 0 and prints output.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search -q \"sample phrase\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n\n  [[ !  \"${lines[0]}\" =~  \\.md                                    ]]\n  [[    \"${lines[0]}\" =~  Title\\ One                              ]]\n  [[    \"${lines[1]}\" =~  -*-                                     ]]\n  [[    \"${lines[2]}\" =~  Sample\\ Content\\ One\\ .*Sample\\ Phrase  ]]\n}\n\n@test \"'search --query <query>' exits with status 0 and prints output.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search --query \"sample phrase\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n\n  [[ !  \"${lines[0]}\" =~  \\.md                                    ]]\n  [[    \"${lines[0]}\" =~  Title\\ One                              ]]\n  [[    \"${lines[1]}\" =~  -*-                                     ]]\n  [[    \"${lines[2]}\" =~  Sample\\ Content\\ One\\ .*Sample\\ Phrase  ]]\n}\n\n# `search` spacing and alignment ##############################################\n\n@test \"'search --list' / 'search -l' includes extra spacing to align with max notebook id length.\" {\n  {\n    _setup_search\n\n    \"${_NB}\" add                            \\\n      --filename  \"example-1.bookmark.md\"   \\\n      --content   \"<http://example.test/>\"  \\\n      --title     \"Example Title One\"\n\n    for ((_i=0; _i < 11; _i++))\n    do\n      \"${_NB}\" add \"note ${_i}\"\n    done\n\n    \"${_NB}\" add                            \\\n      --filename  \"example-2.bookmark.md\"   \\\n      --content   \"<http://example.test/>\"  \\\n      --title     \"Example Title Two\"\n  }\n\n  run \"${_NB}\" search \"example.test\" --no-color --list\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\" -eq 0                             ]]\n\n  [[    \"${output}\" =~  \\]\\ 🔖\\ Example\\ Title\\ Two   ]]\n  [[    \"${output}\" =~  \\]\\ \\ 🔖\\ Example\\ Title\\ One ]]\n\n  [[ !  \"${output}\" =~  bookmark.md                   ]]\n}\n\n@test \"'search' (no '--list' / '-l') does not include extra spacing.\" {\n  {\n    _setup_search\n\n    \"${_NB}\" add                            \\\n      --filename  \"example-1.bookmark.md\"   \\\n      --content   \"<http://example.test/>\"  \\\n      --title     \"Example Title One\"\n\n    for ((_i=0; _i < 11; _i++))\n    do\n      \"${_NB}\" add \"note ${_i}\"\n    done\n\n    \"${_NB}\" add                            \\\n      --filename  \"example-2.bookmark.md\"   \\\n      --content   \"<http://example.test/>\"  \\\n      --title     \"Example Title Two\"\n  }\n\n  run \"${_NB}\" search \"example.test\" --no-color\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"   -eq 0                           ]]\n\n  [[    \"${output}\"   =~  \\]\\ 🔖\\ Example\\ Title\\ Two ]]\n\n  [[    \"${lines[1]}\" =~  -*-                         ]]\n  [[    \"${lines[2]}\" =~  example.test                ]]\n\n  [[    \"${output}\"   =~  \\]\\ 🔖\\ Example\\ Title\\ One ]]\n  [[ !  \"${output}\"   =~  \\]\\ \\ 🔖                    ]]\n\n  [[    \"${lines[4]}\" =~  -*-                         ]]\n  [[    \"${lines[5]}\" =~  example.test                ]]\n}\n\n# `search <multiple matches> [--path] [--list]` ###############################\n\n@test \"'search <multiple matches>' exits with status 0 and prints output.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"example phrase\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[3]}: '%s'\\\\n\" \"${lines[3]}\"\n\n  [[    \"${status}\"   -eq 0                       ]]\n\n  [[ !  \"${lines[0]}\" =~  \\.md                    ]]\n  [[    \"${lines[0]}\" =~  Title\\ Two|Title\\ Three ]]\n  [[    \"${lines[1]}\" =~  -*-                     ]]\n  [[    \"${lines[2]}\" =~  Example\\ Phrase         ]]\n\n  [[ !  \"${lines[3]}\" =~  \\.md                    ]]\n  [[    \"${lines[3]}\" =~  Title\\ Two|Title\\ Three ]]\n  [[    \"${lines[4]}\" =~  -*-                     ]]\n  [[    \"${lines[5]}\" =~  Example\\ Phrase         ]]\n\n  [[    \"${lines[0]}\" !=  \"${lines[3]}\"           ]]\n}\n\n@test \"'search <multiple matches> --path' exits with 0 and prints paths.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"example phrase\" --path\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[ \"${status}\"    -eq 0                               ]]\n\n  [[ \"${output}\"    =~  ${NB_DIR}/home/File\\ Two\\.md    ]]\n  [[ \"${output}\"    =~  ${NB_DIR}/home/File\\ Three\\.md  ]]\n\n  [[ \"${#lines[@]}\" -eq 2                               ]]\n}\n\n@test \"'search <multiple matches> --list' exits with 0 and prints listings.\" {\n  {\n    _setup_search\n  }\n\n  run \"${_NB}\" search \"example phrase\" --list\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[    \"${status}\"     -eq 0             ]]\n\n  [[ !  \"${output}\"     =~  \\.md          ]]\n  [[    \"${output}\"     =~  Title\\ Two    ]]\n  [[    \"${output}\"     =~  Title\\ Three  ]]\n\n  [[    \"${#lines[@]}\"  -eq 2             ]]\n}\n\n@test \"'search <multiple filename match>' exits with status 0 and prints output.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"1-example.md\"  \\\n      --title     \"Title One\"     \\\n      --content   \"Sample Content One Sample Phrase.\"\n\n    \"${_NB}\" add  \"sample.md\"     \\\n      --title     \"Title Two\"     \\\n      --content   \"Example Content Two Example Phrase.\"\n\n    \"${_NB}\" add  \"2-example.md\"  \\\n      --title     \"Title Three\"   \\\n      --content   \"Example Content Three Example Phrase.\"\n  }\n\n  run \"${_NB}\" search \"example.md\"\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n\n  [[ \"${lines[0]}\"  =~  example.md      ]]\n  [[ \"${lines[0]}\"  =~  1               ]]\n  [[ \"${lines[0]}\"  =~  Title\\ One      ]]\n  [[ \"${lines[1]}\"  =~  -*-             ]]\n  [[ \"${lines[2]}\"  =~  Filename\\ Match ]]\n  [[ \"${lines[2]}\"  =~  example.md      ]]\n  [[ \"${lines[2]}\"  =~  1               ]]\n\n  [[ \"${lines[3]}\"  =~  example.md      ]]\n  [[ \"${lines[3]}\"  =~  2               ]]\n  [[ \"${lines[3]}\"  =~  Title\\ Three    ]]\n  [[ \"${lines[4]}\"  =~  -*-             ]]\n  [[ \"${lines[5]}\"  =~  Filename\\ Match ]]\n  [[ \"${lines[5]}\"  =~  example.md      ]]\n  [[ \"${lines[5]}\"  =~  2               ]]\n}\n\n@test \"'search' output includes indicators.\" {\n  {\n    _setup_search\n\n  cat <<HEREDOC | \"${_NB}\" add \"fourth.bookmark.md\"\n# Bookmark Title\n\n<https://example.com/>\n\ndemo phrase\nHEREDOC\n  }\n\n  run \"${_NB}\" search \"demo phrase\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[3]}:   '%s'\\\\n\"  \"${lines[3]}\"\n\n  [[    \"${status}\"   -eq 0                   ]]\n\n  [[    \"${output}\"   =~  🔖\\ Bookmark\\ Title ]]\n}\n\n# `search --bookmarks` #################################################\n\n@test \"'search --bookmarks' exits with status 0 and prints output.\" {\n  {\n    _setup_search\n\n  cat <<HEREDOC | \"${_NB}\" add \"fourth.bookmark.md\"\n# four\n\n<https://example.com/>\n\nExample Phrase\nHEREDOC\n  cat <<HEREDOC | \"${_NB}\" add \"fifth.bookmark.md\"\n# five\n\n<https://example.com/>\n\nSample Phrase\nHEREDOC\n  cat <<HEREDOC | \"${_NB}\" add \"sixth.bookmark.md\"\n# six\n\n<https://example.com/>\n\nExample Phrase\nHEREDOC\n    _files=($(ls \"${NB_DIR}/home/\")) && _filename=\"${_files[0]}\"\n  }\n\n  run \"${_NB}\" search \"example phrase\" --bookmarks\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${_filename}:  '%s'\\\\n\" \"${_filename}\"\n  printf \"\\${lines[3]}:   '%s'\\\\n\"  \"${lines[3]}\"\n\n  [[    \"${status}\"   -eq 0                     ]]\n\n  [[ !  \"${lines[0]}\" =~  \\.md                  ]]\n  [[    \"${lines[0]}\" =~  four|six              ]]\n  [[    \"${lines[1]}\" =~  -*-                   ]]\n  [[    \"${lines[2]}\" =~  Example\\ Phrase       ]]\n\n  [[ !  \"${lines[3]}\" =~  \\.md                  ]]\n  [[    \"${lines[3]}\" =~  four|six              ]]\n  [[    \"${lines[4]}\" =~  -*-                   ]]\n  [[    \"${lines[5]}\" =~  Example\\ Phrase       ]]\n\n  [[    \"${lines[0]}\" != \"${lines[3]}\"          ]]\n}\n\n# `search <query> --all [--path]` #############################################\n\n@test \"'search <query> --all' exits with status 0 and prints output.\" {\n  {\n    _search_all_setup\n  }\n\n  run \"${_NB}\" search \"example phrase\" --all\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  \"${_NB}\" notebooks --paths --unarchived\n  \"${_NB}\" notebooks --paths --unarchived\n  \"${_NB}\" two:notebooks status\n\n  [[    \"${status}\"     -eq 0                             ]]\n\n  [[ !  \"${output}\"     =~  \\.md                          ]]\n\n  [[    \"${output}\"     =~  [.*home:3.*].*\\ Title\\ Three  ]]\n  [[    \"${lines[1]}\"   =~  -*-                           ]]\n  [[    \"${lines[2]}\"   =~  Example\\ Phrase               ]]\n\n  [[    \"${output}\"     =~  [.*home:2.*].*\\ Title\\ Two    ]]\n  [[    \"${lines[4]}\"   =~  -*-                           ]]\n  [[    \"${lines[5]}\"   =~  Example\\ Phrase               ]]\n\n  [[    \"${output}\"     =~  [.*one:1.*].*\\ Example\\ Title ]]\n  [[    \"${lines[7]}\"   =~  -*-                           ]]\n  [[    \"${lines[8]}\"   =~  Example\\ Phrase               ]]\n\n  [[    \"${#lines[@]}\"  -eq 9                             ]]\n}\n\n@test \"'search <query> -a' exits with status 0 and prints output.\" {\n  {\n    _search_all_setup\n  }\n\n  run \"${_NB}\" search \"example phrase\" -a\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                             ]]\n\n  [[ !  \"${output}\"     =~  \\.md                          ]]\n\n  [[    \"${output}\"     =~  [.*home:3.*].*\\ Title\\ Three  ]]\n  [[    \"${lines[1]}\"   =~  -*-                           ]]\n  [[    \"${lines[2]}\"   =~  Example\\ Phrase               ]]\n\n  [[    \"${output}\"     =~  [.*home:2.*].*\\ Title\\ Two    ]]\n  [[    \"${lines[4]}\"   =~  -*-                           ]]\n  [[    \"${lines[5]}\"   =~  Example\\ Phrase               ]]\n\n  [[    \"${output}\"     =~  [.*one:1.*].*\\ Example\\ Title ]]\n  [[    \"${lines[7]}\"   =~  -*-                           ]]\n  [[    \"${lines[8]}\"   =~  Example\\ Phrase               ]]\n\n  [[    \"${#lines[@]}\"  -eq 9                             ]]\n}\n\n@test \"'search <no matching query> --all' exits with status 1 and prints output.\" {\n  {\n    _search_all_setup  &>/dev/null\n  }\n\n  run \"${_NB}\" search 'no match' --all\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[3]}: '%s'\\\\n\" \"${lines[3]}\"\n\n  [[ \"${status}\"  -eq 1                 ]]\n\n  [[ \"${output}\"  =~  Not\\ found        ]]\n  [[ \"${output}\"  =~  in\\ any\\ notebook ]]\n  [[ \"${output}\"  =~  no\\ match         ]]\n}\n\n@test \"'search <multiple matches> --all --path' exits with 0 and prints paths.\" {\n  {\n    _search_all_setup\n  }\n\n  run \"${_NB}\" search \"example phrase\" --all --path\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[ \"${status}\"    -eq 0                             ]]\n\n  [[ \"${#lines[@]}\" -eq 3                             ]]\n\n  [[ \"${output}\"    =~  ${NB_DIR}/home/File\\ Three.md ]]\n  [[ \"${output}\"    =~  ${NB_DIR}/home/File\\ Two.md   ]]\n  [[ \"${output}\"    =~  ${NB_DIR}/one/example.md      ]]\n}\n\n@test \"'search <no matching query> --all --path' exits with 1 and and prints output.\" {\n  {\n    _search_all_setup\n  }\n\n  run \"${_NB}\" search \"no match\" --all --path\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[0]}: '%s'\\\\n\" \"${lines[0]}\"\n\n  [[ \"${status}\"  -eq 1                 ]]\n\n  [[ \"${output}\"  =~  Not\\ found        ]]\n  [[ \"${output}\"  =~  in\\ any\\ notebook ]]\n  [[ \"${output}\"  =~  no\\ match         ]]\n}\n\n# `search <query> [--all]` local ##############################################\n\n@test \"'search <query>' in local notebook exits with status 0 and prints output.\" {\n  {\n    _search_all_setup\n\n    mkdir -p \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    git init 1>/dev/null && touch \"${_TMP_DIR}/example/.index\"\n\n    \"${_NB}\" add  \"example-1.md\"      \\\n      --title     \"Example Title One\" \\\n      --content   \"Example Phrase\"\n\n    \"${_NB}\" add  \"example-2.md\"      \\\n      --title     \"Example Title Two\"\n  }\n\n  run \"${_NB}\" search \"example phrase\"\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0                   ]]\n\n  [[    \"${lines[0]}\"   =~  1                   ]]\n  [[ !  \"${lines[0]}\"   =~  example-1.md        ]]\n  [[    \"${lines[0]}\"   =~  Example\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  -*-                 ]]\n  [[    \"${lines[2]}\"   =~  Example\\ Phrase     ]]\n\n  [[    \"${#lines[@]}\"  -eq 3                   ]]\n}\n\n@test \"'search <query> --all' in local notebook exits with status 0 and prints output.\" {\n  {\n    _search_all_setup &>/dev/null\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example\"\n\n    cd \"${_TMP_DIR}/example\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example\" ]]\n\n    \"${_NB}\" add  \"example-1.md\"    \\\n      --title     \"Local Title One\" \\\n      --content   \"Example Phrase\"\n\n    \"${_NB}\" add  \"example-2.md\"    \\\n      --title     \"Local Title Two\"\n  }\n\n  run \"${_NB}\" search \"example phrase\" --all\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  printf \"\\${lines[0]}:   '%s'\\\\n\" \"${lines[0]}\"\n  printf \"\\${lines[1]}:   '%s'\\\\n\" \"${lines[1]}\"\n  printf \"\\${lines[2]}:   '%s'\\\\n\" \"${lines[2]}\"\n  printf \"\\${lines[3]}:   '%s'\\\\n\" \"${lines[3]}\"\n  printf \"\\${lines[4]}:   '%s'\\\\n\" \"${lines[4]}\"\n  printf \"\\${lines[5]}:   '%s'\\\\n\" \"${lines[5]}\"\n  printf \"\\${lines[6]}:   '%s'\\\\n\" \"${lines[6]}\"\n  printf \"\\${lines[7]}:   '%s'\\\\n\" \"${lines[7]}\"\n  printf \"\\${lines[8]}:   '%s'\\\\n\" \"${lines[8]}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n\n  [[ !  \"${lines[0]}\"   =~  \\.md                                ]]\n\n  [[    \"${lines[0]}\"   =~  [.*local:1.*].*\\ Local\\ Title\\ One  ]]\n  [[    \"${lines[1]}\"   =~  -*-                                 ]]\n  [[    \"${lines[2]}\"   =~  Example\\ Phrase                     ]]\n\n  [[    \"${output}\"     =~  [.*home:3.*].*\\ Title\\ Three        ]]\n  [[    \"${lines[4]}\"   =~  -*-                                 ]]\n  [[    \"${lines[5]}\"   =~  Example\\ Phrase                     ]]\n\n  [[    \"${output}\"     =~  [.*home:2.*].*\\ Title\\ Two          ]]\n  [[    \"${lines[7]}\"   =~  -*-                                 ]]\n  [[    \"${lines[8]}\"   =~  Example\\ Phrase                     ]]\n\n  [[    \"${output}\"     =~  [.*one:1.*].*\\ Example\\ Title       ]]\n  [[    \"${lines[10]}\"  =~  -*-                                 ]]\n  [[    \"${lines[11]}\"  =~  Example\\ Phrase                     ]]\n\n  [[    \"${#lines[@]}\"  -eq 12                                  ]]\n}\n\n# help ########################################################################\n\n@test \"'help search' exits with status 0.\" {\n  run \"${_NB}\" help search\n\n  [[ \"${status}\" -eq 0 ]]\n}\n\n@test \"'help search' prints help information.\" {\n  run \"${_NB}\" help search\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Usage.*\\:   ]]\n  [[ \"${lines[1]}\" =~ nb\\ search  ]]\n}\n"
  },
  {
    "path": "test/settings.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2016\n\nload test_helper\n\n# help ########################################################################\n\n@test \"'help settings' exits with 0 and prints help information.\" {\n  run \"${_NB}\" help settings\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:   ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ set ]]\n}\n\n# #############################################################################\n\n@test \"'settings' with no arguments starts prompt.\" {\nskip \"Determine how to test interactive prompt.\"\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0            ]]\n  [[ \"${lines[0]}\" =~ Settings  ]]\n}\n\n@test \"'settings' with two arguments calls 'settings set'.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings EDITOR example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".nbrc: '%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"${output}\" =~ EDITOR                          ]]\n  [[ \"${output}\" =~ set\\ to\\                        ]]\n  [[ \"${output}\" =~ example                         ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"example\"'  ]]\n}\n\n# env #########################################################################\n\n@test \"EDITOR setting does not inherit from the environment.\" {\n  {\n    \"${_NB}\" init\n    [[ \"${EDITOR:-}\" != \"example\" ]]\n  }\n\n  run \"${_NB}\" settings set EDITOR example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                            ]]\n  [[ \"${output}\" =~ EDITOR                                      ]]\n  [[ \"${output}\" =~ set\\ to\\                                    ]]\n  [[ \"${output}\" =~ example                                     ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"example\"'              ]]\n\n  [[ \"$(\"${_NB}\" settings get EDITOR)\" == 'example'             ]]\n  [[ \"$(EDITOR=vim \"${_NB}\" settings get EDITOR)\" == 'example'  ]]\n}\n\n@test \"Non-EDITOR setting inherits from the environment.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_AUTO_SYNC 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                ]]\n  [[ \"${output}\" =~ NB_AUTO_SYNC                                    ]]\n  [[ \"${output}\" =~ set\\ to\\                                        ]]\n  [[ \"${output}\" =~ '0'                                             ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_AUTO_SYNC=\"${NB_AUTO_SYNC:-0}\"' ]]\n\n  [[ \"$(\"${_NB}\" settings get NB_AUTO_SYNC)\" == '0'                 ]]\n  [[ \"$(NB_AUTO_SYNC=1 \"${_NB}\" settings get NB_AUTO_SYNC)\" == '1'  ]]\n}\n\n# `colors` ####################################################################\n\n@test \"'settings colors' prints colors.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings colors\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0        ]]\n  [[ \"${output}\" =~ '   0'  ]]\n  [[ \"${output}\" =~ ' 105'  ]]\n  [[ \"${output}\" =~ ' 106'  ]]\n}\n\n@test \"'settings colors <number>' prints color.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings colors 105\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0          ]]\n  [[ \"${output}\" =~ ' 105'    ]]\n  [[ ! \"${output}\" =~ ' 106'  ]]\n}\n\n@test \"'settings colors themes' prints theme list.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings colors themes\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" == \"blacklight\"  ]]\n}\n\n# `edit` ######################################################################\n\n@test \"'settings edit' edits .nbrc.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings edit\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'mock_editor' ]]\n}\n\n# `get` #######################################################################\n\n@test \"'settings get' with no argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings get\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  [[ ${status} -eq 1        ]]\n  [[ \"${output}\" =~ 'Usage' ]]\n}\n\n@test \"'settings get' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings get EXAMPLE\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                      ]]\n  [[ \"${output}\" =~ Setting\\ not\\ found\\: ]]\n  [[ \"${output}\" =~ EXAMPLE               ]]\n}\n\n@test \"'settings get' with argument exits and prints.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings get NB_DIR\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0          ]]\n  [[ \"${output}\" =~ ${NB_DIR} ]]\n}\n\n@test \"'settings get' with lowercase argument exits and prints.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings get nb_dir\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0          ]]\n  [[ \"${output}\" =~ ${NB_DIR} ]]\n}\n\n# `list` ######################################################################\n\n@test \"'settings list' lists available settings.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings list\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ 1             ]]\n  [[ \"${lines[0]}\" =~ auto_sync     ]]\n  [[ \"${lines[1]}\" =~ 2             ]]\n  [[ \"${lines[1]}\" =~ color_primary ]]\n}\n\n@test \"'settings list --long' lists available settings with 'show'.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings list --long\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0            ]]\n  [[ \"${lines[0]}\" =~ 1         ]]\n  [[ \"${lines[0]}\" =~ auto_sync ]]\n  [[ \"${lines[1]}\" =~ --------- ]]\n}\n\n# `set` #######################################################################\n\n@test \"'settings set' with no argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1        ]]\n  [[ \"${output}\" =~ 'Usage' ]]\n}\n\n@test \"'settings set' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set EXAMPLE example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                      ]]\n  [[ \"${output}\" =~ Setting\\ not\\ found\\: ]]\n  [[ \"${output}\" =~ EXAMPLE               ]]\n}\n\n@test \"'settings set' with one argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set EDITOR\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1        ]]\n  [[ \"${output}\" =~ 'Usage' ]]\n}\n\n@test \"'settings set' with argument exits and sets.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set EDITOR example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".nbrc: '%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"${output}\" =~ EDITOR                          ]]\n  [[ \"${output}\" =~ set\\ to\\                        ]]\n  [[ \"${output}\" =~ example                         ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"example\"'  ]]\n}\n\n@test \"'settings set' with multi-word argument exits and sets.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set EDITOR \"example editor\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".nbrc: '%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[ ${status} -eq 0                                      ]]\n  [[ \"${output}\" =~ EDITOR                                ]]\n  [[ \"${output}\" =~ set\\ to\\                              ]]\n  [[ \"${output}\" =~ example\\ editor                       ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"example editor\"' ]]\n}\n\n@test \"'settings set' with lowercase setting name exits and sets.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set editor example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".nbrc: '%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"${output}\" =~ EDITOR                          ]]\n  [[ \"${output}\" =~ set\\ to\\                        ]]\n  [[ \"${output}\" =~ example                         ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"example\"'  ]]\n}\n\n@test \"'settings set' with 'unset' value unsets and exits.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" settings set color_secondary 42\n\n    printf \".nbrc: '%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n    cat \"${NBRC_PATH}\" | wc -l\n\n    [[ \"$(cat \"${NBRC_PATH}\")\"          =~  NB_COLOR_SECONDARY  ]]\n    [[ \"$(cat \"${NBRC_PATH}\")\"          =~  42                  ]]\n    [[ \"$(cat \"${NBRC_PATH}\" | wc -l)\"  -eq 16                  ]]\n  }\n\n  run \"${_NB}\" settings set color_secondary unset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".nbrc: '%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[    \"${status}\"             -eq 0                           ]]\n  [[    \"${output}\"             =~  NB_COLOR_SECONDARY          ]]\n  [[    \"${output}\"             =~  restored                    ]]\n  [[    \"${output}\"             =~  8                           ]]\n  [[ !  \"$(cat \"${NBRC_PATH}\")\" =~  NB_COLOR_SECONDARY          ]]\n  [[    \"$(cat \"${NBRC_PATH}\" | wc -l)\"   -eq 14                ]]\n}\n\n@test \"'settings set' with 'default' value unsets and exits.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" settings set color_secondary 42\n\n    [[ \"$(cat \"${NBRC_PATH}\")\"          =~  NB_COLOR_SECONDARY  ]]\n    [[ \"$(cat \"${NBRC_PATH}\")\"          =~  42                  ]]\n    [[ \"$(cat \"${NBRC_PATH}\" | wc -l)\"  -eq 16                  ]]\n  }\n\n  run \"${_NB}\" settings set color_secondary default\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".nbrc: '%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[    \"${status}\"                     -eq 0                   ]]\n  [[    \"${output}\"                     =~  NB_COLOR_SECONDARY  ]]\n  [[    \"${output}\"                     =~  restored            ]]\n  [[    \"${output}\"                     =~  8                   ]]\n  [[ !  \"$(cat \"${NBRC_PATH}\")\"         =~  NB_COLOR_SECONDARY  ]]\n  [[    \"$(cat \"${NBRC_PATH}\" | wc -l)\" -eq 14                  ]]\n}\n\n@test \"'settings set' with 'reset' value unsets and exits.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" settings set color_secondary 42\n\n    [[ \"$(cat \"${NBRC_PATH}\")\"          =~  NB_COLOR_SECONDARY  ]]\n    [[ \"$(cat \"${NBRC_PATH}\")\"          =~  42                  ]]\n    [[ \"$(cat \"${NBRC_PATH}\" | wc -l)\"  -eq 16                  ]]\n  }\n\n  run \"${_NB}\" settings set color_secondary reset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".nbrc: '%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[    \"${status}\"                     -eq 0                   ]]\n  [[    \"${output}\"                     =~  NB_COLOR_SECONDARY  ]]\n  [[    \"${output}\"                     =~  restored            ]]\n  [[    \"${output}\"                     =~  8                   ]]\n  [[ !  \"$(cat \"${NBRC_PATH}\")\"         =~  NB_COLOR_SECONDARY  ]]\n  [[    \"$(cat \"${NBRC_PATH}\" | wc -l)\" -eq 14                  ]]\n}\n\n# `set NB_AUTO_SYNC` #######################################################\n\n@test \"'settings set NB_AUTO_SYNC' with valid argument sets and exits.\" {\n  # shellcheck disable=SC1073,SC2030,SC2031\n  export NB_AUTO_SYNC=\n\n  {\n    \"${_NB}\" init\n\n    [[ \"$(\"${_NB}\" settings get NB_AUTO_SYNC)\" == '1' ]]\n  }\n\n  run \"${_NB}\" settings set NB_AUTO_SYNC 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                ]]\n  [[ \"${output}\" =~ NB_AUTO_SYNC                                    ]]\n  [[ \"${output}\" =~ set\\ to\\                                        ]]\n  [[ \"${output}\" =~ '0'                                             ]]\n  [[ \"$(\"${_NB}\" settings get NB_AUTO_SYNC)\" == '0'                 ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_AUTO_SYNC=\"${NB_AUTO_SYNC:-0}\"' ]]\n}\n\n@test \"'settings set auto_sync' with valid argument sets and exits.\" {\n  # shellcheck disable=SC1073,SC2030,SC2031\n  export NB_AUTO_SYNC=\n\n  {\n    \"${_NB}\" init\n\n    [[ \"$(\"${_NB}\" settings get NB_AUTO_SYNC)\" == '1' ]]\n  }\n\n  run \"${_NB}\" settings set auto_sync 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                ]]\n  [[ \"${output}\" =~ NB_AUTO_SYNC                                    ]]\n  [[ \"${output}\" =~ set\\ to\\                                        ]]\n  [[ \"${output}\" =~ '0'                                             ]]\n  [[ \"$(\"${_NB}\" settings get NB_AUTO_SYNC)\" == '0'                 ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_AUTO_SYNC=\"${NB_AUTO_SYNC:-0}\"' ]]\n}\n\n@test \"'settings set NB_AUTO_SYNC' with invalid argument exits with error.\" {\n  # shellcheck disable=SC1073,SC2030,SC2031\n  export NB_AUTO_SYNC=\n\n  {\n    \"${_NB}\" init\n\n    [[ \"$(\"${_NB}\" settings get NB_AUTO_SYNC)\" == '1' ]]\n  }\n\n  run \"${_NB}\" settings set NB_AUTO_SYNC '0'\n\n  [[ \"${output}\" =~ NB_AUTO_SYNC                                    ]]\n  [[ \"${output}\" =~ set\\ to\\                                        ]]\n  [[ \"${output}\" =~ '0'                                             ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_AUTO_SYNC=\"${NB_AUTO_SYNC:-0}\"' ]]\n\n  run \"${_NB}\" settings set NB_AUTO_SYNC example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"get NB_AUTO_SYNC: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_AUTO_SYNC)\"\n\n  [[ ${status} -eq 1                                                        ]]\n  [[ \"${output}\" =~ NB_AUTO_SYNC                                            ]]\n  [[ \"${output}\" =~ must\\ be\\ either                                        ]]\n  [[ \"$(\"${_NB}\" settings get NB_AUTO_SYNC)\" == '0'                         ]]\n  [[ ! \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_AUTO_SYNC=\"${NB_AUTO_SYNC:-example}\"' ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_AUTO_SYNC=\"${NB_AUTO_SYNC:-0}\"'         ]]\n}\n\n# `set NB_COLOR_PRIMARY` ######################################################\n\n@test \"'settings set NB_COLOR_PRIMARY' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_COLOR_PRIMARY 123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"NB_COLOR_PRIMARY: %s\\\\n\" \"$(\"${_NB}\" settings get NB_COLOR_PRIMARY)\"\n\n  [[ ${status} -eq 0                                                          ]]\n  [[ \"${output}\" =~ NB_COLOR_PRIMARY                                          ]]\n  [[ \"${output}\" =~ set\\ to                                                   ]]\n  [[ \"${output}\" =~ 123                                                       ]]\n  [[ \"$(NB_COLOR_PRIMARY='' \"${_NB}\" settings get NB_COLOR_PRIMARY)\" == '123' ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-123}\"' ]]\n}\n\n@test \"'settings set color_primary' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set color_primary 123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"NB_COLOR_PRIMARY: %s\\\\n\" \"$(\"${_NB}\" settings get NB_COLOR_PRIMARY)\"\n\n  [[ ${status} -eq 0                                                          ]]\n  [[ \"${output}\" =~ NB_COLOR_PRIMARY                                          ]]\n  [[ \"${output}\" =~ set\\ to                                                   ]]\n  [[ \"${output}\" =~ 123                                                       ]]\n  [[ \"$(NB_COLOR_PRIMARY='' \"${_NB}\" settings get NB_COLOR_PRIMARY)\" == '123' ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-123}\"' ]]\n}\n\n@test \"'settings set NB_COLOR_PRIMARY' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_COLOR_PRIMARY 123\n\n  [[ \"${output}\" =~ NB_COLOR_PRIMARY                                          ]]\n  [[ \"${output}\" =~ set\\ to                                                   ]]\n  [[ \"${output}\" =~ 123                                                       ]]\n  [[ \"$(NB_COLOR_PRIMARY='' \"${_NB}\" settings get NB_COLOR_PRIMARY)\" == '123' ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-123}\"' ]]\n\n  run \"${_NB}\" settings set NB_COLOR_PRIMARY invalid-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"NB_COLOR_PRIMARY: %s\\\\n\" \"$(\"${_NB}\" settings get NB_COLOR_PRIMARY)\"\n\n  [[ ${status} -eq 1                                                                      ]]\n  [[ \"${output}\" =~ \\NB_COLOR_PRIMARY\\ must\\ be\\ a\\ number\\.                              ]]\n  [[ \"$(NB_COLOR_PRIMARY='' \"${_NB}\" settings get NB_COLOR_PRIMARY)\" == '123'             ]]\n  [[ ! \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-invalid-color}\"' ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_PRIMARY=\"${NB_COLOR_PRIMARY:-123}\"'             ]]\n}\n\n# `set NB_COLOR_SECONDARY` ####################################################\n\n@test \"'settings set NB_COLOR_SECONDARY' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_COLOR_SECONDARY 123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"NB_COLOR_SECONDARY: %s\\\\n\" \"$(\"${_NB}\" settings get NB_COLOR_SECONDARY)\"\n\n  [[ ${status} -eq 0                                                              ]]\n  [[ \"${output}\" =~ NB_COLOR_SECONDARY                                            ]]\n  [[ \"${output}\" =~ set\\ to                                                       ]]\n  [[ \"${output}\" =~ 123                                                           ]]\n  [[ \"$(\"${_NB}\" settings get NB_COLOR_SECONDARY)\" == '123'                       ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-123}\"' ]]\n}\n\n@test \"'settings set color_secondary' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set color_secondary 123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"NB_COLOR_SECONDARY: %s\\\\n\" \"$(\"${_NB}\" settings get NB_COLOR_SECONDARY)\"\n\n  [[ ${status} -eq 0                                                              ]]\n  [[ \"${output}\" =~ NB_COLOR_SECONDARY                                            ]]\n  [[ \"${output}\" =~ set\\ to                                                       ]]\n  [[ \"${output}\" =~ 123                                                           ]]\n  [[ \"$(\"${_NB}\" settings get NB_COLOR_SECONDARY)\" == '123'                       ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-123}\"' ]]\n}\n\n@test \"'settings set NB_COLOR_SECONDARY' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_COLOR_SECONDARY 123\n\n  [[ \"${output}\" =~ NB_COLOR_SECONDARY                                            ]]\n  [[ \"${output}\" =~ set\\ to                                                       ]]\n  [[ \"${output}\" =~ 123                                                           ]]\n  [[ \"$(\"${_NB}\" settings get NB_COLOR_SECONDARY)\" == '123'                       ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-123}\"' ]]\n\n  run \"${_NB}\" settings set NB_COLOR_SECONDARY invalid-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"NB_COLOR_SECONDARY: %s\\\\n\" \"$(\"${_NB}\" settings get NB_COLOR_SECONDARY)\"\n\n  [[ ${status} -eq 1                                                              ]]\n  [[ \"${output}\" =~ NB_COLOR_SECONDARY\\ must\\ be\\ a\\ number.                      ]]\n  [[ \"$(\"${_NB}\" settings get NB_COLOR_SECONDARY)\" == '123'                       ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_SECONDARY=\"${NB_COLOR_SECONDARY:-123}\"' ]]\n}\n\n# `set NB_COLOR_THEME` ##############################################################\n\n@test \"'settings set NB_COLOR_THEME' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_COLOR_THEME \"console\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"NB_COLOR_THEME: %s\\\\n\" \"$(\"${_NB}\" settings get NB_COLOR_THEME)\"\n\n  [[ ${status} -eq 0                                                          ]]\n  [[ \"${output}\" =~ NB_COLOR_THEME                                            ]]\n  [[ \"${output}\" =~ set\\ to                                                   ]]\n  [[ \"${output}\" =~ console                                                   ]]\n  [[ \"$(NB_COLOR_THEME='' \"${_NB}\" settings get NB_COLOR_THEME)\" == 'console' ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_THEME=\"${NB_COLOR_THEME:-console}\"' ]]\n}\n\n@test \"'settings set color_theme' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set color_theme \"console\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"NB_COLOR_THEME: %s\\\\n\" \"$(\"${_NB}\" settings get NB_COLOR_THEME)\"\n\n  [[ ${status} -eq 0                                                          ]]\n  [[ \"${output}\" =~ NB_COLOR_THEME                                            ]]\n  [[ \"${output}\" =~ set\\ to                                                   ]]\n  [[ \"${output}\" =~ console                                                   ]]\n  [[ \"$(NB_COLOR_THEME='' \"${_NB}\" settings get NB_COLOR_THEME)\" == 'console' ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_THEME=\"${NB_COLOR_THEME:-console}\"' ]]\n}\n\n@test \"'settings set NB_COLOR_THEME' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_COLOR_THEME \"forest\"\n\n  [[ \"${output}\" =~ NB_COLOR_THEME                                            ]]\n  [[ \"${output}\" =~ set\\ to                                                   ]]\n  [[ \"${output}\" =~ forest                                                    ]]\n  [[ \"$(NB_COLOR_THEME='' \"${_NB}\" settings get NB_COLOR_THEME)\" == 'forest'  ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_THEME=\"${NB_COLOR_THEME:-forest}\"'  ]]\n\n  run \"${_NB}\" settings set NB_COLOR_THEME invalid-theme\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"NB_COLOR_THEME: %s\\\\n\" \"$(\"${_NB}\" settings get NB_COLOR_THEME)\"\n\n  [[ ${status} -eq 1                                                            ]]\n  [[ \"${output}\" =~ NB_COLOR_THEME\\ must\\ be\\ one\\ of\\ the\\ available\\ themes\\. ]]\n  [[ \"$(NB_COLOR_THEME='' \"${_NB}\" settings get NB_COLOR_THEME)\" == 'forest'    ]]\n  [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'NB_COLOR_THEME=\"${NB_COLOR_THEME:-forest}\"'    ]]\n}\n\n# `set NB_DIR` #############################################################\n\n@test \"'settings set NB_DIR' with full path argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_DIR /tmp/path/to/data/dir\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"settings get NB_DIR: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_DIR)\"\n\n  [[ ${status} -eq 0                                                        ]]\n  [[ \"${output}\" =~ NB_DIR                                                  ]]\n  [[ \"${output}\" =~ set\\ to                                                 ]]\n  [[ \"${output}\" =~ /tmp/path/to/data/dir                                   ]]\n  [[ \"$(NB_DIR='' \"${_NB}\" settings get NB_DIR)\" == '/tmp/path/to/data/dir' ]]\n}\n\n@test \"'settings set nb_dir' with full path argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set nb_dir /tmp/path/to/data/dir\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"settings get NB_DIR: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_DIR)\"\n\n  [[ ${status} -eq 0                                                        ]]\n  [[ \"${output}\" =~ NB_DIR                                                  ]]\n  [[ \"${output}\" =~ set\\ to                                                 ]]\n  [[ \"${output}\" =~ /tmp/path/to/data/dir                                   ]]\n  [[ \"$(NB_DIR='' \"${_NB}\" settings get NB_DIR)\" == '/tmp/path/to/data/dir' ]]\n}\n\n@test \"'settings set NB_DIR' with spaces sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_DIR \"/tmp/path to data/dir\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"settings get NB_DIR: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_DIR)\"\n\n  [[ ${status} -eq 0                                                        ]]\n  [[ \"${output}\" =~ NB_DIR                                                  ]]\n  [[ \"${output}\" =~ set\\ to                                                 ]]\n  [[ \"${output}\" =~ /tmp/path\\ to\\ data/dir                                 ]]\n  [[ \"$(NB_DIR='' \"${_NB}\" settings get NB_DIR)\" == '/tmp/path to data/dir' ]]\n}\n\n@test \"'settings set NB_DIR' with unquoted ~/ sets with \\$HOME.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_DIR ~/tmp/path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                    ]]\n  [[ \"${output}\" =~ NB_DIR                                              ]]\n  [[ \"${output}\" =~ set\\ to                                             ]]\n  [[ \"${output}\" =~ ${HOME}/tmp/path                                    ]]\n  [[ \"$(NB_DIR='' \"${_NB}\" settings get NB_DIR)\" == \"${HOME}/tmp/path\"  ]]\n}\n\n@test \"'settings set NB_DIR' with quoted ~/ sets with \\$HOME.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_DIR \"${HOME}/tmp/path\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                    ]]\n  [[ \"${output}\" =~ NB_DIR                                              ]]\n  [[ \"${output}\" =~ set\\ to                                             ]]\n  [[ \"${output}\" =~ ${HOME}/tmp/path                                    ]]\n  [[ \"$(NB_DIR='' \"${_NB}\" settings get NB_DIR)\" == \"${HOME}/tmp/path\"  ]]\n}\n\n@test \"'settings set NB_DIR' with invalid directory exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_DIR \"/\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                                                    ]]\n  [[ \"${output}\" =~ \\\"\\/\\\"\\ is\\ not\\ a\\ valid\\ location\\ for\\ NB_DIR\\.  ]]\n  [[ ! \"$(NB_DIR='' \"${_NB}\" settings get NB_DIR)\" == \"/\"               ]]\n}\n\n# `set NB_ENCRYPTION_TOOL` #################################################\n\n@test \"'settings set NB_ENCRYPTION_TOOL' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_ENCRYPTION_TOOL gpg\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                              ]]\n  [[ \"${output}\" =~ NB_ENCRYPTION_TOOL                                            ]]\n  [[ \"${output}\" =~ set\\ to                                                       ]]\n  [[ \"${output}\" =~ gpg                                                           ]]\n  [[ \"$(NB_ENCRYPTION_TOOL='' \"${_NB}\" settings get NB_ENCRYPTION_TOOL)\" == 'gpg' ]]\n}\n\n@test \"'settings set encryption_tool' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set encryption_tool gpg\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                              ]]\n  [[ \"${output}\" =~ NB_ENCRYPTION_TOOL                                            ]]\n  [[ \"${output}\" =~ set\\ to                                                       ]]\n  [[ \"${output}\" =~ gpg                                                           ]]\n  [[ \"$(NB_ENCRYPTION_TOOL='' \"${_NB}\" settings get NB_ENCRYPTION_TOOL)\" == 'gpg' ]]\n}\n\n@test \"'settings set NB_ENCRYPTION_TOOL' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_ENCRYPTION_TOOL 'gpg'\n\n  [[ \"${output}\" =~ NB_ENCRYPTION_TOOL  ]]\n  [[ \"${output}\" =~ set\\ to             ]]\n  [[ \"${output}\" =~ gpg                 ]]\n\n  run \"${_NB}\" settings set NB_ENCRYPTION_TOOL example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                                                              ]]\n  [[ \"${output}\" =~ NB_ENCRYPTION_TOOL                                            ]]\n  [[ \"${output}\" =~ must\\ be\\ either                                              ]]\n  [[ \"${output}\" =~ \\\"openssl\\\"\\ or\\ \\\"gpg\\\"                                      ]]\n  [[ \"$(NB_ENCRYPTION_TOOL='' \"${_NB}\" settings get NB_ENCRYPTION_TOOL)\" == 'gpg' ]]\n}\n\n# `set NB_FOOTER` #############################################################\n\n@test \"'settings set NB_FOOTER' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_FOOTER 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ \"${output}\" =~ NB_FOOTER                     ]]\n  [[ \"${output}\" =~ set\\ to\\                      ]]\n  [[ \"${output}\" =~ '0'                           ]]\n  [[ \"$(\"${_NB}\" settings get NB_FOOTER)\" == '0'  ]]\n}\n\n@test \"'settings set footer' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set footer 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ \"${output}\" =~ NB_FOOTER                     ]]\n  [[ \"${output}\" =~ set\\ to\\                      ]]\n  [[ \"${output}\" =~ '0'                           ]]\n  [[ \"$(\"${_NB}\" settings get NB_FOOTER)\" == '0'  ]]\n}\n\n@test \"'settings set NB_FOOTER' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_FOOTER '0'\n\n  [[ \"${output}\" =~ NB_FOOTER ]]\n  [[ \"${output}\" =~ set\\ to\\  ]]\n  [[ \"${output}\" =~ '0'       ]]\n\n  run \"${_NB}\" settings set NB_FOOTER example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"get NB_FOOTER: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_FOOTER)\"\n\n  [[ ${status} -eq 1                              ]]\n  [[ \"${output}\" =~ NB_FOOTER                     ]]\n  [[ \"${output}\" =~ must\\ be\\ either              ]]\n  [[ \"$(\"${_NB}\" settings get NB_FOOTER)\" == '0'  ]]\n}\n\n# `set NB_HEADER` #############################################################\n\n@test \"'settings set NB_HEADER' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_HEADER 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ \"${output}\" =~ NB_HEADER                     ]]\n  [[ \"${output}\" =~ set\\ to\\                      ]]\n  [[ \"${output}\" =~ '0'                           ]]\n  [[ \"$(\"${_NB}\" settings get NB_HEADER)\" == '0'  ]]\n}\n\n@test \"'settings set header' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set header 0\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ \"${output}\" =~ NB_HEADER                     ]]\n  [[ \"${output}\" =~ set\\ to\\                      ]]\n  [[ \"${output}\" =~ '0'                           ]]\n  [[ \"$(\"${_NB}\" settings get NB_HEADER)\" == '0'  ]]\n}\n\n@test \"'settings set NB_HEADER' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_HEADER '0'\n\n  [[ \"${output}\" =~ NB_HEADER ]]\n  [[ \"${output}\" =~ set\\ to\\  ]]\n  [[ \"${output}\" =~ '0'       ]]\n\n  run \"${_NB}\" settings set NB_HEADER example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"get NB_HEADER: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_HEADER)\"\n\n  [[ ${status} -eq 1                              ]]\n  [[ \"${output}\" =~ NB_HEADER                     ]]\n  [[ \"${output}\" =~ must\\ be\\                     ]]\n  [[ \"$(\"${_NB}\" settings get NB_HEADER)\" == '0'  ]]\n}\n\n# `set NB_LIMIT` ##############################################################\n\n@test \"'settings set NB_LIMIT' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_LIMIT 5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${output}\" =~ NB_LIMIT                  ]]\n  [[ \"${output}\" =~ set\\ to\\                  ]]\n  [[ \"${output}\" =~ 5                         ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == 5 ]]\n}\n\n@test \"'settings set limit' with valid 'auto' argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set limit auto\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"${output}\" =~ NB_LIMIT                        ]]\n  [[ \"${output}\" =~ set\\ to\\                        ]]\n  [[ \"${output}\" =~ auto                            ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == \"auto\"  ]]\n}\n\n@test \"'settings set limit' with valid 'auto-5' argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set limit auto-5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                  ]]\n  [[ \"${output}\" =~ NB_LIMIT                          ]]\n  [[ \"${output}\" =~ set\\ to\\                          ]]\n  [[ \"${output}\" =~ auto\\-5                           ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == \"auto-5\"  ]]\n}\n\n@test \"'settings set limit' with valid 'auto-5^10' argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set limit auto-5^10\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                    ]]\n  [[ \"${output}\" =~ NB_LIMIT                            ]]\n  [[ \"${output}\" =~ set\\ to\\                            ]]\n  [[ \"${output}\" =~ auto\\-5\\^10                         ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == \"auto-5^10\" ]]\n}\n\n@test \"'settings set limit' with valid 'auto+5' argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set limit auto+5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                  ]]\n  [[ \"${output}\" =~ NB_LIMIT                          ]]\n  [[ \"${output}\" =~ set\\ to\\                          ]]\n  [[ \"${output}\" =~ auto\\+5                           ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == \"auto+5\"  ]]\n}\n\n@test \"'settings set limit' with valid 'auto+5^10' argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set limit auto-5^10\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                    ]]\n  [[ \"${output}\" =~ NB_LIMIT                            ]]\n  [[ \"${output}\" =~ set\\ to\\                            ]]\n  [[ \"${output}\" =~ auto\\-5\\^10                         ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == \"auto-5^10\" ]]\n}\n\n@test \"'settings set limit' with valid 'auto^10' argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set limit auto^10\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                    ]]\n  [[ \"${output}\" =~ NB_LIMIT                            ]]\n  [[ \"${output}\" =~ set\\ to\\                            ]]\n  [[ \"${output}\" =~ auto\\^10                            ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == \"auto^10\"   ]]\n}\n\n@test \"'settings set limit' with valid number argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set limit 6\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ \"${output}\" =~ NB_LIMIT                  ]]\n  [[ \"${output}\" =~ set\\ to\\                  ]]\n  [[ \"${output}\" =~ 6                         ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == 6 ]]\n}\n\n@test \"'settings set NB_LIMIT' with invalid arguments exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_LIMIT 7\n\n  [[ \"${output}\" =~ NB_LIMIT  ]]\n  [[ \"${output}\" =~ set\\ to\\  ]]\n  [[ \"${output}\" =~ 7         ]]\n\n  run \"${_NB}\" settings set limit example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"get NB_LIMIT: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_LIMIT)\"\n\n  [[ ${status} -eq 1                          ]]\n  [[ \"${output}\" =~ NB_LIMIT                  ]]\n  [[ \"${output}\" =~ must\\ be\\                 ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == 7 ]]\n\n  run \"${_NB}\" settings set limit auto--5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"get NB_LIMIT: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_LIMIT)\"\n\n  [[ ${status} -eq 1                          ]]\n  [[ \"${output}\" =~ NB_LIMIT                  ]]\n  [[ \"${output}\" =~ must\\ be\\                 ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == 7 ]]\n\n  run \"${_NB}\" settings set limit auto++5\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"get NB_LIMIT: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_LIMIT)\"\n\n  [[ ${status} -eq 1                          ]]\n  [[ \"${output}\" =~ NB_LIMIT                  ]]\n  [[ \"${output}\" =~ must\\ be\\                 ]]\n  [[ \"$(\"${_NB}\" settings get NB_LIMIT)\" == 7 ]]\n}\n\n# `set NB_SYNTAX_THEME` #######################################################\n\n@test \"'settings set NB_SYNTAX_THEME' with valid argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_SYNTAX_THEME \"Monokai Extended\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                  ]]\n  [[ \"${output}\" =~ NB_SYNTAX_THEME                                   ]]\n  [[ \"${output}\" =~ set\\ to\\                                          ]]\n  [[ \"${output}\" =~ Monokai\\ Extended                                 ]]\n  [[ \"$(\"${_NB}\" settings get NB_SYNTAX_THEME)\" == \"Monokai Extended\" ]]\n}\n\n@test \"'settings set syntax' with valid 'Solarized (dark)' argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set syntax \"Solarized (dark)\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                  ]]\n  [[ \"${output}\" =~ NB_SYNTAX_THEME                                   ]]\n  [[ \"${output}\" =~ set\\ to\\                                          ]]\n  [[ \"${output}\" =~ Solarized\\ \\(dark\\)                               ]]\n  [[ \"$(\"${_NB}\" settings get NB_SYNTAX_THEME)\" == \"Solarized (dark)\" ]]\n}\n\n@test \"'settings set syntax' with valid 'Solarized (light)' argument sets and exits.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set syntax \"Solarized (light)\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                    ]]\n  [[ \"${output}\" =~ NB_SYNTAX_THEME                                     ]]\n  [[ \"${output}\" =~ set\\ to\\                                            ]]\n  [[ \"${output}\" =~ Solarized\\ \\(light\\)                                ]]\n  [[ \"$(\"${_NB}\" settings get NB_SYNTAX_THEME)\" == \"Solarized (light)\"  ]]\n}\n\n@test \"'settings set NB_SYNTAX_THEME' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings set NB_SYNTAX_THEME \"Solarized (dark)\"\n\n  [[ ${status} -eq 0                                                  ]]\n  [[ \"${output}\" =~ NB_SYNTAX_THEME                                   ]]\n  [[ \"${output}\" =~ set\\ to\\                                          ]]\n  [[ \"${output}\" =~ Solarized\\ \\(dark\\)                               ]]\n  [[ \"$(\"${_NB}\" settings get NB_SYNTAX_THEME)\" == \"Solarized (dark)\" ]]\n\n  run \"${_NB}\" settings set NB_SYNTAX_THEME not-a-valid-theme\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"get NB_LIMIT: '%s'\\\\n\" \"$(\"${_NB}\" settings get NB_LIMIT)\"\n\n  [[ ${status} -eq 1                                                  ]]\n  [[ \"${output}\" =~ NB_SYNTAX_THEME                                   ]]\n  [[ \"${output}\" =~ must\\ be\\                                         ]]\n  [[ \"$(\"${_NB}\" settings get NB_SYNTAX_THEME)\" == \"Solarized (dark)\" ]]\n}\n\n# `list` ######################################################################\n\n@test \"'settings show <name>' in lowercase shows setting.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings show nb_auto_sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0            ]]\n  [[ \"${lines[0]}\" =~ auto_sync ]]\n  [[ \"${lines[1]}\" =~ --------- ]]\n}\n\n@test \"'settings show <name>' in lowercase with no prefix shows setting.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings show auto_sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0            ]]\n  [[ \"${lines[0]}\" =~ auto_sync ]]\n  [[ \"${lines[1]}\" =~ --------- ]]\n}\n\n@test \"'settings show <name>' in uppercase shows setting.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings show NB_COLOR_THEME\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0              ]]\n  [[ \"${lines[0]}\" =~ color_theme ]]\n  [[ \"${lines[1]}\" =~ ----------- ]]\n}\n\n@test \"'settings show <id>' shows setting.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings show 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${lines[0]}\" =~ color_primary ]]\n  [[ \"${lines[1]}\" =~ ------------- ]]\n}\n\n# `unset` #####################################################################\n\n@test \"'settings unset' with no argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings unset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1        ]]\n  [[ \"${output}\" =~ 'Usage' ]]\n}\n\n@test \"'settings unset' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" settings unset EXAMPLE\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 1                      ]]\n  [[ \"${output}\" =~ Setting\\ not\\ found\\: ]]\n  [[ \"${output}\" =~ EXAMPLE               ]]\n}\n\n@test \"'settings unset' with argument unset, prints, and exits.\" {\n  {\n    \"${_NB}\" init\n    run \"${_NB}\" settings set EDITOR sample\n    [[ \"$(EDITOR='' \"${_NB}\" settings get EDITOR)\" == 'sample'  ]]\n    [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"sample\"'             ]]\n  }\n\n  run \"${_NB}\" settings unset EDITOR\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".nbrc:\\\\n'%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ ! \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"sample\"' ]]\n  [[ ! \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"sample\"' ]]\n  [[ \"${output}\" =~ EDITOR                          ]]\n  [[ \"${output}\" =~ restored\\ to\\ the\\ default      ]]\n  [[ ! \"${output}\" =~ sample                        ]]\n}\n"
  },
  {
    "path": "test/show-info-line.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# todos #######################################################################\n\n@test \"'show <id> --info-line' exits with status 0 and prints undone todo info line.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.todo.md\" \\\n      --content \"# [ ] Example todo description.\"\n  }\n\n  run \"${_NB}\" show 1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0               ]]\n  [[    \"${output}\" =~  \\\n.*\\[.*1.*\\].*\\ ✔️\\ \\ .*Example\\ File.todo.md.*\\ \\\".*\\[.*\\ .*\\].*\\ Example\\ todo\\ description\\.\\\"  ]]\n}\n\n@test \"'show <id> --info-line' exits with status 0 and prints done todo info line.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.todo.md\" \\\n      --content \"# [x] Example todo description.\"\n  }\n\n  run \"${_NB}\" show 1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0               ]]\n  [[    \"${output}\" =~  \\\n.*\\[.*1.*\\].*\\ ✅\\ .*Example\\ File.todo.md.*\\ \\\".*\\[.*x.*\\].*\\ Example\\ todo\\ description\\.\\\"   ]]\n}\n\n# error handling ##############################################################\n\n@test \"'show <not-valid> --info-line' exits with status 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show \"99\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 1           ]]\n  [[    \"${output}\" =~  Not\\ found: ]]\n  [[    \"${output}\" =~  99          ]]\n}\n\n@test \"'show <folder>/<not-valid> --info-line' exits with status 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show \"Example Folder/99\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 1           ]]\n  [[    \"${output}\" =~  Not\\ found: ]]\n  [[    \"${output}\" =~  99          ]]\n}\n\n# edge cases ##################################################################\n\n@test \"'show <id> --info-line' exits with status 0 and prints note info when filename contains colon and spaces.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                        \\\n      --content   \"Example content.\"    \\\n      --filename  \"http: not a url.md\"  \\\n      --title     \"Example Title\"\n  }\n\n  run \"${_NB}\" show 1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                     ]]\n  [[    \"${output}\" =~  1                     ]]\n  [[    \"${output}\" =~  http:\\ not\\ a\\ url.md ]]\n  [[    \"${output}\" =~  Example\\ Title        ]]\n  [[ !  \"${output}\" =~  home                  ]]\n}\n\n# folders #####################################################################\n\n@test \"'show <relative-path> --info-line' exits with status 0 and prints nested file info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show \"Example Folder/example.md\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                   ]]\n  [[    \"${output}\" =~  1                   ]]\n  [[    \"${output}\" =~  Example\\ Folder/1   ]]\n  [[    \"${output}\" =~  example.md          ]]\n  [[    \"${output}\" =~  Example\\ Title      ]]\n  [[ !  \"${output}\" =~  home                ]]\n}\n\n@test \"'show <relative-path> --info-line' exits with status 0 and prints nested folder info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/\"\n  }\n\n  run \"${_NB}\" show \"Example Folder/Sample Folder\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                               ]]\n  [[    \"${output}\" =~  1                               ]]\n  [[    \"${output}\" =~  Example\\ Folder/1               ]]\n  [[    \"${output}\" =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[ !  \"${output}\" =~  home                            ]]\n}\n\n@test \"'show <folder>/<id> --info-line' exits with status 0 and prints nested file info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show \"Example Folder/1\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                 ]]\n  [[    \"${output}\" =~  1                 ]]\n  [[    \"${output}\" =~  Example\\ Folder/1 ]]\n  [[    \"${output}\" =~  example.md        ]]\n  [[    \"${output}\" =~  Example\\ Title    ]]\n  [[ !  \"${output}\" =~  home              ]]\n}\n\n@test \"'show <folder>/<id> --info-line' exits with status 0 and prints nested folder info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/\"\n  }\n\n  run \"${_NB}\" show \"Example Folder/1\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                               ]]\n  [[    \"${output}\" =~  1                               ]]\n  [[    \"${output}\" =~  Example\\ Folder/1               ]]\n  [[    \"${output}\" =~  Example\\ Folder/Sample\\ Folder  ]]\n  [[ !  \"${output}\" =~  home                            ]]\n}\n\n@test \"'show <folder>/<folder-id>/<id> --info-line' exits with status 0 and prints nested file info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show \"Example Folder/1/1\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                                         ]]\n  [[    \"${output}\" =~  1                                         ]]\n  [[    \"${output}\" =~  Example\\ Folder/Sample\\ Folder/1          ]]\n  [[    \"${output}\" =~  Example\\ Folder/Sample\\ Folder/example.md ]]\n  [[    \"${output}\" =~  Example\\ Title                            ]]\n  [[ !  \"${output}\" =~  home                                      ]]\n}\n\n@test \"'show <folder>/<folder-id>/<id> --info-line' exits with status 0 and prints nested folder info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example Folder/Sample Folder/Demo Folder/\"\n  }\n\n  run \"${_NB}\" show \"Example Folder/1/1\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                                           ]]\n  [[    \"${output}\" =~  1                                           ]]\n  [[    \"${output}\" =~  Example\\ Folder/Sample\\ Folder/1            ]]\n  [[    \"${output}\" =~  Example\\ Folder/Sample\\ Folder/Demo\\ Folder ]]\n  [[ !  \"${output}\" =~  home                                        ]]\n}\n\n@test \"'show <notebook>:<folder-id>/<filename> --info-line' exits with status 0 and prints nested folder info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"Example Notebook\"\n    \"${_NB}\" add  \"Example Notebook:Sample Folder/Example File.md\"  \\\n      --title     \"Example Title\"                                   \\\n      --content   \"Example content.\"\n  }\n\n  run \"${_NB}\" show \"Example Notebook:1/Example File.md\" --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0                                                 ]]\n  [[    \"${output}\" =~  1                                                 ]]\n  [[    \"${output}\" =~  Example\\ Notebook:Sample\\ Folder/1                ]]\n  [[    \"${output}\" =~  Example\\ Notebook:Sample\\ Folder/Example\\ File.md ]]\n  [[ !  \"${output}\" =~  home                                              ]]\n}\n\n# first line #################################################################\n\n@test \"'show <id> --info-line' with path in title prints title.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.md\"\n# Example /path/in/title/Example File.md\nHEREDOC\n  }\n\n  run \"${_NB}\" show 1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"  -eq 0                                           ]]\n  [[   \"${output}\"  =~  1                                           ]]\n  [[   \"${output}\"  =~  example.md                                  ]]\n  [[   \"${output}\"  =~  \\\"Example\\ /path/in/title/Example\\ File.md  ]]\n  [[ ! \"${output}\"  =~  __first_line                                ]]\n}\n\n@test \"'show <id> --info-line' exits with status 0 and does not print first line.\" {\n  {\n    \"${_NB}\" init\n    cat <<HEREDOC | \"${_NB}\" add \"example.md\"\nExample line one.\n\nExample line three (line two is blank).\nHEREDOC\n  }\n\n  run \"${_NB}\" show 1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${status}\"  -eq 0                   ]]\n  [[   \"${output}\"  =~  1                   ]]\n  [[   \"${output}\"  =~  example.md          ]]\n  [[ ! \"${output}\"  =~  Example\\ line\\ one. ]]\n  [[ ! \"${output}\"  =~  __first_line        ]]\n}\n\n# `show <id> --info-line` #####################################################\n\n@test \"'show <id> --info-line' exits with status 0 and prints unscoped note info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show 1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${output}\" =~ 1               ]]\n  [[ \"${output}\" =~ example.md      ]]\n  [[ \"${output}\" =~ Example\\ Title  ]]\n  [[ ! \"${output}\" =~ home          ]]\n}\n\n@test \"'show <id> --info-line' exits with status 0 and prints scoped note info.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add one\n    \"${_NB}\" one:add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show one:1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${output}\" =~ one:1           ]]\n  [[ \"${output}\" =~ one:example.md  ]]\n  [[ \"${output}\" =~ Example\\ Title  ]]\n}\n\n@test \"'show <id> --info-line' prints escaped multi-word notebook name when scoped.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"multi word\"\n    \"${_NB}\" multi\\ word:add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show multi\\ word:1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                        ]]\n  [[ \"${output}\" =~ multi\\ word:1           ]]\n  [[ \"${output}\" =~ multi\\ word:example.md  ]]\n  [[ \"${output}\" =~ Example\\ Title          ]]\n}\n\n@test \"'show <id> --info-line' includes indicators.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.bookmark.md\"    \\\n      --title   \"Example Title\"           \\\n      --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" show 1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status}      -eq 0                   ]]\n  [[ \"${output}\"    =~ 1                    ]]\n  [[ \"${output}\"    =~ example.bookmark.md  ]]\n  [[ \"${output}\"    =~ Example\\ Title       ]]\n  [[ ! \"${output}\"  =~ home                 ]]\n  [[ \"${output}\"    =~ 🔖                   ]]\n  [[ ! \"${output}\"  =~ 🔒                   ]]\n}\n\n@test \"'show <id> --info-line' includes encrypted indicators.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.bookmark.md\"    \\\n      --title   \"Example Title\"           \\\n      --content \"<https://example.test>\"  \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" show 1 --info-line\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status}      -eq 0                       ]]\n  [[ \"${output}\"    =~ 1                        ]]\n  [[ \"${output}\"    =~ example.bookmark.md.enc  ]]\n  [[ ! \"${output}\"  =~ Example\\ Title           ]]\n  [[ ! \"${output}\"  =~ home                     ]]\n  [[ \"${output}\"    =~ 🔖                       ]]\n  [[ \"${output}\"    =~ 🔒                       ]]\n}\n"
  },
  {
    "path": "test/show-render.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# syntax highlighting #########################################################\n\n@test \"'show <item>' includes syntax highlighting.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"example.rb\" --content  \"puts \\\"Hello World\\\"\"\n\n    sleep 1\n  }\n\n  run \"${_NB}\" show 1 --render --print --raw\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    ==  0                                            ]]\n  [[    \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\>                          ]]\n\n  [[ !  \"${output}\"    =~  \\<nav\\ class=\\\"header-crumbs\\\"\\>             ]]\n\n  [[    \"${output}\"    =~  pre\\ \\>\\ code.sourceCode                     ]]\n\n  [[    \"${output}\"    =~  \\\n\\<div\\ class=\\\"sourceCode\\\"\\ id=\\\"cb1\\\"\\>\\<pre\\ class=\\\"sourceCode\\ rb\\\"\\>\\<code\\  ]]\n\n  [[    \"${output}\"    =~  \\<code\\ class=\\\"sourceCode\\ ruby\\\"\\>         ]]\n\n  [[    \"${output}\"    =~  \\\n\\<span\\ class=\\\"fu\\\"\\>puts\\</span\\>\\ \\<span\\ class=\\\"st\\\"\\>\\&quot\\;Hello\\ World\\&quot\\;\\</span\\> ]]\n}\n\n# .asciidoc ###################################################################\n\n@test \"'show' with .asciidoc file renders an HTML page with wiki-style links resolved to file URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.asciidoc\" \\\n      --title     \"Title One\"                   \\\n      --content   \"$(cat <<HEREDOC\n= Example AsciiDoc Title\n\nExample content. [[Example Title]]\nHEREDOC\n      )\"\n  }\n\n  run \"${_NB}\" show 2/1 --render --print --raw\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  # TODO: .org / org mode titles in pandoc HTML output?\n  # [[ \"${output}\"    =~  \\<h1\\ id=\\\"title-one\\\"\\>Title\\ One\\</h1\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"file://${NB_DIR}/home/Example%20File.md\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<h1 .*>Example AsciiDoc Title</h1>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v \\\n\"<p>= Example AsciiDoc Title</p>\"\n}\n\n# .org ########################################################################\n\n@test \"'show' with .org file renders an HTML page with wiki-style links resolved to file URLs.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"Example File.md\"             \\\n      --title     \"Example Title\"               \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Example Folder/File One.org\" \\\n      --title     \"Title One\"                   \\\n      --content   \"Example content. [[Example Title]]\"\n  }\n\n  run \"${_NB}\" show 2/1 --render --print --raw\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    ==  0                   ]]\n  [[ \"${output}\"    =~  \\<\\!DOCTYPE\\ html\\> ]]\n\n  # TODO: .org / org mode titles in pandoc HTML output?\n  # [[ \"${output}\"    =~  \\<h1\\ id=\\\"title-one\\\"\\>Title\\ One\\</h1\\> ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"<p>Example content. <a.* href=\\\"file://${NB_DIR}/home/Example%20File.md\\\">\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n\"\\[\\[Example Title\\]\\]</a></p>\"\n}\n\n# links #######################################################################\n\n@test \"'show --render' properly resolves titled wiki-style links.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Root Title One\"    \\\n      --content   \"$(<<HEREDOC cat\nExample link one: [[Root Title Two]]\n\nMore example [[Example Notebook:Example Folder/1]] content [[3/1]] here.\nHEREDOC\n)\"\n\n    \"${_NB}\" add  \"File Two.md\"       \\\n      --title     \"Root Title Two\"    \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Sample Folder/File One.md\"                   \\\n      --title     \"Sample Nested Title Two\"                     \\\n      --content   \"Sample nested content one.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File One.md\" \\\n      --title     \"Example Nested Title One\"                    \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" use \"Sample Notebook\"\n  }\n\n  run \"${_NB}\" show home:1 --render --print --raw\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"one: <a.* href=\\\"file://${NB_DIR}/home/File%20Two.md\\\">\\[\\[Root Title Two\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"example <a.* href=\\\"file://${NB_DIR}/Example%20Notebook/Example%20Folder/File%20One.md\\\">\\[\\[Example\\ Notebook:Example\\ Folder/1\\]\\]</a> content\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"content <a.* href=\\\"file://${NB_DIR}/home/Sample%20Folder/File%20One.md\\\">\\[\\[3/1\\]\\]</a> here\"\n}\n\n@test \"'show --render' properly resolves titled wiki-style links and skips links with non-resolving selectors.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Root Title One\"    \\\n      --content   \"$(<<HEREDOC cat\nExample link one: [[Root Title Two]]\n\nMore example [[Example Notebook:Example Folder/1]] content [[2/1]] here.\nHEREDOC\n)\"\n\n    \"${_NB}\" add  \"File Two.md\"       \\\n      --title     \"Root Title Two\"    \\\n      --content   \"Example content.\"\n\n    \"${_NB}\" add  \"Sample Folder/File One.md\"                   \\\n      --title     \"Sample Nested Title Two\"                     \\\n      --content   \"Sample nested content one.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File One.md\" \\\n      --title     \"Example Nested Title One\"                    \\\n      --content   \"Example nested content one.\"\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" use \"Sample Notebook\"\n  }\n\n  run \"${_NB}\" show home:1 --render --print --raw\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"one: <a.* href=\\\"file://${NB_DIR}/home/File%20Two.md\\\">\\[\\[Root Title Two\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"example <a.* href=\\\"file://${NB_DIR}/Example%20Notebook/Example%20Folder/File%20One.md\\\">\\[\\[Example\\ Notebook:Example\\ Folder/1\\]\\]</a> content\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q 'content \\[\\[2/1\\]\\] here'\n}\n\n@test \"'show --render' properly resolves duplicated wiki-style links.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Root Title One\"    \\\n      --content   \"$(<<HEREDOC cat\nExample link one: [[Example Notebook:Example Folder/1]]\n\nMore example [[Example Notebook:Example Folder/1]] content.\nHEREDOC\n)\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File One.md\" \\\n      --title     \"Nested Title One\"                            \\\n      --content   \"Nested content one.\"\n  }\n\n  run \"${_NB}\" show 1 --render --print --raw\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n   \"link one: <a.* href=\\\"file://${NB_DIR}/Example%20Notebook/Example%20Folder/File%20One.md\\\">\\[\\[Example\\ Notebook:Example\\ Folder/1\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q -v\\\n    \"example <a.* href=\\\"file://${NB_DIR}/Example%20Notebook/Example%20Folder/File%20One.md\\\">\\[\\[Example\\ Notebook:Example\\ Folder/1\\]\\]</a>\"\n}\n\n@test \"'show --render' resolves wiki-style links.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add  \"File One.md\"       \\\n      --title     \"Root Title One\"    \\\n      --content   \"$(<<HEREDOC cat\nExample content one [[Sample Folder/Nested Title One]] with more [[Example Notebook:File Two.md]].\n\nMore example [[Example Notebook:Example Folder/1]] content.\nHEREDOC\n)\"\n\n    \"${_NB}\" add  \"File Two.md\"                   \\\n      --title     \"Root Title Two\"                \\\n      --content   \"Root content two.\"\n\n    \"${_NB}\" add  \"Sample Folder/File One.md\"     \\\n      --title     \"Nested Title One\"              \\\n      --content   \"Nested content one.\"\n\n    \"${_NB}\" add  \"Sample Folder/File Two.md\"     \\\n      --title     \"Nested Title Two\"              \\\n      --content   \"Nested content two.\"\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" add  \"Example Notebook:File One.md\"  \\\n      --title     \"Root Title One\"                \\\n      --content   \"Root content one.\"\n\n    \"${_NB}\" add  \"Example Notebook:File Two.md\"  \\\n      --title     \"Root Title Two\"                \\\n      --content   \"Root content two.\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File One.md\" \\\n      --title     \"Nested Title One\"                            \\\n      --content   \"Nested content one.\"\n\n    \"${_NB}\" add  \"Example Notebook:Example Folder/File Two.md\" \\\n      --title     \"Nested Title Two\"                            \\\n      --content   \"Nested content two.\"\n  }\n\n  run \"${_NB}\" show 1 --render --print --raw\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"<a.* href=\\\"file://${NB_DIR}/home/Sample%20Folder/File%20One.md\\\">\\[\\[Sample\\ Folder/Nested\\ Title\\ One\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"<a.* href=\\\"file://${NB_DIR}/Example%20Notebook/File%20Two.md\\\">\\[\\[Example\\ Notebook:File\\ Two.md\\]\\]</a>\"\n\n  printf \"%s\\\\n\" \"${output}\" | grep -q \\\n    \"<a.* href=\\\"file://${NB_DIR}/Example%20Notebook/Example%20Folder/File%20One.md\\\">\\[\\[Example\\ Notebook:Example\\ Folder/1\\]\\]</a>\"\n}\n\n# --render, --print, and --raw ################################################\n\n@test \"'show --print' prints the un-rendered file contents with highlighting.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"\\\n# Example Title\n\nExample content with [a link](https://example.test) and *formatting*.\"\n  }\n\n  run \"${_NB}\" show \"Example File.md\" --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                   ]]\n  [[ \"${lines[0]}\"  =~  \\.*#.*\\ .*Example\\ Title.*                          ]]\n  [[ \"${lines[1]}\"  =~  \\\n       Example\\ content\\ with\\ .*\\[.*a\\ link.*\\](.*https://example.test.*)  ]]\n  [[ \"${lines[1]}\"  =~  \\ and\\ .*\\*.*formatting.*\\*.*\\.                     ]]\n}\n\n@test \"'show --print --raw' prints the un-rendered file contents without highlighting.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"\\\n# Example Title\n\nExample content with [a link](https://example.test) and *formatting*.\"\n  }\n\n  run \"${_NB}\" show \"Example File.md\" --print --raw\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                                     ]]\n  [[ \"${lines[0]}\"  ==  \"# Example Title\"                                     ]]\n  [[ \"${lines[1]}\"  ==  \\\n      \"Example content with [a link](https://example.test) and *formatting*.\" ]]\n}\n\n@test \"'show --render --print' prints the rendered file as dump from browser.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"\\\n# Example Title\n\nExample content with [a link](https://example.test) and *formatting*.\"\n  }\n\n  run \"${_NB}\" show \"Example File.md\" --render --print\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                               ]]\n  [[ \"${lines[0]}\"  ==  \"Example Title\"                                 ]]\n  [[ \"${lines[1]}\"  ==  \"Example content with a link and formatting.\"   ]]\n}\n\n@test \"'show --render --print --raw' prints the rendered file as raw HTML.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" \\\n      --content \"\\\n# Example Title\n\nExample content with [a link](https://example.test) and *formatting*.\"\n  }\n\n  run \"${_NB}\" show \"Example File.md\" --render --print --raw\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 0                                                   ]]\n  [[ \"${output}\"  =~  \\<!DOCTYPE\\ html\\>                                  ]]\n  [[ \"${output}\"  =~  \\<h1\\ id=\\\"example-title\\\"\\>Example\\ Title\\</h1\\>   ]]\n  [[ \"${output}\"  =~  \\<p\\>Example\\ content\\ with\\                        ]]\n  [[ \"${output}\"  =~  \\<a.*\\ href=\\\"https://example.test\\\"\\>a\\ link\\</a\\> ]]\n  [[ \"${output}\"  =~  and\\ \\<em\\>formatting\\</em\\>.\\</p\\>                 ]]\n}\n"
  },
  {
    "path": "test/show.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# --authors ###################################################################\n\n@test \"'show --authors' prints the list of authors for a file.\" {\n  {\n    \"${_NB}\" init\n\n    declare _global_email=\n    _global_email=\"$(\n      git -C \"${NB_DIR}/home\" config --global user.email  ||\n      git -C \"${NB_DIR}/home\" config user.email           || :\n    )\"\n\n    declare _global_name=\n    _global_name=\"$(\n      git -C \"${NB_DIR}/home\" config --global user.name   ||\n      git -C \"${NB_DIR}/home\" config user.name            || :\n    )\"\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" show 1 --authors\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 1   ]]\n\n  [[ \"${lines[0]}\"  ==  \"${_global_name} <${_global_email}>\" ]]\n\n  \"${_NB}\" notebooks author                   \\\n    --email \"example-new-email@example.test\"  \\\n    --name \"Example New Name\" <<< \"y${_NEWLINE}\"\n\n  \"${_NB}\" edit 1 --content \"Example updated content.\"\n\n  run \"${_NB}\" show 1 --authors\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[ \"${status}\"    -eq 0   ]]\n  [[ \"${#lines[@]}\" -eq 2   ]]\n\n  # ordering is dependent on global name\n\n  _contains \"${_global_name} <${_global_email}>\"                \\\n    \"${lines[0]}\" \"${lines[1]}\"\n\n  _contains \"Example New Name <example-new-email@example.test>\" \\\n    \"${lines[0]}\" \"${lines[1]}\"\n}\n\n# --type ######################################################################\n\n@test \"'show <selector> --type' with a folder exits with status 0 and prints type.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type folder\n  }\n\n  run \"${_NB}\" show 1 --type\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0         ]]\n  [[ \"${output}\" ==   \"folder\"  ]]\n}\n\n@test \"'show <selector> --type' with a markdown file exits with status 0 and prints file extension.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" show 1 --type\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0     ]]\n  [[ \"${output}\" ==   \"md\"  ]]\n}\n\n# --url #######################################################################\n\n@test \"'show --url' with invalid <id> prints error.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n  }\n\n  run \"${_NB}\" show 99 --url\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 1          ]]\n  [[ \"${output}\" =~ Not\\ found  ]]\n}\n\n@test \"'show --url' with note exits with 1 and prints error.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" show 1 --url\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 1                ]]\n  [[ \"${output}\" =~ Not\\ a\\ bookmark. ]]\n}\n\n@test \"'show --url' with URL-less bookmark exits with 1 and prints error.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Example File.bookmark.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" show 1 --url\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 1                ]]\n  [[ \"${output}\" =~ No\\ URL\\ found.   ]]\n}\n\n@test \"'show --url' prints bookmark url.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n  }\n\n  run \"${_NB}\" show 1 --url\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"${_BOOKMARK_URL}\"  ]]\n}\n\n@test \"'show --url' with multiple URLs prints first url in <>.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add example.bookmark.md \\\n      --content \"\\\nhttps://example.com\n<${_BOOKMARK_URL}>\n<https://example.com>\"\n  }\n\n  run \"${_NB}\" show 1 --url\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"${_BOOKMARK_URL}\"  ]]\n}\n\n@test \"'show --url' with encrypted bookmark prints bookmark URL.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\" --encrypt --password=example\n  }\n\n  run \"${_NB}\" show 1 --url --password=example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"${_BOOKMARK_URL}\"  ]]\n}\n\n@test \"'show --url' with gemini:// protocol bookmark prints bookmark URL.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"gemini://example.com/\"\n  }\n\n  run \"${_NB}\" show 1 --url\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                         ]]\n  [[ \"${output}\" ==   \"gemini://example.com/\"   ]]\n}\n\n@test \"'show --url' with whitespace around URL prints bookmark URL.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add                                \\\n      --filename  \"example.bookmark.md\"         \\\n      --content   \"$(cat <<HEREDOC\n# Example Bookmark Title (example.com)\n\n    <https://example.com>   \n\n## Content\n\nExample content.\nHEREDOC\n\n      )\"\n  }\n\n  run \"${_NB}\" show 1 --url\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                         ]]\n  [[ \"${output}\" ==   \"https://example.com\"     ]]\n}\n\n# `show <notebook>` ###########################################################\n\n@test \"'show <notebook>' exits with status 0 and runs ls in the notebook.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"home-one.md\"\n    \"${_NB}\" add \"home-two.md\"\n    \"${_NB}\" notebooks add example\n    \"${_NB}\" example:add \"example-one.md\"\n    \"${_NB}\" example:add \"example-two.md\"\n  }\n\n  run \"${_NB}\" show example\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${lines[0]}\"  =~  example     ]]\n  [[ \"${lines[0]}\"  =~  home        ]]\n  [[ \"${lines[1]}\"  =~  ----        ]]\n  [[ \"${lines[2]}\"  =~  example-two ]]\n  [[ \"${lines[3]}\"  =~  example-one ]]\n}\n\n@test \"'show <notebook>:' (with colon) exits with status 0 and runs ls in the notebook.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"home-one.md\"\n    \"${_NB}\" add \"home-two.md\"\n    \"${_NB}\" notebooks add example\n    \"${_NB}\" example:add \"example-one.md\"\n    \"${_NB}\" example:add \"example-two.md\"\n  }\n\n  run \"${_NB}\" show example:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${lines[0]}\"  =~ example      ]]\n  [[ \"${lines[0]}\"  =~ home         ]]\n  [[ \"${lines[1]}\"  =~ ----         ]]\n  [[ \"${lines[2]}\"  =~ example-two  ]]\n  [[ \"${lines[3]}\"  =~ example-one  ]]\n}\n\n@test \"'show <notebook> --sort' exits with status 0 and runs ls in the notebook.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"home-one.md\"\n    \"${_NB}\" add \"home-two.md\"\n    \"${_NB}\" notebooks add example\n    \"${_NB}\" example:add \"example-one.md\"\n    \"${_NB}\" example:add \"example-two.md\"\n  }\n\n  run \"${_NB}\" show example --sort\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${lines[0]}\"  =~  example-one ]]\n  [[ \"${lines[1]}\"  =~  example-two ]]\n}\n\n@test \"'show <notebook> --path' exits with status 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" show example --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                     ]]\n  [[ \"${#lines[@]}\" -eq 1                     ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found:.*example  ]]\n}\n\n@test \"'show <notebook-path> --path --notebook' exits with status 0 and prints nothing.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" show \"${NB_DIR}/example\" --path --notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"${NB_DIR}/example\" ]]\n}\n\n@test \"'show <notebook> --relative-path' exits with status 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" show example --relative-path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                     ]]\n  [[ \"${#lines[@]}\" -eq 1                     ]]\n  [[ \"${lines[0]}\"  =~  Not\\ found:.*example  ]]\n}\n\n@test \"'show <notebook> --relative-path --notebook' exits with status 0 and prints nothing.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" show example --relative-path --notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n@test \"'show <notebook-path> --relative-path --notebook' exits with status 0 and prints nothing.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add example\n  }\n\n  run \"${_NB}\" show  \"${NB_DIR}/example\" --relative-path --notebook\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"  -eq 0  ]]\n  [[ -z \"${output}\"         ]]\n}\n\n# `show` ######################################################################\n\n@test \"'show' with no argument exits with status 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1           ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\:   ]]\n  [[ \"${lines[1]}\"  =~  '  nb show' ]]\n}\n\n@test \"'show' with no argument does not show the note file.\" {\n  skip \"TODO: Determine how to test for '\\$PAGER'.\"\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n}\n\n# `show --dump` ###############################################################\n\n@test \"'show --dump' with argument exits with 0 and prints note with highlighting.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Example\"\n  }\n\n  run \"${_NB}\" show 1 --dump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0           ]]\n  [[ !  \"${lines[0]}\" ==  \"# Example\" ]]\n  [[    \"${lines[0]}\" =~  \"Example\"   ]]\n}\n\n@test \"'show --dump --no-color' with argument exits with 0 and prints note without highlighting.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Example\"\n  }\n\n  run \"${_NB}\" show 1 --dump --no-color\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0           ]]\n  [[ \"${lines[0]}\"  =~  \"# Example\" ]]\n}\n\n@test \"'show --dump' with no argument exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Example\"\n  }\n\n  run \"${_NB}\" show --dump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 1           ]]\n  [[ !  \"${output}\"   =~  mock_editor ]]\n  [[    \"${lines[0]}\" =~  Usage.*\\:   ]]\n  [[    \"${lines[1]}\" =~  '  nb show' ]]\n}\n\n# <selector> ##################################################################\n\n@test \"'show <selector>' with empty repo exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show 1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                                   ]]\n  [[ \"${lines[0]}\"  ==  \"${_ERROR_PREFIX} Not found: $(_color_primary \"1\")\" ]]\n}\n\n# `show <filename> --dump` ####################################################\n\n@test \"'show <filename> --dump' exits with status 0 and dumps note file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show \"example.md\" --dump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0           ]]\n  [[ \"${output}\" =~   mock_editor ]]\n}\n\n# `show <id> --dump` ##########################################################\n\n@test \"'show <id> --dump' exits with status 0 and dumps note file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n  }\n\n  run \"${_NB}\" show 1 --dump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0           ]]\n  [[ \"${output}\" =~   mock_editor ]]\n}\n\n# `show <path> --dump` #######################################################\n\n@test \"'show <path> --dump' exits with status 0 and dumps note file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show \"${NB_DIR}/home/example.md\" --dump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0           ]]\n  [[ \"${output}\" =~   mock_editor ]]\n}\n\n# `show <title> --dump` #######################################################\n\n@test \"'show <title> --dump' exits with status 0 and dumps note file.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show \"Example Title\" --dump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0               ]]\n  [[ \"${output}\" =~   Example\\ Title  ]]\n}\n\n# `show <filename> --path` ####################################################\n\n@test \"'show <filename> --path' exits with status 0 and prints note path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show \"example.md\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                           ]]\n  [[ \"${output}\" ==   \"${NB_DIR}/home/example.md\" ]]\n}\n\n# `show <id> --path` ##########################################################\n\n@test \"'show <id> --path' exits with status 0 and prints note path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show 1 --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                           ]]\n  [[ \"${output}\" ==   \"${NB_DIR}/home/example.md\" ]]\n}\n\n# `show <path> --path` #######################################################\n\n@test \"'show <path> --path' exits with status 0 and prints note path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show \"${NB_DIR}/home/example.md\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                           ]]\n  [[ \"${output}\" ==   \"${NB_DIR}/home/example.md\" ]]\n}\n\n# `show <title> --path` #######################################################\n\n@test \"'show <title> --path' exits with status 0 and prints note path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show \"Example Title\" --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                           ]]\n  [[ \"${output}\" ==   \"${NB_DIR}/home/example.md\" ]]\n}\n\n# `show <filename> --id` ######################################################\n\n@test \"'show <filename> --id' exits with status 0 and prints note id.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show \"example.md\" --id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0   ]]\n  [[ \"${output}\" ==   \"1\" ]]\n}\n\n# `show <id> --id` ############################################################\n\n@test \"'show <id> --id' exits with status 0 and prints note id.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show 1 --id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0   ]]\n  [[ \"${output}\" ==   \"1\" ]]\n}\n\n# `show <path> --id` ##########################################################\n\n@test \"'show <path> --id' exits with status 0 and prints note id.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show \"${NB_DIR}/home/example.md\" --id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0   ]]\n  [[ \"${output}\" ==   \"1\" ]]\n}\n\n# `show <title> --id` #########################################################\n\n@test \"'show <title> --id' exits with status 0 and prints note id.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show \"Example Title\" --id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0   ]]\n  [[ \"${output}\" ==   \"1\" ]]\n}\n\n# encrypted ###################################################################\n\n@test \"'show' with encrypted file show properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"# Encrypted File Content\" --encrypt --password=example\n  }\n\n  run \"${_NB}\" show 1 --password=example --dump\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                         ]]\n  [[ \"${output}\" =~   Encrypted\\ File\\ Content  ]]\n}\n\n# `show <id> --filename` ######################################################\n\n@test \"'show <id> --filename' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show 1 --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n@test \"'show <id> --basename' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" show 1 --basename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n# `show <id> --title` #########################################################\n\n@test \"'show <id> --title' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show 1 --title\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0               ]]\n  [[ \"${output}\" ==   \"Example Title\" ]]\n}\n\n# `show <id> --indicators` ####################################################\n\n@test \"'show <id> --indicators' exits with status 0 and prints includes pinned indicator.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.bookmark.md\" --content \"<https://example.test>\"\n    \"${_NB}\" pin 1\n  }\n\n  run \"${_NB}\" show 1 --indicators\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0   ]]\n  [[    \"${output}\" =~  📌  ]]\n  [[    \"${output}\" =~  🔖  ]]\n  [[ !  \"${output}\" =~  🔒  ]]\n}\n\n@test \"'show <id> --indicators' exits with status 0 and prints bookmark indicator.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.bookmark.md\" --content \"<https://example.test>\"\n  }\n\n  run \"${_NB}\" show 1 --indicators\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0   ]]\n  [[ !  \"${output}\" =~  📌  ]]\n  [[    \"${output}\" =~  🔖  ]]\n  [[ !  \"${output}\" =~  🔒  ]]\n}\n\n@test \"'show <id> --indicators' exits with status 0 and prints encrypted indicator.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --encrypt --password=password\n  }\n\n  run \"${_NB}\" show 1 --indicators\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0   ]]\n  [[ !  \"${output}\" =~  📌  ]]\n  [[ !  \"${output}\" =~  🔖  ]]\n  [[    \"${output}\" =~  🔒  ]]\n}\n\n@test \"'show <id> --indicators' exits with status 0 and prints encrypted bookmark indicators.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.bookmark.md\"    \\\n      --content \"<https://example.test>\"  \\\n      --encrypt --password=password\n  }\n\n  run \"${_NB}\" show 1 --indicators\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0   ]]\n  [[ !  \"${output}\" =~  📌  ]]\n  [[    \"${output}\" =~  🔖  ]]\n  [[    \"${output}\" =~  🔒  ]]\n}\n\n# `show <id> --added` #########################################################\n\n@test \"'show <id> --added' exits with status 0 and prints the added timestamp.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show 1 --added\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                 ]]\n  [[ \"${output}\" =~   [0-9]{4}-[0-9]{2} ]]\n}\n\n@test \"'show <id> -a' exits with status 0 and prints the added timestamp.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n  }\n\n  run \"${_NB}\" show 1 -a\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                 ]]\n  [[ \"${output}\" =~   [0-9]{4}-[0-9]{2} ]]\n}\n\n# `show <id> --updated` #######################################################\n\n@test \"'show <id> --updated' exits with status 0 and prints the updated timestamp.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n\n    _added=\"$(\"${_NB}\" show 1 --added)\"\n\n    run \"${_NB}\" show 1 --added\n\n    [[ \"${output}\" == \"${_added}\"  ]]\n\n    sleep 1\n\n    \"${_NB}\" edit 1 --content \"More content.\"\n  }\n\n  run \"${_NB}\" show 1 --updated\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_added}: '%s'\\\\n\" \"${_added}\"\n\n  [[ \"${status}\" -eq  0                 ]]\n  [[ \"${output}\" =~   [0-9]{4}-[0-9]{2} ]]\n  [[ \"${output}\" !=   \"${_added}\"       ]]\n}\n\n@test \"'show <id> -u' exits with status 0 and prints the updated timestamp.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"Example Title\"\n\n    _added=\"$(\"${_NB}\" show 1 --added)\"\n\n    run \"${_NB}\" show 1 --added\n\n    [[ \"${output}\" == \"${_added}\"  ]]\n\n    sleep 1\n\n    \"${_NB}\" edit 1 --content \"More content.\"\n  }\n\n  run \"${_NB}\" show 1 -u\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \"\\${_added}: '%s'\\\\n\" \"${_added}\"\n\n  [[ \"${status}\" -eq  0                 ]]\n  [[ \"${output}\" =~   [0-9]{4}-[0-9]{2} ]]\n  [[ \"${output}\" !=   \"${_added}\"       ]]\n}\n\n# `show <id> --selector-id` ###################################################\n\n@test \"'show <id> --selector-id' exits with status 0 and prints the selector id.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show 42 --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0   ]]\n  [[ \"${output}\" =~   42  ]]\n}\n\n@test \"'show <id> --selector-id' exits with status 0 and prints the selector id without notebook.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show notebook:42 --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0   ]]\n  [[ \"${output}\" =~   42  ]]\n}\n\n@test \"'show <id> --selector-id' exits with status 0 and prints the selector filename.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show example.md --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0           ]]\n  [[ \"${output}\" =~   example.md  ]]\n}\n\n@test \"'show <id> --selector-id' exits with status 0 and prints the selector filename without notebook.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show notebook:example.md --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0           ]]\n  [[ \"${output}\" =~   example.md  ]]\n}\n\n@test \"'show <id> --selector-id' exits with status 0 and prints the selector title.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show Example\\ Title --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0               ]]\n  [[ \"${output}\" =~   Example\\ Title  ]]\n}\n\n@test \"'show <id> --selector-id' exits with status 0 and prints the selector title without notebook.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show notebook:Example\\ Title --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0               ]]\n  [[ \"${output}\" =~   Example\\ Title  ]]\n}\n\n@test \"'show <id> --selector-id' exits with status 0 and prints the selector path.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show /example/path --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0               ]]\n  [[ \"${output}\" =~   \\/example\\/path ]]\n}\n\n@test \"'show <id> --selector-id' exits with status 0 and prints the selector path without notebook.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show notebook:/example/path --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ \"${output}\" =~ \\/example\\/path ]]\n}\n\n@test \"'show <id> --selector-id' exits with status 0 and prints nothing when blank with notebook.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" show notebook: --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n  [[ -z \"${output:-}\"       ]]\n}\n\n# `show <id> --type` ##########################################################\n\n@test \"'show <id> --type' with note exits with status 0 and prints note type.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n  }\n\n  run \"${_NB}\" show 1 --type\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0     ]]\n  [[ \"${output}\" ==   \"md\"  ]]\n}\n\n@test \"'show <id> --type' with bookmark exits with status 0 and prints note type.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n  }\n\n  run \"${_NB}\" show 1 --type\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"bookmark.md\" ]]\n}\n\n@test \"'show <id> --type <extension>' exits with status 0 when note matches.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n  }\n\n  run \"${_NB}\" show 1 --type md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n  [[ -z \"${output:-}\"       ]]\n}\n\n@test \"'show <id> --type <extension>' exits with status 0 when bookmark matches.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n  }\n\n  run \"${_NB}\" show 1 --type bookmark.md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n  [[ -z \"${output:-}\"       ]]\n}\n\n@test \"'show <id> --type <extension>' exits with status 0 when bookmark matches one level.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n  }\n\n  run \"${_NB}\" show 1 --type md\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n  [[ -z \"${output:-}\"       ]]\n}\n\n@test \"'show <id> --type <type>' exits with status 0 when note matches.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n  }\n\n  run \"${_NB}\" show 1 --type text\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n  [[ -z \"${output:-}\"       ]]\n}\n\n@test \"'show <id> --type <type>' exits with status 0 when bookmark matches.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" bookmark \"${_BOOKMARK_URL}\"\n  }\n\n  run \"${_NB}\" show 1 --type bookmark\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0 ]]\n  [[ -z \"${output:-}\"       ]]\n}\n\n@test \"'show <id> --type <type>' exits with status 1 when no type match.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add\n  }\n\n  run \"${_NB}\" show 1 --type not-valid\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 1 ]]\n  [[ -z \"${output:-}\"       ]]\n}\n\n# `s <id>` #################################################################\n\n@test \"'s <id> --filename' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" s 1 --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n# `view <id>` #################################################################\n\n@test \"'view <id> --filename' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" view 1 --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n# `<id> show` alternative  ####################################################\n\n@test \"'<id> show --filename' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\"\n  }\n\n  run \"${_NB}\" 1 show --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n# `<scoped>`  #################################################################\n\n@test \"'show <scope>:<id> --filename' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"example.md\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" show one:example.md --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n@test \"'<scope>:<id> show --filename' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"example.md\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" one:example.md show --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n@test \"'<scoped>:show <id> --filename' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"example.md\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" one:show example.md --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n@test \"'<id> <scoped>:show --filename' exits with status 0 and prints note filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" one:add \"example.md\"\n\n    [[ -e \"${NB_DIR}/one/example.md\"  ]]\n  }\n\n  run \"${_NB}\" example.md one:show --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n@test \"'show <scope>:<id> --path' with invalid notebook and matching id in current notebook returns 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n  }\n\n  run \"${_NB}\" show example:1 --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                       ]]\n  [[ \"${output}\"    =~  \\!.*\\ Notebook\\ not\\ found:\\ .*example  ]]\n  [[ \"${#lines[@]}\" -eq 1                                       ]]\n}\n\n# `show <selector>` (notebook name) ###########################################\n\n@test \"'show <selector> --filename' with <selector> matching notebook name and note prints filename.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"example\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0             ]]\n  [[ \"${output}\" ==   \"example.md\"  ]]\n}\n\n@test \"'show <selector> --filename' with <selector> only matching notebook name prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"sample.md\" --title \"sample\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example --filename\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1             ]]\n  [[ \"${output:-}\"  =~  Not\\ found\\:  ]]\n}\n\n@test \"'show <selector> --path' with <selector> matching notebook name and note prints path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"example\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                            ]]\n  [[ \"${output}\" == \"${NB_DIR}/home/example.md\" ]]\n}\n\n@test \"'show <selector> --path' with <selector> only matching notebook name without colon prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"sample.md\" --title \"sample\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1             ]]\n  [[ \"${output:-}\"  =~  Not\\ found\\:  ]]\n}\n\n@test \"'show <selector> --path' with <selector> only matching notebook name with colon prints path.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"sample.md\" --title \"sample\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example: --path\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                   ]]\n  [[ \"${output}\" ==   \"${NB_DIR}/example\" ]]\n}\n\n@test \"'show <selector> --id' with <selector> matching notebook name and note prints id.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"example\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example.md --id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0   ]]\n  [[ \"${output}\" ==   \"1\" ]]\n}\n\n@test \"'show <selector> --id' with <selector> only matching notebook name prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"sample.md\" --title \"sample\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example --id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1             ]]\n  [[ \"${output:-}\"  =~  Not\\ found\\:  ]]\n}\n\n@test \"'show <selector> --title' with <selector> matching notebook name and note prints title.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"example\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example --title\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0         ]]\n  [[ \"${output}\" ==   \"example\" ]]\n}\n\n@test \"'show <selector> --title' with <selector> only matching notebook name prints message.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"sample.md\" --title \"sample\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example --title\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1             ]]\n  [[ \"${output:-}\"  =~  Not\\ found\\:  ]]\n}\n\n@test \"'show <selector> --selector-id' with <selector> matching notebook name and note prints selector-id.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"example.md\" --title \"example\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0         ]]\n  [[ \"${output}\" ==   \"example\" ]]\n}\n\n@test \"'show <selector> --selector-id' with <selector> only matching notebook name prints selector id.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"sample.md\" --title \"sample\"\n    \"${_NB}\" notebooks add \"example\"\n  }\n\n  run \"${_NB}\" show example --selector-id\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0         ]]\n  [[ \"${output}\" ==   \"example\" ]]\n}\n\n# help ########################################################################\n\n@test \"'help show' exits with status 0.\" {\n  run \"${_NB}\" help show\n\n  [[ ${status} -eq 0 ]]\n}\n\n@test \"'help show' prints help information.\" {\n  run \"${_NB}\" help show\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Usage.*\\:   ]]\n  [[ \"${lines[1]}\" =~ '  nb show' ]]\n}\n"
  },
  {
    "path": "test/status.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# error handling ##############################################################\n\n@test \"'status <not-valid>' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" status \"Sample Notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                                                     ]]\n  [[ \"${#lines[@]}\" -eq 1                                                     ]]\n\n  [[ \"${lines[0]}\"  =~  ^.*!.*\\ Notebook\\ not\\ found:\\ .*Sample\\ Notebook.*$  ]]\n}\n\n# aliases #####################################################################\n\n@test \"'st' exits with 0 and prints current notebook status information.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" st\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n\n  [[ \"${lines[0]}\"  ==  \"$(_color_primary \"home\")\"  ]]\n  [[ \"${lines[1]}\"  =~  [^-]----[^-]                ]]\n  [[ \"${lines[2]}\"  ==  \"status: unarchived\"        ]]\n  [[ \"${lines[3]}\"  ==  \"remote: none\"              ]]\n  [[ \"${lines[4]}\"  ==  \"git:    clean\"             ]]\n}\n\n@test \"'stat' exits with 0 and prints current notebook status information.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" stat\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n\n  [[ \"${lines[0]}\"  ==  \"$(_color_primary \"home\")\"  ]]\n  [[ \"${lines[1]}\"  =~  [^-]----[^-]                ]]\n  [[ \"${lines[2]}\"  ==  \"status: unarchived\"        ]]\n  [[ \"${lines[3]}\"  ==  \"remote: none\"              ]]\n  [[ \"${lines[4]}\"  ==  \"git:    clean\"             ]]\n}\n\n# status ######################################################################\n\n@test \"'status' exits with 0 and prints changes.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" archive\n\n    _setup_remote_repo\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    touch \"${NB_DIR}/home/Example New File.md\"\n\n    printf \"\\\\nNew content.\\\\n\" >> \"${NB_DIR}/home/Example File.md\"\n  }\n\n  run \"${_NB}\" status\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                       ]]\n\n  [[ \"${lines[0]}\"  ==  \"$(_color_primary \"home\")\"              ]]\n  [[ \"${lines[1]}\"  =~  [^-]----[^-]                            ]]\n  [[ \"${lines[2]}\"  ==  \"status: archived\"                      ]]\n  [[ \"${lines[3]}\"  ==  \"remote: ${_GIT_REMOTE_URL} (master)\"   ]]\n  [[ \"${lines[4]}\"  ==  \"git:    dirty\"                         ]]\n  [[ \"${lines[5]}\"  ==  \"changes\"                               ]]\n  [[ \"${lines[6]}\"  =~  [^-]-------[^-]                         ]]\n  [[ \"${lines[7]}\"  =~  \\ M\\ \\\"Example\\ File\\.md\\\"              ]]\n  [[ \"${lines[8]}\"  =~  \\?\\?\\ \\\"Example\\ New\\ File\\.md\\\"        ]]\n}\n\n@test \"'status <notebook>' exits with 0 and prints status information for <notebook>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" status \"Example Notebook\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                       ]]\n\n  [[ \"${lines[0]}\"  ==  \"$(_color_primary \"Example Notebook\")\"  ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------[^-]                ]]\n  [[ \"${lines[2]}\"  ==  \"status: unarchived\"                    ]]\n  [[ \"${lines[3]}\"  ==  \"remote: none\"                          ]]\n  [[ \"${lines[4]}\"  ==  \"git:    clean\"                         ]]\n}\n\n@test \"'status' exits with 0 and prints current notebook status information.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" status\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                           ]]\n\n  [[ \"${lines[0]}\"  ==  \"$(_color_primary \"home\")\"  ]]\n  [[ \"${lines[1]}\"  =~  [^-]----[^-]                ]]\n  [[ \"${lines[2]}\"  ==  \"status: unarchived\"        ]]\n  [[ \"${lines[3]}\"  ==  \"remote: none\"              ]]\n  [[ \"${lines[4]}\"  ==  \"git:    clean\"             ]]\n}\n\n# help ########################################################################\n\n@test \"'help status' exits with 0 and prints help information.\" {\n  run \"${_NB}\" help status\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0               ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:       ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ status  ]]\n}\n"
  },
  {
    "path": "test/subcommands.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'subcommands' exits with 0 and prints subcommands.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" subcommands\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0            ]]\n  [[ \"${output}\" =~ \"bookmark\"  ]]\n  [[ \"${output}\" =~ \"status\"    ]]\n}\n"
  },
  {
    "path": "test/sync-branches.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031\n\nload test_helper\n\n@test \"'sync' only fetches select branches.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n    # Example Notebook\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                   ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"  ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n\n    # Sample Notebook\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    diff                                                  \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)  \\\n      <(printf \"* master\\\\n\")\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    [[ \"$(\"${_NB}\" remote)\" =~ ${_GIT_REMOTE_URL}\\ \\(sample-notebook\\)  ]]\n\n    diff                                                  \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote     \\\n          --heads \"${_GIT_REMOTE_URL}\"                    \\\n          | sed \"s/.*\\///g\" || :)                         \\\n      <(printf \"master\\\\nsample-notebook\\\\n\")\n\n    diff                                                  \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all) \\\n      <(printf \"* master\\\\n  remotes/origin/HEAD -> origin/master\\\\n  remotes/origin/master\\\\n\")\n\n    printf \"Sample Notebook Branches: \\\\n\"\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n\n    diff                                                  \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)  \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    # Demo Notebook\n\n    \"${_NB}\" notebooks add \"Demo Notebook\"\n    \"${_NB}\" notebooks use \"Demo Notebook\"\n\n    \"${_NB}\" add \"Demo File.md\" --content \"Demo content.\"\n\n    diff                                                  \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)    \\\n      <(printf \"* master\\\\n\")\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    [[ \"$(\"${_NB}\" remote)\" =~ ${_GIT_REMOTE_URL}\\ \\(demo-notebook\\)  ]]\n\n    diff                                                  \\\n      <(git -C \"${NB_DIR}/Example Notebook\" ls-remote     \\\n          --heads \"${_GIT_REMOTE_URL}\"                    \\\n          | sed \"s/.*\\///g\" || :)                         \\\n      <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n    diff                                                  \\\n      <(git -C \"${NB_DIR}/Example Notebook\" branch --all) \\\n      <(printf \"* master\\\\n  remotes/origin/HEAD -> origin/master\\\\n  remotes/origin/master\\\\n\")\n\n    printf \"Sample Notebook Branches: \\\\n\"\n    git -C \"${NB_DIR}/Sample Notebook\" branch --all\n\n    diff                                                  \\\n      <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)  \\\n      <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n    printf \"Demo Notebook Branches: \\\\n\"\n    git -C \"${NB_DIR}/Demo Notebook\" branch --all\n\n    diff                                                  \\\n      <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)    \\\n      <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n  }\n\n  # Sample Notebook\n\n  run \"${_NB}\" Sample\\ Notebook:sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Sample\\ Notebook.*\\.\\.\\..*Done!   ]]\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote     \\\n        --heads \"${_GIT_REMOTE_URL}\"                    \\\n        | sed \"s/.*\\///g\" || :)                         \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all) \\\n    <(printf \"* master\\\\n  remotes/origin/HEAD -> origin/master\\\\n  remotes/origin/master\\\\n\")\n\n  printf \"Sample Notebook Branches: \\\\n\"\n  git -C \"${NB_DIR}/Sample Notebook\" branch --all\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)  \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n  printf \"Demo Notebook Branches: \\\\n\"\n  git -C \"${NB_DIR}/Demo Notebook\" branch --all\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)    \\\n    <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n  # Example Notebook\n\n  run \"${_NB}\" Example\\ Notebook:sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Example\\ Notebook.*\\.\\.\\..*Done!  ]]\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote     \\\n        --heads \"${_GIT_REMOTE_URL}\"                    \\\n        | sed \"s/.*\\///g\" || :)                         \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all) \\\n    <(printf \"* master\\\\n  remotes/origin/HEAD -> origin/master\\\\n  remotes/origin/master\\\\n\")\n\n  printf \"Sample Notebook Branches: \\\\n\"\n  git -C \"${NB_DIR}/Sample Notebook\" branch --all\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)  \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n  printf \"Demo Notebook Branches: \\\\n\"\n  git -C \"${NB_DIR}/Demo Notebook\" branch --all\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)    \\\n    <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n\n  # Demo Notebook\n\n  run \"${_NB}\" Demo\\ Notebook:sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Demo\\ Notebook.*\\.\\.\\..*Done!     ]]\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote     \\\n        --heads \"${_GIT_REMOTE_URL}\"                    \\\n        | sed \"s/.*\\///g\" || :)                         \\\n    <(printf \"demo-notebook\\\\nmaster\\\\nsample-notebook\\\\n\")\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Example Notebook\" branch --all) \\\n    <(printf \"* master\\\\n  remotes/origin/HEAD -> origin/master\\\\n  remotes/origin/master\\\\n\")\n\n  printf \"Sample Notebook Branches: \\\\n\"\n  git -C \"${NB_DIR}/Sample Notebook\" branch --all\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Sample Notebook\" branch --all)  \\\n    <(printf \"* sample-notebook\\\\n  remotes/origin/sample-notebook\\\\n\")\n\n  printf \"Demo Notebook Branches: \\\\n\"\n  git -C \"${NB_DIR}/Demo Notebook\" branch --all\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR}/Demo Notebook\" branch --all)    \\\n    <(printf \"* demo-notebook\\\\n  remotes/origin/demo-notebook\\\\n\")\n}\n\n@test \"'sync' with unrelated histories displays prompt and merges with existing.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                   ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"  ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    [[ \"$(\"${_NB}\" remote)\" =~ ${_GIT_REMOTE_URL}\\ \\(sample-notebook\\) ]]\n\n    \"${_NB}\" git branch -m \"master\"\n\n    [[ \"$(\"${_NB}\" remote)\" =~ ${_GIT_REMOTE_URL}\\ \\(master\\) ]]\n  }\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}1${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Sample\\ Notebook.*\\.\\.\\.              ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ has\\ existing\\ history:\\ .*master ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Merge\\ and\\ sync\\ with\\ the\\ existing\\ remote\\ branch\\:\\ .*master  ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*\\[.*2.*\\].*\\ Merge\\ and\\ sync\\ with\\ a\\ different\\ existing\\ remote\\ branch\\.   ]]\n  [[ \"${lines[5]}\"  =~  \\\n.*\\[.*3.*\\].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.                ]]\n  [[ \"${lines[6]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[7]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}           ]]\n  [[ \"${lines[8]}\"  =~  Remote\\ removed.                                  ]]\n  [[ \"${lines[9]}\"  =~  [^-]---------------[^-]                           ]]\n  [[ \"${lines[10]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)                  ]]\n  [[ \"${lines[11]}\" =~  Done!                                             ]]\n\n  diff                                                            \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n    <(printf \"master\\\\n\")\n}\n\n@test \"'sync' with unrelated histories displays prompt and creates new orphan.\" {\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n    \"${_NB}\" notebooks rename \"home\" \"Example Notebook\"\n\n    [[ !  -e \"${NB_DIR}/home\"                   ]]\n    [[    -d \"${NB_DIR}/Example Notebook/.git\"  ]]\n\n    \"${_NB}\" add \"Example File.md\" --content \"Example content.\"\n\n    \"${_NB}\" sync\n\n    \"${_NB}\" notebooks add \"Sample Notebook\"\n    \"${_NB}\" notebooks use \"Sample Notebook\"\n\n    \"${_NB}\" add \"Sample File.md\" --content \"Sample content.\"\n\n    \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n    [[ \"$(\"${_NB}\" remote)\" =~ ${_GIT_REMOTE_URL}\\ \\(sample-notebook\\) ]]\n\n    \"${_NB}\" git branch -m \"master\"\n\n    [[ \"$(\"${_NB}\" remote)\" =~ ${_GIT_REMOTE_URL}\\ \\(master\\) ]]\n  }\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0 ]]\n\n  [[ \"${lines[0]}\"  =~  Syncing:\\ .*Sample\\ Notebook.*\\.\\.\\.              ]]\n  [[ \"${lines[1]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[2]}\"  =~  Remote\\ branch\\ has\\ existing\\ history:\\ .*master ]]\n  [[ \"${lines[3]}\"  =~  \\\n.*\\[.*1.*\\].*\\ Merge\\ and\\ sync\\ with\\ the\\ existing\\ remote\\ branch\\:\\ .*master  ]]\n  [[ \"${lines[4]}\"  =~  \\\n.*\\[.*2.*\\].*\\ Merge\\ and\\ sync\\ with\\ a\\ different\\ existing\\ remote\\ branch\\.   ]]\n  [[ \"${lines[5]}\"  =~  \\\n.*\\[.*3.*\\].*\\ Sync\\ as\\ a\\ new\\ orphan\\ branch\\ on\\ the\\ remote\\.                ]]\n  [[ \"${lines[6]}\"  =~  [^-]------------------------------[^-]            ]]\n  [[ \"${lines[7]}\"  =~  \\\nPress\\ .*enter.*\\ to\\ use\\ the\\ selected\\ name,\\ .*type.*\\ a\\             ]]\n  [[ \"${lines[7]}\"  =~  \\\nname,\\ .*type.*\\ a\\ new\\ name,\\ or\\ press\\ .*q.*\\ to\\ quit\\.              ]]\n  [[ \"${lines[8]}\"  =~  [^-]--------------[^-]                            ]]\n  [[ \"${lines[9]}\"  =~  Removing\\ remote:\\ .*${_GIT_REMOTE_URL}           ]]\n  [[ \"${lines[10]}\" =~  Remote\\ removed.                                  ]]\n  [[ \"${lines[11]}\" =~  [^-]---------------[^-]                           ]]\n  [[ \"${lines[12]}\" =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*sample-notebook-1.*\\)       ]]\n  [[ \"${lines[13]}\" =~  Done!                                             ]]\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  diff                                              \\\n    <(git -C \"${NB_DIR}/Example Notebook\" ls-remote \\\n        --heads \"${_GIT_REMOTE_URL}\"                \\\n        | sed \"s/.*\\///g\" || :)                     \\\n    <(printf \"master\\\\nsample-notebook\\\\nsample-notebook-1\\\\n\")\n}\n\n@test \"'remote' and 'sync' with multiple notebooks displays prompts, updates configuration, and syncs successfully.\" {\n  # set up remote\n\n  _setup_remote_repo\n\n  diff                                                            \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n    <(printf \"master\\\\n\")\n\n  # configure locations for clones\n\n  export NB_DIR_1=\"${_TMP_DIR}/NB_DIR_1\"\n  export NB_DIR_2=\"${_TMP_DIR}/NB_DIR_2\"\n  export NB_DIR_3=\"${_TMP_DIR}/NB_DIR_3\"\n\n  # create $NB_DIR_1 and home notebook\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  \"${_NB}\" init\n\n  diff                                                            \\\n    <(git -C \"${NB_DIR_1}/home\" rev-parse --abbrev-ref HEAD)      \\\n    <(printf \"master\\\\n\")\n\n  \"${_NB}\" add  \"Home 1 File One.md\"  \\\n    --title     \"Home 1 Title One\"    \\\n    --content   \"Home 1 content one.\"\n\n  [[    -f \"${NB_DIR_1}/home/Home 1 File One.md\"                  ]]\n\n  # create notebook\n\n  # \"${_NB}\" notebooks add \"Example Notebook\"\n\n  # diff                                                                    \\\n  #   <(git -C \"${NB_DIR_1}/Example Notebook\" rev-parse --abbrev-ref HEAD)  \\\n  #   <(printf \"master\\\\n\")\n\n  # \"${_NB}\" use \"Example Notebook\"\n\n  # \"${_NB}\" add  \"Example 1 File One.md\" \\\n  #   --title     \"Example 1 Title One\"   \\\n  #   --content   \"Example 1 content one.\"\n\n  # [[    -f \"${NB_DIR_1}/Example Notebook/Example 1 File One.md\"   ]]\n\n  # create notebook\n\n  # \"${_NB}\" notebooks add \"Sample Notebook\"\n\n  # diff                                                                    \\\n  #   <(git -C \"${NB_DIR_1}/Sample Notebook\" rev-parse --abbrev-ref HEAD)   \\\n  #   <(printf \"master\\\\n\")\n\n  # \"${_NB}\" use \"Sample Notebook\"\n\n  # \"${_NB}\" add  \"Sample 1 File One.md\"  \\\n  #   --title     \"Sample 1 Title One\"    \\\n  #   --content   \"Sample 1 content one.\"\n\n  # [[    -f \"${NB_DIR_1}/Sample Notebook/Sample 1 File One.md\"     ]]\n\n  # set \"home\" notebook remote\n\n  \"${_NB}\" use \"home\"\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                         ]]\n\n  [[ \"${lines[0]}\"  =~  Adding\\ remote\\ to:\\ .*home               ]]\n  [[ \"${lines[1]}\"  =~  [^-]----------------------[^-]            ]]\n  [[ \"${lines[2]}\"  =~  URL:\\ \\ \\ \\ .*${_GIT_REMOTE_URL}          ]]\n  [[ \"${lines[3]}\"  =~  Branch:\\ .*master                         ]]\n  [[ \"${lines[4]}\"  =~  [^-]--------------[^-]                    ]]\n  [[ \"${lines[5]}\"  =~  \\\nRemote\\ set\\ to:\\ .*${_GIT_REMOTE_URL}.*\\ \\(.*master.*\\)          ]]\n\n  # sync \"home\" to remote\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                         ]]\n\n  diff                                                            \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n    <(printf \"master\\\\n\")\n\n  diff                                      \\\n    <(git -C \"${NB_DIR_1}/home\" ls-remote   \\\n        --heads \"${_GIT_REMOTE_URL}\"        \\\n        | sed \"s/.*\\///g\" || :)             \\\n    <(printf \"master\\\\n\")\n\n  declare _nbdir_1_home_commit_hashes=()\n  _nbdir_1_home_commit_hashes=($(\n    git -C \"${NB_DIR_1}/home\" rev-list --all --full-history\n  ))\n\n  [[ \"${#_nbdir_1_home_commit_hashes[@]}\" == \"2\" ]]\n\n  # create $NB_DIR_2 by cloning remote\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n  diff                                                            \\\n    <(git -C \"${NB_DIR_2}/home\" rev-parse --abbrev-ref HEAD)      \\\n    <(printf \"master\\\\n\")\n\n  [[    -f \"${NB_DIR_2}/home/Home 1 File One.md\"                  ]]\n  [[ !  -f \"${NB_DIR_2}/Example Notebook/Example 1 File One.md\"   ]]\n  [[ !  -f \"${NB_DIR_2}/Sample Notebook/Sample 1 File One.md\"     ]]\n\n  declare _nbdir_2_home_commit_hashes=()\n  _nbdir_2_home_commit_hashes=($(\n    git -C \"${NB_DIR_2}/home\" rev-list --all --full-history\n  ))\n\n  [[ \"${#_nbdir_2_home_commit_hashes[@]}\" == \"2\" ]]\n\n  diff                                                            \\\n    <(printf \"%s\\\\n\" \"${_nbdir_1_home_commit_hashes[@]:-}\")       \\\n    <(printf \"%s\\\\n\" \"${_nbdir_2_home_commit_hashes[@]:-}\")\n\n  # initialize $NB_DIR_3\n\n  export NB_DIR=\"${NB_DIR_3}\"\n\n  \"${_NB}\" init\n\n  diff                                                            \\\n    <(git -C \"${NB_DIR_3}/home\" rev-parse --abbrev-ref HEAD)      \\\n    <(printf \"master\\\\n\")\n\n  \"${_NB}\" add  \"Home 3 File One.md\"  \\\n    --title     \"Home 3 Title One\"    \\\n    --content   \"Home 3 content one.\"\n\n  \"${_NB}\" add  \"Home 3 File Two.md\"  \\\n    --title     \"Home 3 Title Two\"    \\\n    --content   \"Home 3 content Two.\"\n\n  [[    -f \"${NB_DIR_3}/home/Home 3 File One.md\"                  ]]\n  [[ !  -f \"${NB_DIR_3}/home/Home 1 File One.md\"                  ]]\n\n  # declare _nbdir_3_home_commit_hashes_before_sync=()\n  # _nbdir_3_home_commit_hashes_before_sync=($(\n  #   git -C \"${NB_DIR_3}/home\" rev-list --all --full-history\n  # ))\n\n  # add remote\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                         ]]\n\n  # sync\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                         ]]\n\n  [[    -f \"${NB_DIR_3}/home/Home 3 File One.md\"                  ]]\n  [[    -f \"${NB_DIR_3}/home/Home 1 File One.md\"                  ]]\n\n  # verify rebased:\n\n  declare _nbdir_3_home_commit_hashes=()\n  _nbdir_3_home_commit_hashes=($(\n    git -C \"${NB_DIR_3}/home\" rev-list --all --full-history\n  ))\n\n  [[ \"${#_nbdir_3_home_commit_hashes[@]}\" == \"4\" ]]\n\n  diff                                                            \\\n    <(printf \"%s\\\\n\" \"${_nbdir_1_home_commit_hashes[0]:-}\")       \\\n    <(printf \"%s\\\\n\" \"${_nbdir_3_home_commit_hashes[2]:-}\")\n\n  diff                                                            \\\n    <(printf \"%s\\\\n\" \"${_nbdir_1_home_commit_hashes[1]:-}\")       \\\n    <(printf \"%s\\\\n\" \"${_nbdir_3_home_commit_hashes[3]:-}\")\n\n  diff                                                            \\\n    <(printf \"%s\\\\n\" \"${_nbdir_1_home_commit_hashes[1]:-}\")       \\\n    <(git -C \"${NB_DIR_3}/home\" rev-list --max-parents=0 HEAD)\n\n  diff                                                            \\\n    <(git -C \"${NB_DIR_1}/home\" rev-list --max-parents=0 HEAD)    \\\n    <(git -C \"${NB_DIR_3}/home\" rev-list --max-parents=0 HEAD)\n\n  # switch to $NB_DIR_1 and create new notebook\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  \"${_NB}\" notebooks add \"Example Notebook\"\n\n  diff                                                                    \\\n    <(git -C \"${NB_DIR_1}/Example Notebook\" rev-parse --abbrev-ref HEAD)  \\\n    <(printf \"master\\\\n\")\n\n  \"${_NB}\" use \"Example Notebook\"\n\n  \"${_NB}\" add  \"Example 1 File One.md\" \\\n    --title     \"Example 1 Title One\"   \\\n    --content   \"Example 1 content one.\"\n\n  [[    -f \"${NB_DIR_1}/Example Notebook/Example 1 File One.md\"     ]]\n\n  # set new notebook remote as orphan\n\n  run \"${_NB}\" remote add \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}3${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                                           ]]\n\n  git -C \"${NB_DIR_1}/Example Notebook\" ls-remote       \\\n          --heads \"${_GIT_REMOTE_URL}\"                  \\\n          | sed \"s/.*\\///g\"\n\n  diff                                                  \\\n    <(git -C \"${NB_DIR_1}/Example Notebook\" ls-remote   \\\n        --heads \"${_GIT_REMOTE_URL}\"                    \\\n        | sed \"s/.*\\///g\")                              \\\n    <(printf \"example-notebook\\\\nmaster\\\\n\")\n\n  # declare _nbdir_1_example_notebook_commit_hashes=()\n  # _nbdir_1_example_notebook_commit_hashes=($(\n  #   git -C \"${NB_DIR_1}/Example Notebook\" rev-list --all --full-history\n  # ))\n\n  # switch back to $NB_DIR_2\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  \"${_NB}\" notebooks add \"Example Clone Notebook\" \"${_GIT_REMOTE_URL}\" \"example-notebook\"\n\n  diff                                        \\\n    <(cd \"${NB_DIR_2}/Example Clone Notebook\" &&\n      git config --get remote.origin.url)     \\\n    <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n  diff                                        \\\n    <(cd \"${NB_DIR_2}/Example Clone Notebook\" &&\n      git rev-parse --abbrev-ref HEAD)        \\\n    <(printf \"example-notebook\\\\n\")\n\n  [[ -f \"${NB_DIR_2}/Example Clone Notebook/Example 1 File One.md\"  ]]\n}\n\n@test \"'sync' with different branch names displays prompts, updates local branch to match remote, and syncs successfully.\" {\n  {\n    # set up remote\n\n    _setup_remote_repo \"example-branch-name\"\n\n    diff                                                            \\\n      <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n          | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n      <(printf \"example-branch-name\\\\n\")\n\n    # configure locations for clones\n\n    export NB_DIR_1=\"${_TMP_DIR}/nbdir-1\"\n    export NB_DIR_2=\"${_TMP_DIR}/nbdir-2\"\n\n    # create $NB_DIR_1 and assign remote\n\n    export NB_DIR=\"${NB_DIR_1}\"\n\n    \"${_NB}\" init\n    \"${_NB}\" git remote add origin \"${_GIT_REMOTE_URL}\"\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR_1}/home\" rev-parse --abbrev-ref HEAD)      \\\n      <(printf \"master\\\\n\")\n\n    # create $NB_DIR_2 and assign remote\n\n    export NB_DIR=\"${NB_DIR_2}\"\n\n    \"${_NB}\" init\n    \"${_NB}\" git remote add origin \"${_GIT_REMOTE_URL}\"\n\n    diff                                                            \\\n      <(git -C \"${NB_DIR_2}/home\" rev-parse --abbrev-ref HEAD)      \\\n      <(printf \"master\\\\n\")\n\n    # create file in $NB_DIR_1\n\n    export NB_DIR=\"${NB_DIR_1}\"\n\n    NB_AUTO_SYNC=0 \"${_NB}\" add           \\\n      \"Example Folder/Example File.md\"    \\\n      --content \"Example content from 1.\"\n\n    [[    -f \"${NB_DIR_1:-}/home/Example Folder/Example File.md\"  ]]\n    [[ !  -f \"${NB_DIR_2:-}/home/Example Folder/Example File.md\"  ]]\n  }\n\n  run \"${_NB}\" sync  <<< \"y${_NEWLINE}1${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n  [[    \"${output}\"   =~  Syncing:\\ .*home.*...Done!              ]]\n\n  # $NB_DIR_1 default branch name is updated\n\n  diff                                                            \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n    <(printf \"example-branch-name\\\\n\")\n\n  diff                                                            \\\n    <(git -C \"${NB_DIR_1}/home\" rev-parse --abbrev-ref HEAD)      \\\n    <(printf \"example-branch-name\\\\n\")\n\n  diff                                                            \\\n    <(git -C \"${NB_DIR_2}/home\" rev-parse --abbrev-ref HEAD)      \\\n    <(printf \"master\\\\n\")\n\n\n  # file from $NB_DIR_1 is synced to remote, but not other clone\n\n  [[    -f \"${NB_DIR_1:-}/home/Example Folder/Example File.md\"    ]]\n  [[ !  -f \"${NB_DIR_2:-}/home/Example Folder/Example File.md\"    ]]\n\n  # switch to $NB_DIR_2 and sync\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync <<< \"y${_NEWLINE}1${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0                                       ]]\n  [[    \"${output}\"   =~  Syncing:\\ .*home.*...Done!              ]]\n\n  # $NB_DIR_2 default branch name is updated\n\n  diff                                                            \\\n    <(git ls-remote --symref \"${_GIT_REMOTE_URL}\" HEAD            \\\n        | awk '/^ref:/ {sub(/refs\\/heads\\//, \"\", $2); print $2}') \\\n    <(printf \"example-branch-name\\\\n\")\n\n  diff                                                            \\\n    <(git -C \"${NB_DIR_1}/home\" rev-parse --abbrev-ref HEAD)      \\\n    <(printf \"example-branch-name\\\\n\")\n\n  diff                                                            \\\n    <(git -C \"${NB_DIR_2}/home\" rev-parse --abbrev-ref HEAD)      \\\n    <(printf \"example-branch-name\\\\n\")\n\n  # file from $NB_DIR_1 is synced from remote to $NB_DIR_2\n\n  [[    -f \"${NB_DIR_1:-}/home/Example Folder/Example File.md\"    ]]\n  [[    -f \"${NB_DIR_2:-}/home/Example Folder/Example File.md\"    ]]\n}\n"
  },
  {
    "path": "test/sync-folders.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031\n\nload test_helper\n\n_setup_notebooks() {\n  _setup_remote_repo\n\n  export NB_DIR_1=\"${_TMP_DIR}/nbdir-1\"\n  export NB_DIR_2=\"${_TMP_DIR}/nbdir-2\"\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n  export NB_DIR=\"${NB_DIR_1}\"\n}\n\n# sync --all #################################################################\n\n@test \"'sync --all' with no local syncs global notebooks with a folder.\" {\n  export NB_AUTO_SYNC=0\n\n  {\n    _setup_notebooks\n\n    # global-remote\n\n    \"${_NB}\" notebooks add global-remote \"${_GIT_REMOTE_URL}\"\n\n    run \"${_NB}\" global-remote:add      \\\n      \"Example Folder/global-remote.md\" \\\n      --content \"Example content from global-remote.\"\n\n    [[ \"${status}\" -eq 0 ]]\n\n    # NB_DIR_1\n\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-no-remote.md\" ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/archived.md\"            ]]\n    [[   -f \"${NB_DIR_1}/global-remote/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/global-no-remote.md\"    ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-no-remote.md\" ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/example-archived.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-no-remote.md\"             ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/archived.md\"                     ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-no-remote.md\"             ]]\n\n    # global-no-remote\n\n    \"${_NB}\" notebooks add global-no-remote\n\n    run \"${_NB}\" global-no-remote:add       \\\n      \"Example Folder/global-no-remote.md\"  \\\n      --content \"Example content from global-no-remote.\"\n\n    [[ \"${status}\" -eq 0 ]]\n\n    # NB_DIR_1\n\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-no-remote.md\" ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/archived.md\"            ]]\n    [[   -f \"${NB_DIR_1}/global-remote/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/global-no-remote.md\"    ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-remote.md\"    ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-no-remote.md\" ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/example-archived.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-no-remote.md\"             ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/archived.md\"                     ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-no-remote.md\"             ]]\n\n    # example-archived\n\n    \"${_NB}\" notebooks add example-archived \"${_GIT_REMOTE_URL}\"\n    \"${_NB}\" notebooks archive example-archived\n    run \"${_NB}\" example-archived:add \\\n      \"Example Folder/archived.md\"    \\\n      --content \"Example content from example-archived.\"\n\n    [[ \"${status}\" -eq 0 ]]\n\n    # NB_DIR_1\n\n    [[   -f \"${NB_DIR_1}/example-archived/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-no-remote.md\" ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/archived.md\"            ]]\n    [[   -f \"${NB_DIR_1}/global-remote/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/global-no-remote.md\"    ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-remote.md\"    ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-no-remote.md\" ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/example-archived.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-no-remote.md\"             ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/archived.md\"                     ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-no-remote.md\"             ]]\n  }\n\n  # sync 1: send changes to remote\n  run \"${_NB}\" sync --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${output}\" =~ \\\n    Syncing:\\ .*global-remote.*....*home.*...Done!            ]]\n  [[ ! \"${output}\" =~ local                                   ]]\n  [[ ! \"${output}\" =~ archived                                ]]\n  [[ ! \"${output}\" =~ no-remote                               ]]\n\n  [[ \"${status}\" -eq 0                                        ]]\n\n  # sync 2: sync all again to get changes\n  run \"${_NB}\" sync --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${output}\" =~ \\\n    Syncing:\\ .*global-remote.*....*home.*...Done!            ]]\n  [[ ! \"${output}\" =~ local                                   ]]\n  [[ ! \"${output}\" =~ archived                                ]]\n  [[ ! \"${output}\" =~ no-remote                               ]]\n\n  [[ \"${status}\" -eq 0                                        ]]\n\n  # NB_DIR_1\n\n  [[   -f \"${NB_DIR_1}/example-archived/Example Folder/archived.md\"         ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-remote.md\"    ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-no-remote.md\" ]]\n\n  [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/archived.md\"            ]]\n  [[   -f \"${NB_DIR_1}/global-remote/Example Folder/global-remote.md\"       ]]\n  [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/global-no-remote.md\"    ]]\n\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/archived.md\"         ]]\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-remote.md\"    ]]\n  [[   -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-no-remote.md\" ]]\n\n  [[ ! -f \"${NB_DIR_1}/home/Example Folder/example-archived.md\"             ]]\n  [[   -f \"${NB_DIR_1}/home/Example Folder/global-remote.md\"                ]]\n  [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-no-remote.md\"             ]]\n\n  # NB_DIR_2\n\n  [[ ! -f \"${NB_DIR_2}/home/Example Folder/archived.md\"                     ]]\n  [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-remote.md\"                ]]\n  [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-no-remote.md\"             ]]\n}\n\n# local notebook ##############################################################\n\n@test \"'sync --all' with local syncs local and global notebooks with a folder.\" {\n  export NB_AUTO_SYNC=0\n\n  {\n    _setup_notebooks\n\n    # global-remote\n\n    \"${_NB}\" notebooks add global-remote \"${_GIT_REMOTE_URL}\"\n\n    run \"${_NB}\" global-remote:add      \\\n      \"Example Folder/global-remote.md\" \\\n      --content \"Example content from global-remote.\"\n\n    [[ \"${status}\" -eq 0 ]]\n\n    # NB_DIR_1\n\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-no-remote.md\" ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/local.md\"            ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/archived.md\"            ]]\n    [[   -f \"${NB_DIR_1}/global-remote/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/global-no-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/local.md\"               ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-no-remote.md\" ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/local.md\"            ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/example-archived.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-no-remote.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/local.md\"                        ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/archived.md\"                     ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-no-remote.md\"             ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/local.md\"                        ]]\n\n    # local\n\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/archived.md\"            ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/global-no-remote.md\"    ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/local.md\"               ]]\n\n    # global-no-remote\n\n    \"${_NB}\" notebooks add global-no-remote\n\n    run \"${_NB}\" global-no-remote:add       \\\n      \"Example Folder/global-no-remote.md\"  \\\n      --content \"Example content from global-no-remote.\"\n\n    [[ \"${status}\" -eq 0 ]]\n\n    # NB_DIR_1\n\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-no-remote.md\" ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/local.md\"            ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/archived.md\"            ]]\n    [[   -f \"${NB_DIR_1}/global-remote/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/global-no-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/local.md\"               ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-remote.md\"    ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-no-remote.md\" ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/local.md\"            ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/example-archived.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-no-remote.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/local.md\"                        ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/archived.md\"                     ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-no-remote.md\"             ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/local.md\"                        ]]\n\n    # local\n\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/archived.md\"            ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/global-no-remote.md\"    ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/local.md\"               ]]\n\n    # example-archived\n\n    \"${_NB}\" notebooks add example-archived \"${_GIT_REMOTE_URL}\"\n    \"${_NB}\" notebooks archive example-archived\n\n    run \"${_NB}\" example-archived:add \\\n      \"Example Folder/archived.md\"    \\\n      --content \"Example content from example-archived.\"\n\n    [[ \"${status}\" -eq 0 ]]\n\n    # NB_DIR_1\n\n    [[   -f \"${NB_DIR_1}/example-archived/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-no-remote.md\" ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/local.md\"            ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/archived.md\"            ]]\n    [[   -f \"${NB_DIR_1}/global-remote/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/global-no-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/local.md\"               ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-remote.md\"    ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-no-remote.md\" ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/local.md\"            ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/example-archived.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-no-remote.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/local.md\"                        ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/archived.md\"                     ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-no-remote.md\"             ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/local.md\"                        ]]\n\n    # local\n\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/archived.md\"            ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/global-no-remote.md\"    ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/local.md\"               ]]\n\n    run \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\" \"${_GIT_REMOTE_URL}\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\"            ]]\n\n    [[ ${status} -eq 0                                    ]]\n    [[ \"$(\"${_NB}\" remote --url)\" == \"${_GIT_REMOTE_URL}\" ]]\n\n    \"${_NB}\" notebooks current --local\n\n    run \"${_NB}\" add            \\\n      \"Example Folder/local.md\" \\\n      --content \"Example content from local.\"\n\n    [[ \"${status}\" -eq 0 ]]\n\n    # NB_DIR_1\n\n    [[   -f \"${NB_DIR_1}/example-archived/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-no-remote.md\" ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/local.md\"            ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/archived.md\"            ]]\n    [[   -f \"${NB_DIR_1}/global-remote/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/global-no-remote.md\"    ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/local.md\"               ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/archived.md\"         ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-remote.md\"    ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-no-remote.md\" ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/local.md\"            ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/example-archived.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-no-remote.md\"             ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/local.md\"                        ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/archived.md\"                     ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-remote.md\"                ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-no-remote.md\"             ]]\n    [[ ! -f \"${NB_DIR_2}/home/Example Folder/local.md\"                        ]]\n\n    # local\n\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/archived.md\"            ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/global-remote.md\"       ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/global-no-remote.md\"    ]]\n    [[   -f \"${_TMP_DIR}/example-local/Example Folder/local.md\"               ]]\n  }\n\n  # sync 1: send changes to remote\n  run \"${_NB}\" sync --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ! \"${output}\" =~ \\\n    Syncing:\\ .*local.*....*local.*....*global-remote.*....*home.*...Done!  ]]\n  [[   \"${output}\" =~ \\\n    Syncing:\\ .*local.*....*global-remote.*....*home.*...Done!              ]]\n\n  [[ ! \"${output}\" =~ archived  ]]\n  [[ ! \"${output}\" =~ no-remote ]]\n\n  [[ \"${status}\" -eq 0          ]]\n\n  # sync 2: sync all again to get changes\n  run \"${_NB}\" sync --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n\n  [[ ! \"${output}\" =~ \\\n    Syncing:\\ .*local.*....*local.*....*global-remote.*....*home.*...Done!  ]]\n  [[   \"${output}\" =~ \\\n    Syncing:\\ .*local.*....*global-remote.*....*home.*...Done!              ]]\n\n  [[ ! \"${output}\" =~ archived  ]]\n  [[ ! \"${output}\" =~ no-remote ]]\n\n  [[ \"${status}\" -eq 0          ]]\n\n  # NB_DIR_1\n\n  [[   -f \"${NB_DIR_1}/example-archived/Example Folder/archived.md\"         ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-remote.md\"    ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/global-no-remote.md\" ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/Example Folder/local.md\"            ]]\n\n  [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/archived.md\"            ]]\n  [[   -f \"${NB_DIR_1}/global-remote/Example Folder/global-remote.md\"       ]]\n  [[ ! -f \"${NB_DIR_1}/global-remote/Example Folder/global-no-remote.md\"    ]]\n  [[   -f \"${NB_DIR_1}/global-remote/Example Folder/local.md\"               ]]\n\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/archived.md\"         ]]\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-remote.md\"    ]]\n  [[   -f \"${NB_DIR_1}/global-no-remote/Example Folder/global-no-remote.md\" ]]\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/Example Folder/local.md\"            ]]\n\n  [[ ! -f \"${NB_DIR_1}/home/Example Folder/example-archived.md\"             ]]\n  [[   -f \"${NB_DIR_1}/home/Example Folder/global-remote.md\"                ]]\n  [[ ! -f \"${NB_DIR_1}/home/Example Folder/global-no-remote.md\"             ]]\n  [[   -f \"${NB_DIR_1}/home/Example Folder/local.md\"                        ]]\n\n  # NB_DIR_2\n\n  [[ ! -f \"${NB_DIR_2}/home/Example Folder/archived.md\"                     ]]\n  [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-remote.md\"                ]]\n  [[ ! -f \"${NB_DIR_2}/home/Example Folder/global-no-remote.md\"             ]]\n  [[ ! -f \"${NB_DIR_2}/home/Example Folder/local.md\"                        ]]\n\n  # local\n\n  [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/archived.md\"            ]]\n  [[   -f \"${_TMP_DIR}/example-local/Example Folder/global-remote.md\"       ]]\n  [[ ! -f \"${_TMP_DIR}/example-local/Example Folder/global-no-remote.md\"    ]]\n  [[   -f \"${_TMP_DIR}/example-local/Example Folder/local.md\"               ]]\n}\n\n@test \"'sync' succeeds with local notebook with a folder.\" {\n  {\n    _setup_notebooks\n\n    run \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n\n    run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n\n    printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n    printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n    [[ ${status} -eq 0                                    ]]\n    [[ \"$(\"${_NB}\" remote --url)\" == \"${_GIT_REMOTE_URL}\" ]]\n    [[ \"${output}\"                =~ Remote\\ set\\ to      ]]\n    [[ \"${output}\"                =~ ${_GIT_REMOTE_URL}   ]]\n\n    \"${_NB}\" notebooks current --local\n\n    run \"${_NB}\" add            \\\n      \"Example Folder/local.md\" \\\n      --content \"Example content from local.\"\n\n    [[ \"${status}\" -eq 0                                      ]]\n    [[ -f \"${_TMP_DIR}/example-local/Example Folder/local.md\" ]]\n    [[ ! -f \"${NB_DIR_1}/home/Example Folder/local.md\"        ]]\n  }\n\n  # sync 1: send changes to remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                                      ]]\n  [[ -f \"${_TMP_DIR}/example-local/Example Folder/local.md\" ]]\n  [[ ! -f \"${NB_DIR_1}/home/Example Folder/local.md\"        ]]\n\n  cd ..\n\n  \"${_NB}\" notebooks current --local || true\n\n  # sync 2: pull changes from remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0                                      ]]\n  [[ -f \"${_TMP_DIR}/example-local/Example Folder/local.md\" ]]\n  [[ -f \"${NB_DIR_1}/home/Example Folder/local.md\"          ]]\n}\n\n# sync ########################################################################\n\n@test \"'sync' succeeds when files are added and removed from two clones within a folder.\" {\n  # skip\n  {\n    _setup_notebooks\n    \"${_NB}\" add \"Example Folder/one.md\" --content \"Example content from 1.\"\n\n    export NB_DIR=\"${NB_DIR_2}\"\n    \"${_NB}\" add \"Example Folder/two.md\" --content \"Example content from 2.\"\n\n    export NB_DIR=\"${NB_DIR_1}\"\n  }\n\n  # sync 1: send changes to remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(1)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  diff                                                      \\\n    <(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/) \\\n    <(printf \"1\\\\n\")\n  diff                                                      \\\n    <(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/) \\\n    <(printf \"1\\\\n\")\n  diff                                                      \\\n    <(cat \"${NB_DIR_1}/home/Example Folder/.index\")         \\\n    <(printf \"one.md\\\\n\")\n  diff                                                      \\\n    <(cat \"${NB_DIR_2}/home/Example Folder/.index\")         \\\n    <(printf \"two.md\\\\n\")\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  # sync 2: pull changes from remote, rebase, send new changes back to remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(2)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  diff                                                      \\\n    <(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/) \\\n    <(printf \"1\\\\n\")\n  diff                                                      \\\n    <(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/) \\\n    <(printf \"2\\\\n\")\n  diff                                                      \\\n    <(cat \"${NB_DIR_1}/home/Example Folder/.index\")         \\\n    <(printf \"one.md\\\\n\")\n  diff                                                      \\\n    <(cat \"${NB_DIR_2}/home/Example Folder/.index\")         \\\n    <(printf \"one.md%stwo.md\\\\n\" \"${_NEWLINE}\")\n\n  # sync 3: pull changes from remote\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(3)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0                                                              ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 2                 ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 2                 ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \"one.md${_NEWLINE}two.md\" ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \"one.md${_NEWLINE}two.md\" ]]\n\n  # Add more notes to each clone\n\n  export NB_DIR=\"${NB_DIR_1}\"\n  run \"${_NB}\" add \"Example Folder/one-2.md\" --content \"Example content from 1.\"\n\n  export NB_DIR=\"${NB_DIR_2}\"\n  run \"${_NB}\" add \"Example Folder/two-2.md\" --content \"Example content from 2.\"\n\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 3 ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 3 ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \\\n        \"one.md${_NEWLINE}two.md${_NEWLINE}one-2.md\"                ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \\\n        \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md\"                ]]\n\n  # sync 4: send new changes to remote\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(4)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0                                              ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 3 ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 3 ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \\\n        \"one.md${_NEWLINE}two.md${_NEWLINE}one-2.md\"                ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \\\n        \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md\"                ]]\n\n  # sync 5: pull changes from remote, rebase, send new changes back to remote\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(5)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0                                                ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 4   ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 3   ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md\"                     ]]\n\n  # sync 6: pull changes from remote\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(6)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0                                                ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 4   ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 4   ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md\"  ]]\n\n  # add more notes to and remove notes from each clone\n\n  export NB_DIR=\"${NB_DIR_1}\"\n  run \"${_NB}\" add \"Example Folder/one-3.md\" --content \"Example content from 1.\"\n  run \"${_NB}\" delete \"Example Folder/two.md\" --force\n\n  export NB_DIR=\"${NB_DIR_2}\"\n  run \"${_NB}\" add \"Example Folder/two-3.md\" --content \"Example content from 2.\"\n\n  printf \"(6.5)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 4 ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 5 ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \\\n    \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}one-3.md\"        ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \\\n    \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md\"  ]]\n\n  # sync 7: push changes to remote\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(7)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0                                              ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 4 ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 5 ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \\\n    \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}one-3.md\"        ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \\\n    \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md\"  ]]\n\n  # sync 8: pull changes from remote\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(8)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0                                              ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 5 ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 5 ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md${_NEWLINE}one-3.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md\"               ]]\n\n  # sync 9: push changes to remote\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(9)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0                                              ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 5 ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 5 ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md${_NEWLINE}one-3.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md\"               ]]\n\n  # sync 10: pull changes from remote\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(10)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/.index\"\n\n  [[ \"${status}\" -eq 0                                              ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count Example\\ Folder/)\" == 5 ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count Example\\ Folder/)\" == 5 ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md${_NEWLINE}one-3.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/Example Folder/.index\")\" == \\\n     \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md${_NEWLINE}one-3.md\"  ]]\n}\n\n@test \"'sync' succeeds when one file is edited on two clones within a folder.\" {\n  # skip\n\n  _setup_notebooks\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" add \"Example Folder/one.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  # ls -la \"${NB_DIR_2}\"\n\n  _sed_i 's/Line 4/Line n/' \"${NB_DIR_2}/home/Example Folder/one.md\"\n\n  run \"${_NB}\" &>/dev/null\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  _sed_i 's/Line 4/Line x/' \"${NB_DIR_1}/home/Example Folder/one.md\"\n\n  run \"${_NB}\" &>/dev/null\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  cat \"${NB_DIR_1}/home/Example Folder/one.md\"\n\n  [[ \"${status}\" -eq 0                                ]]\n  [[ \"${output}\" =~ Files\\ containing\\ conflicts\\:    ]]\n  [[ \"${output}\" =~ \\ \\ home\\:Example\\ Folder/one\\.md ]]\n\n  grep -q '<<<<<<< HEAD'        \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '\\- Line n List Item' \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '======='             \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '\\- Line x List Item' \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '>>>>>>>'             \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '\\[nb\\] Commit'       \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '\\- Line 5 List Item' \"${NB_DIR_1}/home/Example Folder/one.md\"\n}\n\n@test \"'sync' succeeds when multiple files are edited on two clones within a folder.\" {\n  # skip\n  _setup_notebooks\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" add \"Example Folder/one.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n\n  run \"${_NB}\" add \"Example Folder/two.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n\n  run \"${_NB}\" add \"Example Folder/three.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  # ls -la \"${NB_DIR_2}\"\n\n  _sed_i 's/Line 4/Line n/' \"${NB_DIR_2}/home/Example Folder/one.md\"\n  _sed_i 's/Line 4/Line n/' \"${NB_DIR_2}/home/Example Folder/two.md\"\n  _sed_i 's/Line 4/Line n/' \"${NB_DIR_2}/home/Example Folder/three.md\"\n\n  run \"${_NB}\" &>/dev/null\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  _sed_i 's/Line 4/Line x/' \"${NB_DIR_1}/home/Example Folder/one.md\"\n  _sed_i 's/Line 4/Line x/' \"${NB_DIR_1}/home/Example Folder/two.md\"\n  _sed_i 's/Line 4/Line x/' \"${NB_DIR_1}/home/Example Folder/three.md\"\n\n  run \"${_NB}\" &>/dev/null\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  cat \"${NB_DIR_1}/home/Example Folder/one.md\"\n\n  [[ \"${status}\" -eq 0                                  ]]\n  [[ \"${output}\" =~ Files\\ containing\\ conflicts\\:      ]]\n  [[ \"${output}\" =~ \\ \\ home\\:Example\\ Folder/one\\.md   ]]\n  [[ \"${output}\" =~ \\ \\ home\\:Example\\ Folder/two\\.md   ]]\n  [[ \"${output}\" =~ \\ \\ home\\:Example\\ Folder/three\\.md ]]\n\n  grep -q '<<<<<<< HEAD'        \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '\\- Line n List Item' \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '======='             \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '\\- Line x List Item' \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '>>>>>>>'             \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '\\[nb\\] Commit'       \"${NB_DIR_1}/home/Example Folder/one.md\"\n  grep -q '\\- Line 5 List Item' \"${NB_DIR_1}/home/Example Folder/one.md\"\n\n  grep -q '<<<<<<< HEAD'        \"${NB_DIR_1}/home/Example Folder/two.md\"\n  grep -q '\\- Line n List Item' \"${NB_DIR_1}/home/Example Folder/two.md\"\n  grep -q '======='             \"${NB_DIR_1}/home/Example Folder/two.md\"\n  grep -q '\\- Line x List Item' \"${NB_DIR_1}/home/Example Folder/two.md\"\n  grep -q '>>>>>>>'             \"${NB_DIR_1}/home/Example Folder/two.md\"\n  grep -q '\\[nb\\] Commit'       \"${NB_DIR_1}/home/Example Folder/two.md\"\n  grep -q '\\- Line 5 List Item' \"${NB_DIR_1}/home/Example Folder/two.md\"\n\n  grep -q '<<<<<<< HEAD'        \"${NB_DIR_1}/home/Example Folder/three.md\"\n  grep -q '\\- Line n List Item' \"${NB_DIR_1}/home/Example Folder/three.md\"\n  grep -q '======='             \"${NB_DIR_1}/home/Example Folder/three.md\"\n  grep -q '\\- Line x List Item' \"${NB_DIR_1}/home/Example Folder/three.md\"\n  grep -q '>>>>>>>'             \"${NB_DIR_1}/home/Example Folder/three.md\"\n  grep -q '\\[nb\\] Commit'       \"${NB_DIR_1}/home/Example Folder/three.md\"\n  grep -q '\\- Line 5 List Item' \"${NB_DIR_1}/home/Example Folder/three.md\"\n}\n\n@test \"'sync' succeeds when the same filename is added on two clones within a folder.\" {\n  # skip\n  _setup_notebooks\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" add \"Example Folder/one.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" add \"Example Folder/one.md\" --content \"Example different content from 2.\n\nThis content is unique to 2.\n\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"1:one.md\\\\n\"\n  cat \"${NB_DIR_1}/home/Example Folder/one.md\"\n  printf \"2:one.md\\\\n\"\n  cat \"${NB_DIR_2}/home/Example Folder/one.md\"\n\n  [[ \"${status}\" -eq 0                                ]]\n  [[ \"${output}\" =~ Files\\ containing\\ conflicts\\:    ]]\n  [[ \"${output}\" =~ \\ \\ home\\:Example\\ Folder/one\\.md ]]\n\n  grep -q '<<<<<<< HEAD'                        \"${NB_DIR_2}/home/Example Folder/one.md\"\n  grep -q 'Example content from 1.'             \"${NB_DIR_2}/home/Example Folder/one.md\"\n  grep -q '\\- Line 3 List Item'                 \"${NB_DIR_2}/home/Example Folder/one.md\"\n  grep -q '======='                             \"${NB_DIR_2}/home/Example Folder/one.md\"\n  grep -q 'Example different content'           \"${NB_DIR_2}/home/Example Folder/one.md\"\n  grep -q '>>>>>>>'                             \"${NB_DIR_2}/home/Example Folder/one.md\"\n  grep -q '\\[nb\\] Add\\: Example Folder/one.md'  \"${NB_DIR_2}/home/Example Folder/one.md\"\n}\n\n@test \"'sync' succeeds when an encrypted file is edited on two clones within a folder.\" {\n  # skip\n\n  _setup_notebooks\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" add \"Example Folder/one.md\"  \\\n    --encrypt --password password           \\\n    --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n  run \"${_NB}\" sync\n\n  [[ -e \"${NB_DIR_1}/home/Example Folder/one.md.enc\"                    ]]\n  [[ ! -e \"${NB_DIR_1}/home/Example Folder/one--conflicted-copy.md.enc\" ]]\n\n  [[ ! -e \"${NB_DIR_2}/home/Example Folder/one.md.enc\"                  ]]\n  [[ ! -e \"${NB_DIR_2}/home/Example Folder/one--conflicted-copy.md.enc\" ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  [[ ! \"$(\n          \"${_NB}\" show \"Example Folder/one.md.enc\" \\\n            --password password --print --no-color\n        )\" =~ Edit\\ content\\ from\\ 1\\.                    ]]\n  [[ ! \"$(\n          \"${_NB}\" show \"Example Folder/one.md.enc\" \\\n          --password password --print --no-color\n        )\" =~ Edit\\ content\\ from\\ 2\\.                    ]]\n\n  run \"${_NB}\" sync\n\n  [[ -e \"${NB_DIR_1}/home/Example Folder/one.md.enc\"                    ]]\n  [[ ! -e \"${NB_DIR_1}/home/Example Folder/one--conflicted-copy.md.enc\" ]]\n\n  [[ -e \"${NB_DIR_2}/home/Example Folder/one.md.enc\"                    ]]\n  [[ ! -e \"${NB_DIR_2}/home/Example Folder/one--conflicted-copy.md.enc\" ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/Example Folder/one.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR_2}/home/Example Folder/one.md.enc\")\"        ]]\n\n  ls -la \"${NB_DIR_2}\"\n\n  echo \"Edit content from 2.\" | \"${_NB}\" edit \"Example Folder/1\" --password password\n\n  run \"${_NB}\" sync\n\n  [[ -e \"${NB_DIR_1}/home/Example Folder/one.md.enc\"                    ]]\n  [[ ! -e \"${NB_DIR_1}/home/Example Folder/one--conflicted-copy.md.enc\" ]]\n\n  [[ -e \"${NB_DIR_2}/home/Example Folder/one.md.enc\"                    ]]\n  [[ ! -e \"${NB_DIR_2}/home/Example Folder/one--conflicted-copy.md.enc\" ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/Example Folder/one.md.enc\")\" != \\\n     \"$(_get_hash \"${NB_DIR_2}/home/Example Folder/one.md.enc\")\"        ]]\n\n  [[ \"$(\n        \"${_NB}\" show \"Example Folder/one.md.enc\" \\\n          --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 2\\.                      ]]\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  _before=\"$(\n    _get_hash \"${NB_DIR_1}/home/Example Folder/one.md.enc\"\n  )\"\n\n  echo \"Edit content from 1.\" | \"${_NB}\" edit \"Example Folder/1\" --password password\n\n  _after=\"$(\n    _get_hash \"${NB_DIR_1}/home/Example Folder/one.md.enc\"\n  )\"\n\n  printf \"\\${_before}:  %s\\\\n\" \"${_before}\"\n  printf \"\\${_after}:   %s\\\\n\" \"${_after}\"\n\n  [[ \"${_before}\" != \"${_after}\"      ]]\n\n  [[ \"$(\n        \"${_NB}\" show \"Example Folder/one.md.enc\" \\\n          --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 1\\.  ]]\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/Example Folder/one.md.enc\")\" != \\\n     \"$(_get_hash \"${NB_DIR_2}/home/Example Folder/one.md.enc\")\"            ]]\n\n  [[ \"${status}\" -eq 0                                                      ]]\n\n  [[ -e \"${NB_DIR_1}/home/Example Folder/one.md.enc\"                        ]]\n  [[ -e \"${NB_DIR_1}/home/Example Folder/one--conflicted-copy.md.enc\"       ]]\n\n  [[ -e \"${NB_DIR_2}/home/Example Folder/one.md.enc\"                        ]]\n  [[ ! -e \"${NB_DIR_2}/home/Example Folder/one--conflicted-copy.md.enc\"     ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/Example Folder/one.md.enc\")\" != \\\n     \"$(_get_hash \"${NB_DIR_2}/home/Example Folder/one.md.enc\")\"            ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/Example Folder/one--conflicted-copy.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR_2}/home/Example Folder/one.md.enc\")\"            ]]\n\n  [[ ${output} =~ Conflicted\\ copies\\ of\\ binary\\ files\\:                   ]]\n  [[ ${output} =~ \\ \\ home\\:Example\\ Folder/one\\-\\-conflicted-copy\\.md\\.enc ]]\n\n  [[ \"$(\n        \"${_NB}\" show \"Example Folder/one.md.enc\"                   \\\n          --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 1\\.                      ]]\n  [[ \"$(\n        \"${_NB}\" show \"Example Folder/one--conflicted-copy.md.enc\"  \\\n          --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 2\\.                      ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq 0 ]]\n\n  [[ -e \"${NB_DIR_1}/home/Example Folder/one.md.enc\"                              ]]\n  [[ -e \"${NB_DIR_1}/home/Example Folder/one--conflicted-copy.md.enc\"             ]]\n\n  [[ -e \"${NB_DIR_2}/home/Example Folder/one.md.enc\"                              ]]\n  [[ -e \"${NB_DIR_2}/home/Example Folder/one--conflicted-copy.md.enc\"             ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/Example Folder/one.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR_2}/home/Example Folder/one.md.enc\")\"                  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/Example Folder/one--conflicted-copy.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR_2}/home/Example Folder/one--conflicted-copy.md.enc\")\" ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/Example Folder/one.md.enc\")\" != \\\n     \"$(_get_hash \"${NB_DIR_1}/home/Example Folder/one--conflicted-copy.md.enc\")\" ]]\n\n  [[ \"$(\n        \"${_NB}\" show \"Example Folder/one.md.enc\"                   \\\n          --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 1\\.                                ]]\n  [[ \"$(\n        \"${_NB}\" show \"Example Folder/one--conflicted-copy.md.enc\"  \\\n          --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 2\\.                                ]]\n}\n\n@test \"'sync' notebooks exist after setup.\" {\n  _setup_notebooks\n\n  [[ -d \"${_GIT_REMOTE_PATH}\"     ]]\n  [[ \"${NB_DIR_1}\" == \"${NB_DIR}\" ]]\n  [[ -d \"${NB_DIR_1}/home/.git\"   ]]\n  [[ -d \"${NB_DIR_2}/home/.git\"   ]]\n}\n"
  },
  {
    "path": "test/sync.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031\n\nload test_helper\n\n_setup_notebooks() {\n  _setup_remote_repo\n\n  export NB_DIR_1=\"${_TMP_DIR}/nbdir-1\"\n  export NB_DIR_2=\"${_TMP_DIR}/nbdir-2\"\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n\n  export NB_DIR=\"${NB_DIR_1}\"\n}\n\n# help ########################################################################\n\n@test \"'help sync' exits with 0 and prints help information.\" {\n  run \"${_NB}\" help sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:     ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ sync  ]]\n}\n\n# .index ######################################################################\n\n# TODO\n# @test \"'sync' reconciles nested index.\" {\n#   # skip\n#   {\n#     _setup_remote_repo\n\n#     \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n#     \"${_NB}\" notebooks rename \"home\"  \"Notebook One\"\n#     \"${_NB}\" notebooks add            \"Notebook Two\" \"${_GIT_REMOTE_URL}\"\n\n#     [[ \"$(\"${_NB}\" notebooks current --name)\" == \"Notebook One\" ]]\n\n#     \"${_NB}\" add \"Notebook One:Folder/Example File One.md\" --content \"Example content one.\"\n#     \"${_NB}\" add \"Notebook One:Folder/Example File Two.md\" --content \"Example content two.\"\n\n#     echo \"Example content three.\" > \"${NB_DIR}/Notebook One/Folder/Example File Three.md\"\n\n#     \"${_NB}\" git add --all\n#     \"${_NB}\" git commit -am \"Example commit message.\"\n\n#     [[    -e \"${NB_DIR}/Notebook One/Folder/Example File One.md\"    ]]\n#     [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Two.md\"    ]]\n#     [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Three.md\"  ]]\n\n#     [[ !  -e \"${NB_DIR}/Notebook Two/Folder/Example File One.md\"    ]]\n#     [[ !  -e \"${NB_DIR}/Notebook Two/Folder/Example File Two.md\"    ]]\n#     [[ !  -e \"${NB_DIR}/Notebook Two/Folder/Example File Three.md\"  ]]\n\n#     diff                                            \\\n#       <(cat \"${NB_DIR}/Notebook One/Folder/.index\") \\\n#       <(cat <<HEREDOC\n# Example File One.md\n# Example File Two.md\n# HEREDOC\n\n#     \"${_NB}\" git push origin master\n# )\n\n#     diff                                            \\\n#       <(cat \"${NB_DIR}/Notebook Two/Folder/.index\") \\\n#       <(cat <<HEREDOC\n# HEREDOC\n# )\n#   }\n\n#   run \"${_NB}\" Notebook\\ Two:sync\n\n#   printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n#   printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n#   [[ \"${status}\" -eq  0                                           ]]\n#   [[ \"${output}\" =~   Syncing:\\ .*Notebook\\ Two.*...Done\\!        ]]\n\n#   [[    -e \"${NB_DIR}/Notebook One/Folder/Example File One.md\"    ]]\n#   [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Two.md\"    ]]\n#   [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Three.md\"  ]]\n\n#   [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File One.md\"    ]]\n#   [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File Two.md\"    ]]\n#   [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File Three.md\"  ]]\n\n#   diff                                            \\\n#     <(cat \"${NB_DIR}/Notebook One/Folder/.index\") \\\n#     <(cat <<HEREDOC\n# Example File One.md\n# Example File Two.md\n# HEREDOC\n# )\n\n#   diff                                            \\\n#     <(cat \"${NB_DIR}/Notebook Two/Folder/.index\") \\\n#     <(cat <<HEREDOC\n# Example File One.md\n# Example File Two.md\n# Example File Three.md\n# HEREDOC\n# )\n\n#   cd \"${NB_DIR}/Notebook Two\" || return 1\n#   while [[ -n \"$(git status --porcelain)\"   ]]\n#   do\n#     sleep 1\n#   done\n#   git log | grep -q '\\[nb\\] Reconcile Index'\n#   cd \"${_TMP_DIR}\"\n\n#   {\n#     \"${_NB}\" add \"Notebook One:Folder/Example File Four.md\" --content \"Example content four.\"\n\n#     [[    -e \"${NB_DIR}/Notebook One/Folder/Example File One.md\"    ]]\n#     [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Two.md\"    ]]\n#     [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Three.md\"  ]]\n#     [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Four.md\"   ]]\n\n#     [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File One.md\"    ]]\n#     [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File Two.md\"    ]]\n#     [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File Three.md\"  ]]\n#     [[ !  -e \"${NB_DIR}/Notebook Two/Folder/Example File Four.md\"   ]]\n\n#     \"${_NB}\" Notebook\\ One:sync\n#   }\n\n#   run \"${_NB}\" Notebook\\ Two:sync\n\n#   printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n#   printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n#   [[ \"${status}\" -eq  0                                             ]]\n#   [[ \"${output}\" =~   Syncing:\\ .*Notebook\\ Two.*...Done\\!          ]]\n\n#   [[    -e \"${NB_DIR}/Notebook One/Folder/Example File One.md\"      ]]\n#   [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Two.md\"      ]]\n#   [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Three.md\"    ]]\n#   [[    -e \"${NB_DIR}/Notebook One/Folder/Example File Four.md\"     ]]\n\n#   [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File One.md\"      ]]\n#   [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File Two.md\"      ]]\n#   [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File Three.md\"    ]]\n#   [[    -e \"${NB_DIR}/Notebook Two/Folder/Example File Four.md\"     ]]\n\n#   diff                                            \\\n#     <(cat \"${NB_DIR}/Notebook One/Folder/.index\") \\\n#     <(cat <<HEREDOC\n# Example File One.md\n# Example File Two.md\n# Example File Four.md\n# Example File Three.md\n# HEREDOC\n# )\n\n#   diff                                            \\\n#     <(cat \"${NB_DIR}/Notebook Two/Folder/.index\") \\\n#     <(cat <<HEREDOC\n# Example File One.md\n# Example File Two.md\n# Example File Four.md\n# Example File Three.md\n# HEREDOC\n# )\n# }\n\n@test \"'sync' reconciles root-level index.\" {\n  # skip\n  {\n    _setup_remote_repo\n\n    \"${_NB}\" init \"${_GIT_REMOTE_URL}\"\n    \"${_NB}\" notebooks rename \"home\"  \"Notebook One\"\n    \"${_NB}\" notebooks add            \"Notebook Two\" \"${_GIT_REMOTE_URL}\"\n\n    [[ \"$(\"${_NB}\" notebooks current --name)\" == \"Notebook One\" ]]\n\n    \"${_NB}\" add \"Notebook One:Example File One.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"Notebook One:Example File Two.md\" --content \"Example content two.\"\n\n    echo \"Example content three.\" > \"${NB_DIR}/Notebook One/Example File Three.md\"\n\n    \"${_NB}\" git add --all\n    \"${_NB}\" git commit -am \"Example commit message.\"\n\n    [[    -e \"${NB_DIR}/Notebook One/Example File One.md\"   ]]\n    [[    -e \"${NB_DIR}/Notebook One/Example File Two.md\"   ]]\n    [[    -e \"${NB_DIR}/Notebook One/Example File Three.md\" ]]\n\n    [[ !  -e \"${NB_DIR}/Notebook Two/Example File One.md\"   ]]\n    [[ !  -e \"${NB_DIR}/Notebook Two/Example File Two.md\"   ]]\n    [[ !  -e \"${NB_DIR}/Notebook Two/Example File Three.md\" ]]\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/Notebook One/.index\")  \\\n    <(cat <<HEREDOC\nExample File One.md\nExample File Two.md\nHEREDOC\n\n  \"${_NB}\" git push origin master\n)\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/Notebook Two/.index\")  \\\n    <(cat <<HEREDOC\nHEREDOC\n)\n  }\n\n  run \"${_NB}\" Notebook\\ Two:sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                                     ]]\n  [[ \"${output}\" =~   Syncing:\\ .*Notebook\\ Two.*...Done\\!  ]]\n\n  [[    -e \"${NB_DIR}/Notebook One/Example File One.md\"     ]]\n  [[    -e \"${NB_DIR}/Notebook One/Example File Two.md\"     ]]\n  [[    -e \"${NB_DIR}/Notebook One/Example File Three.md\"   ]]\n\n  [[    -e \"${NB_DIR}/Notebook Two/Example File One.md\"     ]]\n  [[    -e \"${NB_DIR}/Notebook Two/Example File Two.md\"     ]]\n  [[    -e \"${NB_DIR}/Notebook Two/Example File Three.md\"   ]]\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/Notebook One/.index\")  \\\n    <(cat <<HEREDOC\nExample File One.md\nExample File Two.md\nHEREDOC\n)\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/Notebook Two/.index\")  \\\n    <(cat <<HEREDOC\nExample File One.md\nExample File Two.md\nExample File Three.md\nHEREDOC\n)\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Notebook Two\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n\n  git -C \"${NB_DIR}/Notebook Two\" log | grep -q '\\[nb\\] Reconcile Index'\n\n  {\n    \"${_NB}\" add \"Notebook One:Example File Four.md\" --content \"Example content four.\"\n\n    [[    -e \"${NB_DIR}/Notebook One/Example File One.md\"   ]]\n    [[    -e \"${NB_DIR}/Notebook One/Example File Two.md\"   ]]\n    [[    -e \"${NB_DIR}/Notebook One/Example File Three.md\" ]]\n    [[    -e \"${NB_DIR}/Notebook One/Example File Four.md\"  ]]\n\n    [[    -e \"${NB_DIR}/Notebook Two/Example File One.md\"   ]]\n    [[    -e \"${NB_DIR}/Notebook Two/Example File Two.md\"   ]]\n    [[    -e \"${NB_DIR}/Notebook Two/Example File Three.md\" ]]\n    [[ !  -e \"${NB_DIR}/Notebook Two/Example File Four.md\"  ]]\n\n    \"${_NB}\" Notebook\\ One:sync\n  }\n\n  run \"${_NB}\" Notebook\\ Two:sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\" -eq  0                                     ]]\n  [[ \"${output}\" =~   Syncing:\\ .*Notebook\\ Two.*...Done\\!  ]]\n\n  [[    -e \"${NB_DIR}/Notebook One/Example File One.md\"     ]]\n  [[    -e \"${NB_DIR}/Notebook One/Example File Two.md\"     ]]\n  [[    -e \"${NB_DIR}/Notebook One/Example File Three.md\"   ]]\n  [[    -e \"${NB_DIR}/Notebook One/Example File Four.md\"    ]]\n\n  [[    -e \"${NB_DIR}/Notebook Two/Example File One.md\"     ]]\n  [[    -e \"${NB_DIR}/Notebook Two/Example File Two.md\"     ]]\n  [[    -e \"${NB_DIR}/Notebook Two/Example File Three.md\"   ]]\n  [[    -e \"${NB_DIR}/Notebook Two/Example File Four.md\"    ]]\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/Notebook One/.index\")  \\\n    <(cat <<HEREDOC\nExample File One.md\nExample File Two.md\nExample File Three.md\nExample File Four.md\nHEREDOC\n)\n\n  diff                                      \\\n    <(cat \"${NB_DIR}/Notebook Two/.index\")  \\\n    <(cat <<HEREDOC\nExample File One.md\nExample File Two.md\nExample File Three.md\nExample File Four.md\nHEREDOC\n)\n}\n\n# sync --all #################################################################\n\n@test \"'sync --all' with no local syncs global notebooks.\" {\n  export NB_AUTO_SYNC=0\n\n  {\n    _setup_notebooks\n\n    # global-remote\n\n    \"${_NB}\" notebooks add global-remote \"${_GIT_REMOTE_URL}\"\n\n    run \"${_NB}\" global-remote:add \"global-remote.md\" \\\n      --content \"Example content from global-remote.\"\n\n    [[ ${status} -eq 0                                          ]]\n\n    # NB_DIR_1\n\n    [[ ! -f \"${NB_DIR_1}/example-archived/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-no-remote.md\"  ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/archived.md\"             ]]\n    [[   -f \"${NB_DIR_1}/global-remote/global-remote.md\"        ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/global-no-remote.md\"     ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/global-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/global-no-remote.md\"  ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/example-archived.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-no-remote.md\"              ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/archived.md\"                      ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-no-remote.md\"              ]]\n\n    # global-no-remote\n\n    \"${_NB}\" notebooks add global-no-remote\n\n    run \"${_NB}\" global-no-remote:add \"global-no-remote.md\" \\\n      --content \"Example content from global-no-remote.\"\n\n    [[ ${status} -eq 0                                          ]]\n\n    # NB_DIR_1\n\n    [[ ! -f \"${NB_DIR_1}/example-archived/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-no-remote.md\"  ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/archived.md\"             ]]\n    [[   -f \"${NB_DIR_1}/global-remote/global-remote.md\"        ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/global-no-remote.md\"     ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/global-remote.md\"     ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/global-no-remote.md\"  ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/example-archived.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-no-remote.md\"              ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/archived.md\"                      ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-no-remote.md\"              ]]\n\n    # example-archived\n\n    \"${_NB}\" notebooks add example-archived \"${_GIT_REMOTE_URL}\"\n    \"${_NB}\" notebooks archive example-archived\n    run \"${_NB}\" example-archived:add \"archived.md\" \\\n      --content \"Example content from example-archived.\"\n\n    [[ ${status} -eq 0                                          ]]\n\n    # NB_DIR_1\n\n    [[   -f \"${NB_DIR_1}/example-archived/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-no-remote.md\"  ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/archived.md\"             ]]\n    [[   -f \"${NB_DIR_1}/global-remote/global-remote.md\"        ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/global-no-remote.md\"     ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/global-remote.md\"     ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/global-no-remote.md\"  ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/example-archived.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-no-remote.md\"              ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/archived.md\"                      ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-no-remote.md\"              ]]\n  }\n\n  # sync 1: send changes to remote\n  run \"${_NB}\" sync --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${output}\" =~ \\\n    Syncing:\\ .*global-remote.*....*home.*...Done!            ]]\n  [[ ! \"${output}\" =~ local                                   ]]\n  [[ ! \"${output}\" =~ archived                                ]]\n  [[ ! \"${output}\" =~ no-remote                               ]]\n\n  [[ ${status} -eq 0                                          ]]\n\n  # sync 2: sync all again to get changes\n  run \"${_NB}\" sync --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[   \"${output}\" =~ \\\n    Syncing:\\ .*global-remote.*....*home.*...Done!            ]]\n  [[ ! \"${output}\" =~ local                                   ]]\n  [[ ! \"${output}\" =~ archived                                ]]\n  [[ ! \"${output}\" =~ no-remote                               ]]\n\n  [[ ${status} -eq 0                                          ]]\n\n  # NB_DIR_1\n\n  [[   -f \"${NB_DIR_1}/example-archived/archived.md\"          ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/global-remote.md\"     ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/global-no-remote.md\"  ]]\n\n  [[ ! -f \"${NB_DIR_1}/global-remote/archived.md\"             ]]\n  [[   -f \"${NB_DIR_1}/global-remote/global-remote.md\"        ]]\n  [[ ! -f \"${NB_DIR_1}/global-remote/global-no-remote.md\"     ]]\n\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/archived.md\"          ]]\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/global-remote.md\"     ]]\n  [[   -f \"${NB_DIR_1}/global-no-remote/global-no-remote.md\"  ]]\n\n  [[ ! -f \"${NB_DIR_1}/home/example-archived.md\"              ]]\n  [[   -f \"${NB_DIR_1}/home/global-remote.md\"                 ]]\n  [[ ! -f \"${NB_DIR_1}/home/global-no-remote.md\"              ]]\n\n  # NB_DIR_2\n\n  [[ ! -f \"${NB_DIR_2}/home/archived.md\"                      ]]\n  [[ ! -f \"${NB_DIR_2}/home/global-remote.md\"                 ]]\n  [[ ! -f \"${NB_DIR_2}/home/global-no-remote.md\"              ]]\n}\n\n# local notebook ##############################################################\n\n@test \"'sync --all' with local syncs local and global notebooks.\" {\n  export NB_AUTO_SYNC=0\n\n  {\n    _setup_notebooks\n\n    # global-remote\n\n    \"${_NB}\" notebooks add global-remote \"${_GIT_REMOTE_URL}\"\n\n    run \"${_NB}\" global-remote:add \"global-remote.md\" \\\n      --content \"Example content from global-remote.\"\n\n    [[ ${status} -eq 0                                          ]]\n\n    # NB_DIR_1\n\n    [[ ! -f \"${NB_DIR_1}/example-archived/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-no-remote.md\"  ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/local.md\"             ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/archived.md\"             ]]\n    [[   -f \"${NB_DIR_1}/global-remote/global-remote.md\"        ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/global-no-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/local.md\"                ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/global-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/global-no-remote.md\"  ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/local.md\"             ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/example-archived.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-no-remote.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/local.md\"                         ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/archived.md\"                      ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-no-remote.md\"              ]]\n    [[ ! -f \"${NB_DIR_2}/home/local.md\"                         ]]\n\n    # local\n\n    [[ ! -f \"${_TMP_DIR}/example-local/archived.md\"             ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/global-remote.md\"        ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/global-no-remote.md\"     ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/local.md\"                ]]\n\n    # global-no-remote\n\n    \"${_NB}\" notebooks add global-no-remote\n\n    run \"${_NB}\" global-no-remote:add \"global-no-remote.md\" \\\n      --content \"Example content from global-no-remote.\"\n\n    [[ ${status} -eq 0                                          ]]\n\n    # NB_DIR_1\n\n    [[ ! -f \"${NB_DIR_1}/example-archived/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-no-remote.md\"  ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/local.md\"             ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/archived.md\"             ]]\n    [[   -f \"${NB_DIR_1}/global-remote/global-remote.md\"        ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/global-no-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/local.md\"                ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/global-remote.md\"     ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/global-no-remote.md\"  ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/local.md\"             ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/example-archived.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-no-remote.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/local.md\"                         ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/archived.md\"                      ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-no-remote.md\"              ]]\n    [[ ! -f \"${NB_DIR_2}/home/local.md\"                         ]]\n\n    # local\n\n    [[ ! -f \"${_TMP_DIR}/example-local/archived.md\"             ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/global-remote.md\"        ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/global-no-remote.md\"     ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/local.md\"                ]]\n\n    # example-archived\n\n    \"${_NB}\" notebooks add example-archived \"${_GIT_REMOTE_URL}\"\n    \"${_NB}\" notebooks archive example-archived\n\n    run \"${_NB}\" example-archived:add \"archived.md\" \\\n      --content \"Example content from example-archived.\"\n\n    [[ ${status} -eq 0                                          ]]\n\n    # NB_DIR_1\n\n    [[   -f \"${NB_DIR_1}/example-archived/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-no-remote.md\"  ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/local.md\"             ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/archived.md\"             ]]\n    [[   -f \"${NB_DIR_1}/global-remote/global-remote.md\"        ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/global-no-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/local.md\"                ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/global-remote.md\"     ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/global-no-remote.md\"  ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/local.md\"             ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/example-archived.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-no-remote.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/local.md\"                         ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/archived.md\"                      ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-no-remote.md\"              ]]\n    [[ ! -f \"${NB_DIR_2}/home/local.md\"                         ]]\n\n    # local\n\n    [[ ! -f \"${_TMP_DIR}/example-local/archived.md\"             ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/global-remote.md\"        ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/global-no-remote.md\"     ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/local.md\"                ]]\n\n    run \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\" \"${_GIT_REMOTE_URL}\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n\n    [[ ${status} -eq 0                                    ]]\n    [[ \"$(\"${_NB}\" remote --url)\" == \"${_GIT_REMOTE_URL}\" ]]\n\n    \"${_NB}\" notebooks current --local\n\n    run \"${_NB}\" add \"local.md\" --content \"Example content from local.\"\n\n    [[ ${status} -eq 0                                          ]]\n\n    # NB_DIR_1\n\n    [[   -f \"${NB_DIR_1}/example-archived/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/global-no-remote.md\"  ]]\n    [[ ! -f \"${NB_DIR_1}/example-archived/local.md\"             ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-remote/archived.md\"             ]]\n    [[   -f \"${NB_DIR_1}/global-remote/global-remote.md\"        ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/global-no-remote.md\"     ]]\n    [[ ! -f \"${NB_DIR_1}/global-remote/local.md\"                ]]\n\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/archived.md\"          ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/global-remote.md\"     ]]\n    [[   -f \"${NB_DIR_1}/global-no-remote/global-no-remote.md\"  ]]\n    [[ ! -f \"${NB_DIR_1}/global-no-remote/local.md\"             ]]\n\n    [[ ! -f \"${NB_DIR_1}/home/example-archived.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_1}/home/global-no-remote.md\"              ]]\n    [[ ! -f \"${NB_DIR_1}/home/local.md\"                         ]]\n\n    # NB_DIR_2\n\n    [[ ! -f \"${NB_DIR_2}/home/archived.md\"                      ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-remote.md\"                 ]]\n    [[ ! -f \"${NB_DIR_2}/home/global-no-remote.md\"              ]]\n    [[ ! -f \"${NB_DIR_2}/home/local.md\"                         ]]\n\n    # local\n\n    [[ ! -f \"${_TMP_DIR}/example-local/archived.md\"             ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/global-remote.md\"        ]]\n    [[ ! -f \"${_TMP_DIR}/example-local/global-no-remote.md\"     ]]\n    [[   -f \"${_TMP_DIR}/example-local/local.md\"                ]]\n  }\n\n  # sync 1: send changes to remote\n  run \"${_NB}\" sync --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ! \"${output}\" =~ \\\n    Syncing:\\ .*local.*....*local.*....*global-remote.*....*home.*...Done!  ]]\n  [[   \"${output}\" =~ \\\n    Syncing:\\ .*local.*....*global-remote.*....*home.*...Done!              ]]\n\n  [[ ! \"${output}\" =~ archived                                ]]\n  [[ ! \"${output}\" =~ no-remote                               ]]\n\n  [[ ${status} -eq 0                                          ]]\n\n  # sync 2: sync all again to get changes\n  run \"${_NB}\" sync --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n\n  [[ ! \"${output}\" =~ \\\n    Syncing:\\ .*local.*....*local.*....*global-remote.*....*home.*...Done!  ]]\n  [[   \"${output}\" =~ \\\n    Syncing:\\ .*local.*....*global-remote.*....*home.*...Done!              ]]\n\n  [[ ! \"${output}\" =~ archived                                ]]\n  [[ ! \"${output}\" =~ no-remote                               ]]\n\n  [[ ${status} -eq 0                                          ]]\n\n  # NB_DIR_1\n\n  [[   -f \"${NB_DIR_1}/example-archived/archived.md\"          ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/global-remote.md\"     ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/global-no-remote.md\"  ]]\n  [[ ! -f \"${NB_DIR_1}/example-archived/local.md\"             ]]\n\n  [[ ! -f \"${NB_DIR_1}/global-remote/archived.md\"             ]]\n  [[   -f \"${NB_DIR_1}/global-remote/global-remote.md\"        ]]\n  [[ ! -f \"${NB_DIR_1}/global-remote/global-no-remote.md\"     ]]\n  [[   -f \"${NB_DIR_1}/global-remote/local.md\"                ]]\n\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/archived.md\"          ]]\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/global-remote.md\"     ]]\n  [[   -f \"${NB_DIR_1}/global-no-remote/global-no-remote.md\"  ]]\n  [[ ! -f \"${NB_DIR_1}/global-no-remote/local.md\"             ]]\n\n  [[ ! -f \"${NB_DIR_1}/home/example-archived.md\"              ]]\n  [[   -f \"${NB_DIR_1}/home/global-remote.md\"                 ]]\n  [[ ! -f \"${NB_DIR_1}/home/global-no-remote.md\"              ]]\n  [[   -f \"${NB_DIR_1}/home/local.md\"                         ]]\n\n  # NB_DIR_2\n\n  [[ ! -f \"${NB_DIR_2}/home/archived.md\"                      ]]\n  [[ ! -f \"${NB_DIR_2}/home/global-remote.md\"                 ]]\n  [[ ! -f \"${NB_DIR_2}/home/global-no-remote.md\"              ]]\n  [[ ! -f \"${NB_DIR_2}/home/local.md\"                         ]]\n\n  # local\n\n  [[ ! -f \"${_TMP_DIR}/example-local/archived.md\"             ]]\n  [[   -f \"${_TMP_DIR}/example-local/global-remote.md\"        ]]\n  [[ ! -f \"${_TMP_DIR}/example-local/global-no-remote.md\"     ]]\n  [[   -f \"${_TMP_DIR}/example-local/local.md\"                ]]\n}\n\n@test \"'sync' succeeds with local notebook.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" notebooks init \"${_TMP_DIR}/example-local\"\n\n    cd \"${_TMP_DIR}/example-local\"\n\n    [[ \"$(pwd)\" == \"${_TMP_DIR}/example-local\" ]]\n\n    \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n    diff <(\"${_NB}\" remote --url) <(printf \"%s\\\\n\" \"${_GIT_REMOTE_URL}\")\n\n    \"${_NB}\" notebooks current --local\n\n    run \"${_NB}\" add \"local.md\" --content \"Example content from local.\"\n\n    [[    -f \"${_TMP_DIR}/example-local/local.md\" ]]\n    [[ !  -f \"${NB_DIR_1}/home/local.md\"          ]]\n  }\n\n  # sync 1: send changes to remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ -f \"${_TMP_DIR}/example-local/local.md\"  ]]\n  [[ ! -f \"${NB_DIR_1}/home/local.md\"         ]]\n\n  cd ..\n\n  \"${_NB}\" notebooks current --local || true\n\n  # sync 2: pull changes from remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                          ]]\n  [[ -f \"${_TMP_DIR}/example-local/local.md\"  ]]\n  [[ -f \"${NB_DIR_1}/home/local.md\"           ]]\n}\n\n# sync errors #################################################################\n\n@test \"'sync' returns error when notebook has no remote.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" remote remove <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" remote && return 1\n  }\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}:   '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:   '%s'\\\\n\" \"${output}\"\n  printf \"\\${lines[2]}: '%s'\\\\n\" \"${lines[2]}\"\n\n  [[ \"${lines[0]}\" =~ No\\ remote\\ configured  ]]\n  [[ \"${lines[1]}\" =~ Set\\ the\\ remote        ]]\n  [[ ${status} -eq 1                          ]]\n}\n\n@test \"'sync --all' returns error when no unarchived notebooks with remotes found.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" notebooks add example\n    \"${_NB}\" notebooks archive home\n    \"${_NB}\" remote remove <<< \"y${_NEWLINE}\"\n\n    \"${_NB}\" remote && return 1\n  }\n\n  run \"${_NB}\" sync --all\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ No\\ unarchived\\ notebooks ]]\n  [[ ${status} -eq 1                            ]]\n}\n\n# remote set && sync #########################################################\n\n@test \"'sync' fails with invalid remote.\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" remote remove <<< \"y${_NEWLINE}\"\n\n    [[ \"$(\"${_NB}\" remote 2>&1)\" =~ No\\ remote ]]\n\n    \"${_NB}\" add \"one.md\" --content \"Example content from 1.\"\n\n    [[    -f \"${NB_DIR_1}/home/one.md\"  ]]\n    [[ !  -f \"${NB_DIR_2}/home/one.md\"  ]]\n\n    \"${_NB}\" git remote add origin \"https://example.test/invalid.git\"\n\n    diff                        \\\n      <(\"${_NB}\" remote --url)  \\\n      <(printf \"%s\\\\n\" \"https://example.test/invalid.git\")\n  }\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 1                                   ]]\n  [[    \"${lines[0]}\" =~  Syncing                             ]]\n  [[    \"${lines[0]}\" =~  home                                ]]\n  [[    \"${lines[1]}\" =~  unable\\ to\\ access\\                 ]]\n  [[    \"${lines[1]}\" =~  https://example.test/invalid.git/   ]]\n  [[ !  \"${output}\"   =~  Done                                ]]\n}\n\n@test \"'sync' succeeds after 'remote set'\" {\n  {\n    _setup_notebooks\n\n    \"${_NB}\" remote remove <<< \"y${_NEWLINE}\"\n\n    [[ \"$(\"${_NB}\" remote 2>&1)\" =~ No\\ remote ]]\n\n    \"${_NB}\" add \"one.md\" --content \"Example content from 1.\"\n\n    [[    -f \"${NB_DIR_1}/home/one.md\"  ]]\n    [[ !  -f \"${NB_DIR_2}/home/one.md\"  ]]\n  }\n\n  run \"${_NB}\" remote set \"${_GIT_REMOTE_URL}\" <<< \"y${_NEWLINE}1${_NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${output}\" =~ Remote\\ set\\ to     ]]\n  [[ \"${output}\" =~ ${_GIT_REMOTE_URL}  ]]\n  [[ ${status} -eq 0                    ]]\n\n  # sync 1: send changes to remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Syncing:\\ .*home.*...Done! ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  # sync 2: pull changes from remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Syncing:\\ .*home.*...Done! ]]\n\n  [[ ${status} -eq 0                ]]\n  [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n  [[ -f \"${NB_DIR_2}/home/one.md\"   ]]\n}\n\n# autosync ####################################################################\n\n@test \"NB_AUTO_SYNC=1 syncs with 'add'.\" {\n  {\n    _setup_notebooks\n\n    [[ ! -f \"${NB_DIR_1}/home/one.md\" ]]\n    [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n  }\n\n  export NB_AUTO_SYNC=1\n\n  # sync 1: add with autosync on\n  run \"${_NB}\" add \"one.md\" --content \"Example content from 1.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" env\n\n  [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n  [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n\n  [[ ${status}      -eq 0           ]]\n  [[ \"${lines[0]}\"  =~ Added        ]]\n  [[ \"${lines[0]}\"  =~ one          ]]\n  [[ ! \"${output}\"  =~ Sync         ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  # sync 2: pull changes from remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls -la \"${NB_DIR_1}/home/\"\n  git -C \"${NB_DIR_1}/home\" status\n  ls -la \"${NB_DIR_2}/home/\"\n  git -C \"${NB_DIR_2}/home\" status\n\n  [[ ${status} -eq 0              ]]\n  [[ -f \"${NB_DIR_1}/home/one.md\" ]]\n  [[ -f \"${NB_DIR_2}/home/one.md\" ]]\n}\n\n@test \"NB_AUTO_SYNC=0 does not sync with 'add'.\" {\n  {\n    _setup_notebooks\n\n    [[ ! -f \"${NB_DIR_1}/home/one.md\" ]]\n    [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n  }\n\n  export NB_AUTO_SYNC=0\n\n  # sync 1: add with autosync off\n  run \"${_NB}\" add \"one.md\" --content \"Example content from 1.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" env\n\n  [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n  [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n\n  [[ ${status}      -eq 0           ]]\n  [[ \"${lines[0]}\"  =~ Added        ]]\n  [[ \"${lines[0]}\"  =~ one          ]]\n  [[ ! \"${output}\"  =~ Sync         ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  # sync 2: pull changes from remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls -la \"${NB_DIR_1}/home/\"\n  git -C \"${NB_DIR_1}/home\" status\n  ls -la \"${NB_DIR_2}/home/\"\n  git -C \"${NB_DIR_2}/home\" status\n\n  [[ ${status} -eq 0                ]]\n  [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n  [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n}\n\n@test \"NB_AUTO_SYNC=1 syncs dirty repo.\" {\n  {\n    _setup_notebooks\n\n    touch \"${NB_DIR_1}/home/one.md\"\n\n    [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n    [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n\n    \"${_NB}\" git dirty\n  }\n\n  export NB_AUTO_SYNC=1\n\n  # sync 1: autosync on with no subcommand\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" env\n\n  [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n  [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n\n  [[ ${status}      -eq 0           ]]\n  [[ \"${lines[0]}\"  =~ home         ]]\n  [[ \"${lines[2]}\"  =~ one          ]]\n  [[ ! \"${output}\"  =~ Sync         ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  # sync 2: pull changes from remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls -la \"${NB_DIR_1}/home/\"\n  git -C \"${NB_DIR_1}/home\" status\n  ls -la \"${NB_DIR_2}/home/\"\n  git -C \"${NB_DIR_2}/home\" status\n\n  [[ ${status} -eq 0              ]]\n  [[ -f \"${NB_DIR_1}/home/one.md\" ]]\n  [[ -f \"${NB_DIR_2}/home/one.md\" ]]\n}\n\n@test \"NB_AUTO_SYNC=0 does not sync dirty repo.\" {\n  {\n    _setup_notebooks\n\n    touch \"${NB_DIR_1}/home/one.md\"\n\n    [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n    [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n\n    \"${_NB}\" git dirty\n  }\n\n  export NB_AUTO_SYNC=0\n\n  # sync 1: autosync off with no subcommand\n  run \"${_NB}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  \"${_NB}\" env\n\n  [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n  [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n\n  [[ ${status}      -eq 0           ]]\n  [[ \"${lines[0]}\"  =~ home         ]]\n  [[ \"${lines[2]}\"  =~ one          ]]\n  [[ ! \"${output}\"  =~ Sync         ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  # sync 2: pull changes from remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  ls -la \"${NB_DIR_1}/home/\"\n  git -C \"${NB_DIR_1}/home\" status\n  ls -la \"${NB_DIR_2}/home/\"\n  git -C \"${NB_DIR_2}/home\" status\n\n  [[ ${status} -eq 0                ]]\n  [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n  [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n}\n\n@test \"NB_AUTO_SYNC=1 with error fails silently.\" {\n  {\n    _setup_notebooks\n    mv \"${_GIT_REMOTE_PATH}\" \"${_GIT_REMOTE_PATH}.bak\"\n\n    [[ ! -f \"${NB_DIR_1}/home/one.md\" ]]\n    [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n  }\n\n  export NB_AUTO_SYNC=1\n\n  # sync 1: add with autosync\n  run \"${_NB}\" add \"one.md\" --content \"Example content from 1.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n  [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n\n  [[ ${status}      -eq 0           ]]\n  [[ \"${lines[0]}\"  =~ Added        ]]\n  [[ \"${lines[0]}\"  =~ one          ]]\n  [[ ! \"${output}\"  =~ Sync         ]]\n\n  mv \"${_GIT_REMOTE_PATH}.bak\" \"${_GIT_REMOTE_PATH}\"\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  # sync 2: pull changes from remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                ]]\n  [[ -f \"${NB_DIR_1}/home/one.md\"   ]]\n  [[ ! -f \"${NB_DIR_2}/home/one.md\" ]]\n}\n\n# sync ########################################################################\n\n@test \"'sync' succeeds when files are added and removed from two clones.\" {\n  # skip\n  {\n    _setup_notebooks\n    \"${_NB}\" add \"one.md\" --content \"Example content from 1.\"\n\n    export NB_DIR=\"${NB_DIR_2}\"\n    \"${_NB}\" add \"two.md\" --content \"Example content from 2.\"\n\n    export NB_DIR=\"${NB_DIR_1}\"\n  }\n\n  # sync 1: send changes to remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(1)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 1  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 1  ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \"one.md\" ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \"two.md\" ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  # sync 2: pull changes from remote, rebase, send new changes back to remote\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(2)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                                  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 1                    ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 2                    ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \"one.md\"                   ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \"one.md${_NEWLINE}two.md\"  ]]\n\n  # sync 3: pull changes from remote\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(3)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                                  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 2                    ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 2                    ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \"one.md${_NEWLINE}two.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \"one.md${_NEWLINE}two.md\"  ]]\n\n  # Add more notes to each clone\n\n  export NB_DIR=\"${NB_DIR_1}\"\n  run \"${_NB}\" add \"one-2.md\" --content \"Example content from 1.\"\n\n  export NB_DIR=\"${NB_DIR_2}\"\n  run \"${_NB}\" add \"two-2.md\" --content \"Example content from 2.\"\n\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 3  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 3  ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \"one.md${_NEWLINE}two.md${_NEWLINE}one-2.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md\"  ]]\n\n  # sync 4: send new changes to remote\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(4)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 3  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 3  ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \"one.md${_NEWLINE}two.md${_NEWLINE}one-2.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md\"  ]]\n\n  # sync 5: pull changes from remote, rebase, send new changes back to remote\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(5)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                                  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 4                    ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 3                    ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md\"                     ]]\n\n  # sync 6: pull changes from remote\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(6)\\\\n\"\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                                  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 4                    ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 4                    ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md\"  ]]\n\n  # add more notes to and remove notes from each clone\n\n  export NB_DIR=\"${NB_DIR_1}\"\n  run \"${_NB}\" add \"one-3.md\" --content \"Example content from 1.\"\n  run \"${_NB}\" delete \"two.md\" --force\n\n  export NB_DIR=\"${NB_DIR_2}\"\n  run \"${_NB}\" add \"two-3.md\" --content \"Example content from 2.\"\n\n  printf \"(6.5)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 4 ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 5 ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \\\n    \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}one-3.md\"        ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \\\n    \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md\"  ]]\n\n  # sync 7: push changes to remote\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(7)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 4  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 5  ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \\\n    \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}one-3.md\"        ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \\\n    \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md\"  ]]\n\n  # sync 8: pull changes from remote\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(8)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 5  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 5  ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md${_NEWLINE}one-3.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md\"               ]]\n\n  # sync 9: push changes to remote\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(9)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 5  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 5  ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md${_NEWLINE}one-3.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}two.md${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md\"               ]]\n\n  # sync 10: pull changes from remote\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"(10)\\\\n\"\n  NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count\n  printf \"index 1:\\\\n\"\n  cat \"${NB_DIR_1}/home/.index\"\n  NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count\n  printf \"index 2:\\\\n\"\n  cat \"${NB_DIR_2}/home/.index\"\n\n  [[ ${status} -eq 0                                ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_1}\" \"${_NB}\" count)\" == 5  ]]\n  [[ \"$(NB_DIR=\"${NB_DIR_2}\" \"${_NB}\" count)\" == 5  ]]\n  [[ \"$(cat \"${NB_DIR_1}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md${_NEWLINE}one-3.md\"  ]]\n  [[ \"$(cat \"${NB_DIR_2}/home/.index\")\" == \\\n     \"one.md${_NEWLINE}${_NEWLINE}two-2.md${_NEWLINE}one-2.md${_NEWLINE}two-3.md${_NEWLINE}one-3.md\"  ]]\n}\n\n@test \"'sync' succeeds when one file is edited on two clones.\" {\n  # skip\n\n  _setup_notebooks\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" add \"one.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  # ls -la \"${NB_DIR_2}\"\n\n  _sed_i 's/Line 4/Line n/' \"${NB_DIR_2}/home/one.md\"\n\n  run \"${_NB}\" &>/dev/null\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  _sed_i 's/Line 4/Line x/' \"${NB_DIR_1}/home/one.md\"\n\n  run \"${_NB}\" &>/dev/null\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  cat \"${NB_DIR_1}/home/one.md\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ ${output} =~ Files\\ containing\\ conflicts\\:  ]]\n  [[ ${output} =~ \\ \\ home\\:one\\.md               ]]\n\n  grep -q '<<<<<<< HEAD'        \"${NB_DIR_1}/home/one.md\"\n  grep -q '\\- Line n List Item' \"${NB_DIR_1}/home/one.md\"\n  grep -q '======='             \"${NB_DIR_1}/home/one.md\"\n  grep -q '\\- Line x List Item' \"${NB_DIR_1}/home/one.md\"\n  grep -q '>>>>>>>'             \"${NB_DIR_1}/home/one.md\"\n  grep -q '\\[nb\\] Commit'       \"${NB_DIR_1}/home/one.md\"\n  grep -q '\\- Line 5 List Item' \"${NB_DIR_1}/home/one.md\"\n}\n\n@test \"'sync' succeeds when multiple files are edited on two clones.\" {\n  # skip\n  _setup_notebooks\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" add \"one.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n\n  run \"${_NB}\" add \"two.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n\n  run \"${_NB}\" add \"three.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  # ls -la \"${NB_DIR_2}\"\n\n  _sed_i 's/Line 4/Line n/' \"${NB_DIR_2}/home/one.md\"\n  _sed_i 's/Line 4/Line n/' \"${NB_DIR_2}/home/two.md\"\n  _sed_i 's/Line 4/Line n/' \"${NB_DIR_2}/home/three.md\"\n\n  run \"${_NB}\" &>/dev/null\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  _sed_i 's/Line 4/Line x/' \"${NB_DIR_1}/home/one.md\"\n  _sed_i 's/Line 4/Line x/' \"${NB_DIR_1}/home/two.md\"\n  _sed_i 's/Line 4/Line x/' \"${NB_DIR_1}/home/three.md\"\n\n  run \"${_NB}\" &>/dev/null\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  cat \"${NB_DIR_1}/home/one.md\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ ${output} =~ Files\\ containing\\ conflicts\\:  ]]\n  [[ ${output} =~ \\ \\ home\\:one\\.md               ]]\n  [[ ${output} =~ \\ \\ home\\:two\\.md               ]]\n  [[ ${output} =~ \\ \\ home\\:three\\.md             ]]\n\n  grep -q '<<<<<<< HEAD'        \"${NB_DIR_1}/home/one.md\"\n  grep -q '\\- Line n List Item' \"${NB_DIR_1}/home/one.md\"\n  grep -q '======='             \"${NB_DIR_1}/home/one.md\"\n  grep -q '\\- Line x List Item' \"${NB_DIR_1}/home/one.md\"\n  grep -q '>>>>>>>'             \"${NB_DIR_1}/home/one.md\"\n  grep -q '\\[nb\\] Commit'       \"${NB_DIR_1}/home/one.md\"\n  grep -q '\\- Line 5 List Item' \"${NB_DIR_1}/home/one.md\"\n\n  grep -q '<<<<<<< HEAD'        \"${NB_DIR_1}/home/two.md\"\n  grep -q '\\- Line n List Item' \"${NB_DIR_1}/home/two.md\"\n  grep -q '======='             \"${NB_DIR_1}/home/two.md\"\n  grep -q '\\- Line x List Item' \"${NB_DIR_1}/home/two.md\"\n  grep -q '>>>>>>>'             \"${NB_DIR_1}/home/two.md\"\n  grep -q '\\[nb\\] Commit'       \"${NB_DIR_1}/home/two.md\"\n  grep -q '\\- Line 5 List Item' \"${NB_DIR_1}/home/two.md\"\n\n  grep -q '<<<<<<< HEAD'        \"${NB_DIR_1}/home/three.md\"\n  grep -q '\\- Line n List Item' \"${NB_DIR_1}/home/three.md\"\n  grep -q '======='             \"${NB_DIR_1}/home/three.md\"\n  grep -q '\\- Line x List Item' \"${NB_DIR_1}/home/three.md\"\n  grep -q '>>>>>>>'             \"${NB_DIR_1}/home/three.md\"\n  grep -q '\\[nb\\] Commit'       \"${NB_DIR_1}/home/three.md\"\n  grep -q '\\- Line 5 List Item' \"${NB_DIR_1}/home/three.md\"\n}\n\n@test \"'sync' succeeds when the same filename is added on two clones.\" {\n  # skip\n  _setup_notebooks\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" add \"one.md\" --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n  run \"${_NB}\" sync\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" add \"one.md\" --content \"Example different content from 2.\n\nThis content is unique to 2.\n\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  printf \"1:one.md\\\\n\"\n  cat \"${NB_DIR_1}/home/one.md\"\n  printf \"2:one.md\\\\n\"\n  cat \"${NB_DIR_2}/home/one.md\"\n\n  [[ ${status} -eq 0                              ]]\n  [[ ${output} =~ Files\\ containing\\ conflicts\\:  ]]\n  [[ ${output} =~ \\ \\ home\\:one\\.md               ]]\n\n  grep -q '<<<<<<< HEAD'              \"${NB_DIR_2}/home/one.md\"\n  grep -q 'Example content from 1.'   \"${NB_DIR_2}/home/one.md\"\n  grep -q '\\- Line 3 List Item'       \"${NB_DIR_2}/home/one.md\"\n  grep -q '======='                   \"${NB_DIR_2}/home/one.md\"\n  grep -q 'Example different content' \"${NB_DIR_2}/home/one.md\"\n  grep -q '>>>>>>>'                   \"${NB_DIR_2}/home/one.md\"\n  grep -q '\\[nb\\] Add\\: one.md'       \"${NB_DIR_2}/home/one.md\"\n}\n\n@test \"'sync' succeeds when an encrypted file is edited on two clones.\" {\n  # skip\n\n  _setup_notebooks\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  run \"${_NB}\" add \"one.md\"       \\\n    --encrypt --password password \\\n    --content \"Example content from 1.\n\n- Line 3 List Item\n- Line 4 List Item\n- Line 5 List Item\n\"\n  run \"${_NB}\" sync\n\n  [[ -e \"${NB_DIR_1}/home/one.md.enc\"                     ]]\n  [[ ! -e \"${NB_DIR_1}/home/one--conflicted-copy.md.enc\"  ]]\n\n  [[ ! -e \"${NB_DIR_2}/home/one.md.enc\"                   ]]\n  [[ ! -e \"${NB_DIR_2}/home/one--conflicted-copy.md.enc\"  ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  [[ ! \"$(\n          \"${_NB}\" show one.md.enc --password password --print --no-color\n        )\" =~ Edit\\ content\\ from\\ 1\\.                    ]]\n  [[ ! \"$(\n          \"${_NB}\" show one.md.enc --password password --print --no-color\n        )\" =~ Edit\\ content\\ from\\ 2\\.                    ]]\n\n  run \"${_NB}\" sync\n\n  [[ -e \"${NB_DIR_1}/home/one.md.enc\"                     ]]\n  [[ ! -e \"${NB_DIR_1}/home/one--conflicted-copy.md.enc\"  ]]\n\n  [[ -e \"${NB_DIR_2}/home/one.md.enc\"                     ]]\n  [[ ! -e \"${NB_DIR_2}/home/one--conflicted-copy.md.enc\"  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/one.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR_2}/home/one.md.enc\")\"         ]]\n\n  ls -la \"${NB_DIR_2}\"\n\n  echo \"Edit content from 2.\" | \"${_NB}\" edit 1 --password password\n\n  run \"${_NB}\" sync\n\n  [[ -e \"${NB_DIR_1}/home/one.md.enc\"                     ]]\n  [[ ! -e \"${NB_DIR_1}/home/one--conflicted-copy.md.enc\"  ]]\n\n  [[ -e \"${NB_DIR_2}/home/one.md.enc\"                     ]]\n  [[ ! -e \"${NB_DIR_2}/home/one--conflicted-copy.md.enc\"  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/one.md.enc\")\" != \\\n     \"$(_get_hash \"${NB_DIR_2}/home/one.md.enc\")\"         ]]\n\n  [[ \"$(\n        \"${_NB}\" show one.md.enc --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 2\\.                      ]]\n\n  export NB_DIR=\"${NB_DIR_1}\"\n\n  _before=\"$(\n    _get_hash \"${NB_DIR_1}/home/one.md.enc\"\n  )\"\n\n  echo \"Edit content from 1.\" | \"${_NB}\" edit 1 --password password\n\n  _after=\"$(\n    _get_hash \"${NB_DIR_1}/home/one.md.enc\"\n  )\"\n\n  printf \"\\${_before}:  %s\\\\n\" \"${_before}\"\n  printf \"\\${_after}:   %s\\\\n\" \"${_after}\"\n\n  [[ \"${_before}\" != \"${_after}\"      ]]\n\n  [[ \"$(\n        \"${_NB}\" show one.md.enc --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 1\\.  ]]\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/one.md.enc\")\" != \\\n     \"$(_get_hash \"${NB_DIR_2}/home/one.md.enc\")\"             ]]\n\n  [[ ${status} -eq 0                                          ]]\n\n  [[ -e \"${NB_DIR_1}/home/one.md.enc\"                         ]]\n  [[ -e \"${NB_DIR_1}/home/one--conflicted-copy.md.enc\"        ]]\n\n  [[ -e \"${NB_DIR_2}/home/one.md.enc\"                         ]]\n  [[ ! -e \"${NB_DIR_2}/home/one--conflicted-copy.md.enc\"      ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/one.md.enc\")\" != \\\n     \"$(_get_hash \"${NB_DIR_2}/home/one.md.enc\")\"             ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/one--conflicted-copy.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR_2}/home/one.md.enc\")\"             ]]\n\n  [[ ${output} =~ Conflicted\\ copies\\ of\\ binary\\ files\\:     ]]\n  [[ ${output} =~ \\ \\ home\\:one\\-\\-conflicted-copy\\.md\\.enc   ]]\n\n  [[ \"$(\n        \"${_NB}\" show one.md.enc --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 1\\.                          ]]\n  [[ \"$(\n        \"${_NB}\" show one--conflicted-copy.md.enc --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 2\\.                          ]]\n\n  export NB_DIR=\"${NB_DIR_2}\"\n\n  run \"${_NB}\" sync\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ ${status} -eq 0                                                ]]\n\n  [[ -e \"${NB_DIR_1}/home/one.md.enc\"                               ]]\n  [[ -e \"${NB_DIR_1}/home/one--conflicted-copy.md.enc\"              ]]\n\n  [[ -e \"${NB_DIR_2}/home/one.md.enc\"                               ]]\n  [[ -e \"${NB_DIR_2}/home/one--conflicted-copy.md.enc\"              ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/one.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR_2}/home/one.md.enc\")\"                   ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/one--conflicted-copy.md.enc\")\" == \\\n     \"$(_get_hash \"${NB_DIR_2}/home/one--conflicted-copy.md.enc\")\"  ]]\n\n  [[ \"$(_get_hash \"${NB_DIR_1}/home/one.md.enc\")\" != \\\n     \"$(_get_hash \"${NB_DIR_1}/home/one--conflicted-copy.md.enc\")\"  ]]\n\n  [[ \"$(\n        \"${_NB}\" show one.md.enc --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 1\\.                                ]]\n  [[ \"$(\n        \"${_NB}\" show one--conflicted-copy.md.enc --password password --print --no-color\n      )\" =~ Edit\\ content\\ from\\ 2\\.                                ]]\n}\n\n@test \"'sync' notebooks exist after setup.\" {\n  _setup_notebooks\n\n  [[ -d \"${_GIT_REMOTE_PATH}\"     ]]\n  [[ \"${NB_DIR_1}\" == \"${NB_DIR}\" ]]\n  [[ -d \"${NB_DIR_1}/home/.git\"   ]]\n  [[ -d \"${NB_DIR_2}/home/.git\"   ]]\n}\n"
  },
  {
    "path": "test/t.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031,SC2063,SC2076\n\nload test_helper\n\n# t todos alias ###############################################################\n\n@test \"'todos <notebook>:<folder>/' exits with 0 and lists todos.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/Two.todo.md\"           \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" t todos Example\\ Notebook:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0     ]]\n\n  [[ !  \"${output}\"   =~  Four  ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\. ]]\n  [[    \"${lines[1]}\" =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/2.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ two\\.     ]]\n  [[    \"${lines[2]}\" =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/1.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.     ]]\n}\n\n# t alias <folder> ############################################################\n\n@test \"'t open <folder>' exits with 0 and lists open todos and tasks in folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/Note One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Note Title One.\n\nExample content.\n\n- [x] Task one.\n- [ ] Task two.\n- [ ] Task three.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note Two.md\"      \\\n      --content   \"Example note content two.\"\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo Two.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [x] Task two.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Three.todo.md\"   \\\n      --content   \"# [x] Example todo description three.\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Four.todo.md\"    \\\n      --content   \"# [ ] Example todo description four.\"\n  }\n\n  run \"${_NB}\" t open Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 13  ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/6.*].*\\ ✔️\\ \\ *[\\ ].*\\ Example\\ todo\\ description\\ four\\.      ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*\\[.*Example\\ Folder/4.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n  [[    \"${lines[2]}\"   =~  .*------------------------------------.*                ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                               ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Folder/2.*].*\\ Example\\ Note\\ Title\\ One.              ]]\n  [[    \"${lines[5]}\"   =~  .*------------------------------------.*  ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                 ]]\n  [[    \"${lines[7]}\"  =~  \\\n.*[.*Example\\ Folder/2\\ 3.*].*\\ .*[\\ ].*\\ Task\\ three\\.               ]]\n\n  [[    \"${lines[8]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[9]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[10]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                             ]]\n  [[    \"${lines[11]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                             ]]\n  [[    \"${lines[12]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.                            ]]\n}\n\n@test \"'t closed <folder>' exits with 0 and lists closed todos and tasks in folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/Note One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Note Title One.\n\nExample content.\n\n- [x] Task one.\n- [ ] Task two.\n- [ ] Task three.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note Two.md\"      \\\n      --content   \"Example note content two.\"\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo Two.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [x] Task two.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Three.todo.md\"   \\\n      --content   \"# [x] Example todo description three.\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Four.todo.md\"    \\\n      --content   \"# [ ] Example todo description four.\"\n  }\n\n  run \"${_NB}\" t closed Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 10  ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/5.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\.  ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*\\[.*Example\\ Folder/4.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.    ]]\n  [[    \"${lines[2]}\"   =~  .*------------------------------------.*                  ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 2.*].*\\ .*[.*x.*].*\\ Task\\ two\\.                              ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Folder/2.*].*\\ Example\\ Note\\ Title\\ One.              ]]\n  [[    \"${lines[5]}\"   =~  .*------------------------------------.*  ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 1.*].*\\ .*[.*x.*].*\\ Task\\ one\\.              ]]\n\n  [[    \"${lines[7]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[8]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[9]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.                        ]]\n}\n\n@test \"'t <folder>' exits with 0 and lists todos and tasks in folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/Note One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Note Title One.\n\nExample content.\n\n- [x] Task one.\n- [ ] Task two.\n- [ ] Task three.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note Two.md\"      \\\n      --content   \"Example note content two.\"\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo Two.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [x] Task two.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Three.todo.md\"   \\\n      --content   \"# [x] Example todo description three.\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Four.todo.md\"    \\\n      --content   \"# [ ] Example todo description four.\"\n  }\n\n  run \"${_NB}\" t Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 17  ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/6.*].*\\ ✔️\\ \\ .*[\\ ].*\\ Example\\ todo\\ description\\ four\\.       ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*\\[.*Example\\ Folder/5.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\.  ]]\n  [[    \"${lines[2]}\"   =~  \\\n.*\\[.*Example\\ Folder/4.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.    ]]\n  [[    \"${lines[3]}\"   =~  .*------------------------------------.*                  ]]\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                                 ]]\n  [[    \"${lines[5]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 2.*].*\\ .*[.*x.*].*\\ Task\\ two\\.                              ]]\n\n  [[    \"${lines[6]}\"   =~  \\\n.*\\[.*Example\\ Folder/2.*].*\\ Example\\ Note\\ Title\\ One.              ]]\n  [[    \"${lines[7]}\"   =~  .*------------------------------------.*  ]]\n  [[    \"${lines[8]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 1.*].*\\ .*[.*x.*].*\\ Task\\ one\\.              ]]\n  [[    \"${lines[9]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                 ]]\n  [[    \"${lines[10]}\"  =~  \\\n.*[.*Example\\ Folder/2\\ 3.*].*\\ .*[\\ ].*\\ Task\\ three\\.               ]]\n\n  [[    \"${lines[11]}\"  =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[12]}\"  =~  .*------------------------------------.*              ]]\n  [[    \"${lines[13]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                             ]]\n  [[    \"${lines[14]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                             ]]\n  [[    \"${lines[15]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.                        ]]\n  [[    \"${lines[16]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.                            ]]\n}\n\n# t alias <id> ################################################################\n\n@test \"'t open <folder>/<id>' exits with 0 and lists open tasks in the item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" t open Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 5                           ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.   ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.   ]]\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.  ]]\n}\n\n@test \"'tasks closed <folder>/<id>' exits with 0 and lists closed tasks in the item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                      \\\n      --filename  \"Example Folder/Todo One.todo.md\"   \\\n      --content   \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" t closed Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 3                                   ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*\\[.*Example\\ Folder/1\\ 3.*\\].*\\ .*\\[.*x.*\\].*\\ Task\\ three\\.  ]]\n}\n\n@test \"'tasks <folder>/<id>' exits with 0 and lists tasks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                      \\\n      --filename \"Example Folder/Todo One.todo.md\"    \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" t Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 6                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.       ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.       ]]\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.  ]]\n  [[    \"${lines[5]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.      ]]\n}\n"
  },
  {
    "path": "test/test_helper.bash",
    "content": "#!/usr/bin/env bash\n###############################################################################\n# test_helper.bash\n#\n# Test helper for Bats: Bash Automated Testing System.\n#\n# https://github.com/bats-core/bats-core\n# https://github.com/sstephenson/bats\n###############################################################################\n\n# bats_require_minimum_version\n#\n# https://github.com/bats-core/bats-core/blob/master/docs/source/writing-tests.md\nif hash \"bats_require_minimum_version\" &>/dev/null\nthen\n  bats_require_minimum_version 1.5.0\nfi\n\n# _setup()\n#\n# Usage:\n#   _setup [<bats-base-path>]\n#\n# Description:\n#   Set up the test environment.\n_setup() {\n  IFS=$'\\n\\t'\n\n  # Allow clobber. More info: https://stackoverflow.com/a/6762399\n  set +o noclobber\n\n  # Allow globbing.\n  set +o noglob\n\n  #############################################################################\n\n  # $NB_TEST_BASE_PATH\n  #\n  # The base directory for the test suite.\n  export NB_TEST_BASE_PATH=\"${1:-\"${BATS_TEST_DIRNAME}\"}\"\n\n  # $_ME\n  #\n  # The name of the program.\n  export _ME=\"nb\"\n\n  # $_NB\n  #\n  # The location of the `nb` script being tested.\n  export _NB=\"${NB_TEST_BASE_PATH}/../nb\"\n\n  # $_TMP_DIR\n  #\n  # The temp directory for the test run.\n  export _TMP_DIR=\n  _TMP_DIR=\"$(mktemp -d /tmp/nb_test.XXXXXX)\" || exit 1\n\n  #############################################################################\n\n  # $EDITOR\n  #\n  # Set to mock_editor when unassigned.\n  if [[ -z \"${EDITOR:-}\" ]] || [[ ! \"${EDITOR:-}\" =~ mock_editor ]]\n  then\n    export EDITOR=\"${NB_TEST_BASE_PATH}/fixtures/bin/mock_editor\"\n  fi\n\n  # $NBRC_PATH\n  #\n  # The location of the .nbrc configuration file.\n  export NBRC_PATH=\"${_TMP_DIR}/.nbrc\"\n\n  # $NB_AUTO_SYNC\n  #\n  # Turn off auto-sync.\n  export NB_AUTO_SYNC=0\n\n  # $NB_COLOR_PRIMARY\n  #\n  # Set to a value compatible with CI terminals.\n  export NB_COLOR_PRIMARY=3\n\n  # $NB_DIR\n  #\n  # The location of the directory that contains the notebooks.\n  export NB_DIR=\"${_TMP_DIR}/notebooks\"\n\n  # $NB_DOWNLOAD_TOOL\n  #\n  # Only use curl for downloads..\n  export NB_DOWNLOAD_TOOL=\"curl\"\n\n  # $NB_PINNED_PATTERN\n  #\n  # Pattern for tag-based pinning.\n  export NB_PINNED_PATTERN=\"#pinned\"\n\n  # $NB_SERVER_PORT\n  #\n  # The port used for the `browse` server.\n  export NB_SERVER_PORT=6789\n\n  #############################################################################\n\n  # $_BOOKMARK\n  #\n  # The location of the `bookmark` script being tested.\n  export _BOOKMARK=\"${NB_TEST_BASE_PATH}/../bin/bookmark\"\n\n  # $_BOOKMARK_URL\n  #\n  # A URL for an HTML file.\n  export _BOOKMARK_URL=\"file://${NB_TEST_BASE_PATH}/fixtures/example.com.html\"\n\n  # $_BOOKMARK_OG_URL\n  #\n  # A URL for an HTML file with open graph tags.\n  export _BOOKMARK_OG_URL=\"file://${NB_TEST_BASE_PATH}/fixtures/example.com-og.html\"\n\n  # $_BOOKMARK_TITLES_URL\n  #\n  # A URL for an HTML file with multiple title tags with unicode characters.\n  export _BOOKMARK_TITLES_URL=\"file://${NB_TEST_BASE_PATH}/fixtures/example.com-titles.html\"\n\n  # $_BOOKMARK_TITLES_NEWLINES_URL\n  #\n  # A URL for an HTML file with <title> tags separated from content by newlines.\n  export _BOOKMARK_TITLES_NEWLINES_URL=\"file://${NB_TEST_BASE_PATH}/fixtures/example.com-titles-newlines.html\"\n\n  # $_ERROR_PREFIX\n  #\n  # The color string added to error messages by `_exit_1` and `_return_1`.\n  export _ERROR_PREFIX=\n  _ERROR_PREFIX=\"$(tput setaf 1)!$(tput sgr0)\"\n\n  # $_GIT_REMOTE_PATH\n  #\n  # Path to use for a git remote repository within the temp directory.\n  export _GIT_REMOTE_PATH=\"${_TMP_DIR}/remote\"\n\n  # $_GIT_REMOTE_URL\n  #\n  # URL to use for a git remote repository within the temp directory.\n  export _GIT_REMOTE_URL=\"file://${_GIT_REMOTE_PATH}\"\n\n  # $_NB_PATH\n  #\n  # Used by `bookmark` and `notes` for testing.\n  export _NB_PATH=\"${_NB}\"\n\n  # $_NOTES\n  #\n  # The location of the `notes` script being tested.\n  export _NOTES=\"${NB_TEST_BASE_PATH}/../bin/notes\"\n\n  #############################################################################\n  # verify that NB_DIR and NBRC_PATH are in the temp directory\n\n  if [[ ! \"${NB_DIR}\"         =~ ^/tmp/nb_test ]] ||\n     [[ ! \"${NBRC_PATH}\"      =~ ^/tmp/nb_test ]]\n  then\n    exit 1\n  fi\n}\n\n###############################################################################\n# setup() and teardown()\n#\n# https://bats-core.readthedocs.io/en/stable/writing-tests.html\n###############################################################################\n\nsetup() {\n  _setup\n\n  # Use empty `nb` script in environment to avoid depending on `nb`\n  # being available in `$PATH`.\n  export PATH=\"${NB_TEST_BASE_PATH}/fixtures/bin:${PATH}\"\n}\n\nteardown() {\n  if [[ -n  \"${_TMP_DIR:?}\"                   ]] &&\n     [[ -e  \"${_TMP_DIR:?}\"                   ]] &&\n     [[     \"${_TMP_DIR:?}\" =~ ^/tmp/nb_test  ]]\n  then\n    rm -rf  \"${_TMP_DIR:?}\"\n  fi\n}\n\n###############################################################################\n# Helpers\n###############################################################################\n\n# $_AMP\n#\n# Ampersand configurable as escaped &amp; or &.\nexport _AMP=\"&\"\n\n# $_BT\n#\n# Backtick with ANSI-C quoting for string building.\n_BT=$'`'\n\n# $_IMOGI\n#\n# A character representing an image.\nexport _IMOGI=\"🌄\"\n\n# $_NBSP\n#\n# Non-breaking space. See also: $_S\nexport _NBSP=\" \"\n\n# $_NEWLINE\n#\n# Newline with ANSI-C quoting for string building.\nexport _NEWLINE=$'\\n'\n\n# $_S\n#\n# Non-breaking space. See also: $_NBSP\nexport _S=\" \"\n\n# _compare()\n#\n# Usage:\n#   _compare <expected> <actual>\n#\n# Description:\n#   Compare the content of a variable against an expected value. When used\n#   within a `@test` block the output is only displayed when the test fails.\n_compare() {\n  local _expected=\"${1:-}\"\n  local _actual=\"${2:-}\"\n\n  printf \"expected:\\\\n%s\\\\n\"  \"${_expected}\"\n  printf \"actual:\\\\n%s\\\\n\"    \"${_actual}\"\n}\n\n# _contains()\n#\n# Usage:\n#   _contains <query> <list-item>...\n#\n# Exit / Error Status:\n#   0 (success, true)  If the item is included in the list.\n#   1 (error,  false)  If not.\n#\n# Example:\n#   _contains \"${_query}\" \"${_list[@]}\"\n_contains() {\n  local _query=\"${1:-}\"\n\n  shift\n\n  if [[ -z \"${_query}\"  ]] ||\n     [[ -z \"${*:-}\"     ]]\n  then\n    return 1\n  fi\n\n  local __element=\n  for   __element in \"${@}\"\n  do\n    [[ \"${__element}\" == \"${_query}\" ]] && return 0\n  done\n\n  return 1\n}\n\n# _get_hash()\n#\n# Usage:\n#   _get_hash <path>\n#\n# Description:\n#   Generate a hash for the file or directory at <path>.\n_get_hash() {\n  # Usage: _get_hash_with_command <path> <command>\n  _get_hash_with_command() {\n    local _command=\n    IFS=' ' read -ra _command <<< \"${2:-}\"\n\n    local _path=\"${1:-}\"\n\n    if [[ -z \"${_command[*]:-}\"   ]] ||\n       [[ -z \"${_path}\"           ]]\n    then\n      return 1\n    fi\n\n    if [[ -d \"${_path}\"           ]]\n    then\n      tar -P -cf - \"${_path}\"     \\\n        | \"${_command[@]}\"        \\\n        | awk '{ print $1 }'\n    else\n      \"${_command[@]}\" \"${_path}\" \\\n        | awk '{print $1}'\n    fi\n  }\n\n  local _path=\"${1:-}\"\n  [[ -n \"${_path:-}\" ]] || return 1\n\n  if hash \"shasum\" 2>/dev/null\n  then\n    _get_hash_with_command \"${_path}\" \"shasum -a 256\"\n  elif hash \"md5sum\" 2>/dev/null\n  then\n    _get_hash_with_command \"${_path}\" \"md5sum\"\n  elif hash \"md5\" 2>/dev/null\n  then\n    _get_hash_with_command \"${_path}\" \"md5 -q\"\n  else\n    printf \"No hashing tool found.\\\\n\"\n    exit 1\n  fi\n}\n\n# color variables\n\nexport _TPUT_COLOR_PRIMARY=   && _TPUT_COLOR_PRIMARY=\"$(tput setaf 3)\"\nexport _TPUT_SETAF_8=         && _TPUT_SETAF_8=\"$(tput setaf 8)\"\nexport _TPUT_SGR0=            && _TPUT_SGR0=\"$(tput sgr0)\"\nexport _TPUT_SMUL=            && _TPUT_SMUL=\"$(tput smul)\"\n\n# _color_muted()\n#\n# Usage:\n#   _color_muted <string>\n#\n# Print the given string with the muted color.\n_color_muted() {\n  printf \"%s%s%s%s\"     \\\n    \"${_TPUT_SGR0}\"     \\\n    \"${_TPUT_SETAF_8}\"  \\\n    \"${1:-}\"            \\\n    \"${_TPUT_SGR0}\"\n}\n\n# _color_primary()\n#\n# Usage:\n#   _color_primary <string> [--underline]\n_color_primary() {\n  local _input=\"${1:-}\"\n\n  if [[ -z \"${_input:-}\"          ]]\n  then\n    printf \"Usage: _color_primary <string>\" 1>&2\n    exit 1\n  fi\n\n  if [[ \"${2:-}\" == \"--underline\" ]]\n  then\n    printf                                                                  \\\n      \"${_TPUT_SGR0}${_TPUT_SMUL}${_TPUT_COLOR_PRIMARY}%s${_TPUT_SGR0}\\\\n\"  \\\n      \"${_input}\"\n  else\n    printf                                                                  \\\n      \"${_TPUT_SGR0}${_TPUT_COLOR_PRIMARY}%s${_TPUT_SGR0}\\\\n\"               \\\n      \"${_input}\"\n  fi\n}\n\n# _sed_i()\n#\n# `sed -i` takes an extension on macOS, but that extension can cause errors in\n# GNU `sed`.\n#\n# https://stackoverflow.com/q/43171648\n# https://stackoverflow.com/a/16746032\n_sed_i() {\n  if sed --help >/dev/null 2>&1\n  then # GNU\n    sed -i \"${@}\"\n  else # BSD\n    sed -i '' \"${@}\"\n  fi\n}\n\n# _setup_remote_repo()\n#\n# Usage:\n#   _setup_remote_repo [<branch-name>]\n#\n# Description:\n#   Initialize and add initial commit to a git repository at\n#   `$_GIT_REMOTE_URL`.\n_setup_remote_repo() {\n  local _branch_name=\"${1:-\"master\"}\"\n  local _pwd=\"${PWD}\"\n\n  if [[ -n \"${_GIT_REMOTE_PATH}\"                  ]] &&\n     [[    \"${_GIT_REMOTE_PATH}\" =~ ^/tmp/nb_test ]]\n  then\n    mkdir \"${_GIT_REMOTE_PATH}.setup\"     &&\n      cd \"${_GIT_REMOTE_PATH}.setup\"      &&\n      git init                            &&\n      git checkout -b \"${_branch_name}\"   &&\n      touch '.index'                      &&\n      git add --all                       &&\n      git commit -a -m \"Initial commit.\"  &&\n      git clone --bare \"${_GIT_REMOTE_PATH}.setup\" \"${_GIT_REMOTE_PATH}\" &&\n      cd \"${_GIT_REMOTE_PATH}\"            &&\n      git remote rm \"origin\"\n\n      cd \"${_pwd}\" || exit\n  fi\n}\n"
  },
  {
    "path": "test/todo-add.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031,SC2063\n\nload test_helper\n\n# templates ###################################################################\n\n@test \"'add todo <title>' with assigned \\$NB_DEFAULT_TEMPLATE skips the template and creates new todo.\" {\n  {\n    \"${_NB}\" init\n\n    export NB_DEFAULT_TEMPLATE=\"Example template with no template tags.\"\n  }\n\n  run \"${_NB}\" add todo \"Example todo title.\" \\\n    --related \"http://example.com\"            \\\n    --related \"example:123\"                   \\\n    --related \"[[sample:456]]\"                \\\n    --related \"Example Title\"                 \\\n    --tag     tag1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ todo\\ title\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(cat <<HEREDOC\n# [ ] Example todo title.\n\n## Related\n\n- <http://example.com>\n- [[example:123]]\n- [[sample:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1\nHEREDOC\n)\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n# edge cases ##################################################################\n\n@test \"'todo add check <multi-word> <description>' exits with 0, creates new todo with 'check <multi-word> <description>' as title, creates commit.\" {\n\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add check example multi-word description.\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(printf \"# [ ] check example multi-word description.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ check\\ example\\ multi-word\\ description\\.\\\"  ]]\n}\n\n# `add todo` ##################################################################\n\n@test \"'add todo <title> --related <URL> --related <selector> --tag <tag>' exits with 0, creates new todo with <title> as title, related items, and tag, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" add todo \"Example todo title.\" \\\n    --related \"http://example.com\"            \\\n    --related \"example:123\"                   \\\n    --related \"[[sample:456]]\"                \\\n    --related \"Example Title\"                 \\\n    --tag     tag1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ todo\\ title\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(cat <<HEREDOC\n# [ ] Example todo title.\n\n## Related\n\n- <http://example.com>\n- [[example:123]]\n- [[sample:456]]\n- [[Example Title]]\n\n## Tags\n\n#tag1\nHEREDOC\n)\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n# aliases #####################################################################\n\n@test \"'todo a <multi-word> <description>' exits with 0, creates new todo with <multi-word> <description>, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo a Example multi-word description.\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(printf \"# [ ] Example multi-word description.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ multi-word\\ description\\.\\\"  ]]\n}\n\n@test \"'todo + <multi-word> <description>' exits with 0, creates new todo with <multi-word> <description>, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo + Example multi-word description.\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(printf \"# [ ] Example multi-word description.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ multi-word\\ description\\.\\\"  ]]\n}\n\n# container selectors #########################################################\n\n@test \"'todo add <notebook>: <multi-word> <description>' exits with 0, creates new todo in <notebook> with <multi-word> <description>, creates commit.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" todo add Example\\ Notebook: Example multi-word description.\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                 ]]\n\n  _home_files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_home_files[@]}\" -eq 0             ]]\n\n  _files=($(ls \"${NB_DIR}/Example Notebook/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                 ]]\n  [[ \"${_files[0]}\"   =~ ^[0-9]+\\.todo\\.md$ ]]\n\n  cat \"${NB_DIR}/Example Notebook/${_files[0]}\"\n\n  diff                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/${_files[0]}\")  \\\n    <(printf \"# [ ] Example multi-word description.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/Example Notebook\" log | grep -q '\\[nb\\] Add'\n\n  [[ \"${lines[0]}\"  =~  \\\nAdded:\\ .*\\[.*Example\\ Notebook:1.*\\].*\\ ✔️\\ \\ .*Example\\ Notebook:[0-9]+\\.todo\\.md        ]]\n  [[ \"${lines[0]}\"  =~  \\\nExample\\ Notebook:[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ multi-word\\ description\\.\\\"  ]]\n}\n\n@test \"'todo add <folder> <multi-word> <description>' exits with 0, creates new todo in <folder> with <multi-word> <description>, creates commit.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder\" --type \"folder\"\n  }\n\n  run \"${_NB}\" todo add Example\\ Folder/ Example multi-word description.\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n\n  _files=($(ls \"${NB_DIR}/home/Example Folder/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/Example Folder/${_files[0]}\"\n\n  diff                                                        \\\n    <(cat \"${NB_DIR}/home/Example Folder/${_files[0]}\")       \\\n    <(printf \"# [ ] Example multi-word description.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n\n  [[ \"${lines[0]}\"    =~  \\\nAdded:\\ .*\\[.*Example\\ Folder/1.*\\].*\\ ✔️\\ \\ .*Example\\ Folder/[0-9]+\\.todo\\.md          ]]\n  [[ \"${lines[0]}\"    =~  \\\nExample\\ Folder/[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ multi-word\\ description\\.\\\"  ]]\n}\n\n# --related ###################################################################\n\n@test \"'todo add <title> --related <URL> --relared <selector>' exits with 0, creates new todo with <title> as title and related items, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add \"Example todo title.\" \\\n    --related \"http://example.com\"            \\\n    --related \"example:123\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ todo\\ title\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(cat <<HEREDOC\n# [ ] Example todo title.\n\n## Related\n\n- <http://example.com>\n- [[example:123]]\nHEREDOC\n)\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n# --tag #######################################################################\n\n@test \"'todo add <title> --tag <one> --tag <two>' exits with 0, creates new todo with <title> as title and tags, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add \"Example todo title.\" \\\n    --tag \"tag1\"                              \\\n    --tag \"tag2\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ todo\\ title\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(cat <<HEREDOC\n# [ ] Example todo title.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n# --task ######################################################################\n\n@test \"'todo add <title> --task <one> --task <two>' exits with 0, creates new todo with <title> as title and tasklist, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add \"Example todo title.\" \\\n    --task \"Task title one.\"                  \\\n    --task \"Task title two.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq  0                  ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ todo\\ title\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(cat <<HEREDOC\n# [ ] Example todo title.\n\n## Tasks\n\n- [ ] Task title one.\n- [ ] Task title two.\nHEREDOC\n)\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n# --description ###############################################################\n\n@test \"'todo add --description' with no <description> exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add \"Example content.\" --description\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 1                                   ]]\n  [[ \"${output}\"      =~  \\\n\\!.*\\ .*--description.*\\ requires\\ a\\ valid\\ argument\\.       ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  -eq 0                                   ]]\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Add'\n}\n\n# --due #######################################################################\n\n@test \"'todo add --due' with no <date> exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add \"Example content.\" --due\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 1                     ]]\n  [[ \"${output}\"      =~  \\\n\\!.*\\ .*--due.*\\ requires\\ a\\ valid\\ argument\\. ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  -eq 0                     ]]\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Add'\n}\n\n@test \"'todo add <title> --description <description> --due <datetime>' exits with 0, creates new todo with <title> as title, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add \"Example todo title.\" \\\n    --description \"Example description.\"      \\\n    --due         \"2200-01-01\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ todo\\ title\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(cat <<HEREDOC\n# [ ] Example todo title.\n\n## Due\n\n2200-01-01\n\n## Description\n\nExample description.\nHEREDOC\n)\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n# todo add ####################################################################\n\n@test \"'todo add' with no <title> exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 1                 ]]\n  [[ \"${lines[0]}\"    =~  Usage             ]]\n  [[ \"${lines[1]}\"    =~  todo\\ add         ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  -eq 0                 ]]\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Add'\n}\n\n@test \"'todo add <title>' exits with 0, creates new todo with <title> as title, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add \"Example todo title.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ todo\\ title\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(printf \"# [ ] Example todo title.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'todo add <title> --edit' exits with 0, creates new todo with \\$EDITOR, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add \"Example todo title.\" --edit\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ todo\\ title\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(printf \"\\\n# [ ] Example todo title.\n# mock_editor %s/home/%s\\\\n\" \"${NB_DIR}\" \"${_files[0]%.md}\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'todo add <title> --description <description>' exits with 0, creates new todo with <title> and <description>, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add \"Example todo title.\" --description \"Example description.\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ todo\\ title\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(printf \"\\\n# [ ] Example todo title.\n\n## Description\n\nExample description.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'todo add <description> --content <content> --title <title>' exits with 0, creates new todo with <description>, <content>, and <title>, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add           \\\n    \"Example todo description.\"   \\\n    --content \"Example content.\"  \\\n    --title   \"Example Title\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ Title\\ ·\\ Example\\ todo\\ description\\.\\\"  ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                  ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$ ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(printf \"\\\n# [ ] Example Title · Example todo description.\n\nExample content.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n}\n\n@test \"'todo add <multi-word> <description>' exits with 0, creates new todo with <multi-word> <description>, creates commit.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo add Example multi-word description.\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                   ]]\n\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  printf \"\\${_files[*]}: '%s'\\\\n\" \"${_files[*]:-}\"\n\n  [[ \"${#_files[@]}\"  -eq 1                   ]]\n  [[ \"${_files[0]}\"   =~  ^[0-9]+\\.todo\\.md$  ]]\n\n  cat \"${NB_DIR}/home/${_files[0]}\"\n\n  diff                                        \\\n    <(cat \"${NB_DIR}/home/${_files[0]}\")      \\\n    <(printf \"# [ ] Example multi-word description.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Add'\n\n  [[ \"${output}\"      =~  \\\nAdded:\\ .*\\[.*1.*\\].*\\ ✔️\\ \\ .*[0-9]+\\.todo\\.md.*\\ \\\".*\\[\\ \\].*\\ Example\\ multi-word\\ description\\.\\\"  ]]\n}\n"
  },
  {
    "path": "test/todo-delete.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031,SC2063\n\nload test_helper\n\n# todo delete #################################################################\n\n@test \"'todo delete <notebook>:<folder>/<id>' with positive confirmation prompt exits with 0, deletes todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/Example Notebook/.index\")\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" todo delete Example\\ Notebook:Example\\ Folder/3 <<< \"y${NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/Example Notebook/Example Folder/Three.todo.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/Example Notebook\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/Example Notebook/Example Folder/.index\"            ]]\n  [[    \"$(ls \"${NB_DIR}/Example Notebook/Example Folder\")\"  == \\\n          \"$(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\" ]]\n  [[    \"${_original_index}\"                  != \\\n          \"$(cat \"${NB_DIR}/Example Notebook/Example Folder/.index\")\" ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                                                   ]]\n  [[ \"${output}\" =~   Deleted:                                            ]]\n  [[ \"${output}\" =~   Example\\ Notebook:.*Example\\ Folder/Three.todo.md.* ]]\n}\n\n@test \"'todo delete <id>' with postive confirmation prompt exits with 0, deletes todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Three.todo.md\"\n\n    _original_index=\"$(cat \"${NB_DIR}/home/.index\")\"\n  }\n\n  run \"${_NB}\" todo delete 3 <<< \"y${NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Three.todo.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log | grep -q '\\[nb\\] Delete'\n\n  # Deletes entry from index:\n\n  [[ -e \"${NB_DIR}/home/.index\"             ]]\n  [[    \"$(ls \"${NB_DIR}/home\")\"  == \\\n          \"$(cat \"${NB_DIR}/home/.index\")\"  ]]\n  [[    \"${_original_index}\"      != \\\n          \"$(cat \"${NB_DIR}/home/.index\")\"  ]]\n\n  # Prints output:\n\n  [[ \"${status}\" -eq  0                 ]]\n  [[ \"${output}\" =~   Deleted:          ]]\n  [[ \"${output}\" =~   .*Three.todo.md.* ]]\n}\n\n@test \"'todo delete <id>' with negative response exits with 0.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Three.todo.md\"\n  }\n\n  run \"${_NB}\" todo delete 3 <<< \"n${NEWLINE}\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 0                       ]]\n  [[ \"${lines[0]}\"    =~  Deleting.*Three.todo.md ]]\n  [[ \"${lines[1]}\"    =~  Exiting\\.\\.\\.           ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  -eq 3                       ]]\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Deleted'\n}\n\n@test \"'todo delete' with no selector exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo delete\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 1               ]]\n  [[ \"${lines[0]}\"    =~  Usage.*:        ]]\n  [[ \"${lines[1]}\"    =~  ${_ME}\\ todo    ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  -eq 0               ]]\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Deleted'\n}\n\n# <title> #####################################################################\n\n@test \"'todo delete folder/<title>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.todo.md\"                  \\\n      --content \"# [ ] Sample todo description.\"\n\n    \"${_NB}\" add \"Example Folder/Example File.todo.md\"  \\\n      --content \"# [ ] Example todo description.\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.todo.md\" ]]\n  }\n\n  run \"${_NB}\" delete \"Example Folder/Example todo description.\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes  file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.todo.md\"  ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Example File.todo.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/1                     ]]\n  [[ \"${output}\" =~ ✔️                                     ]]\n  [[ \"${output}\" =~ Example\\ Folder/Example\\ File.todo.md ]]\n}\n\n@test \"'todo delete folder/folder/<title>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.todo.md\"                                \\\n      --content \"# [ ] Sample todo description.\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.todo.md\"  \\\n      --content \"# [ ] Example todo description.\"\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.todo.md\"  ]]\n  }\n\n  run \"${_NB}\" delete \"Example Folder/Sample Folder/Example todo description.\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.todo.md\"    ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Sample Folder/Example File.todo.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                              ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/1                      ]]\n  [[ \"${output}\" =~ ✔️                                                     ]]\n  [[ \"${output}\" =~ Example\\ Folder/Sample\\ Folder/Example\\ File.todo.md  ]]\n}\n\n@test \"'todo delete notebook:folder/<title>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.tod.md\"                  \\\n      --content \"# [ ] Sample todo description.\"\n\n    \"${_NB}\" add \"Example Folder/Example File.todo.md\"  \\\n      --content \"# [ ] Example todo description.\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Example File.todo.md\"  ]]\n  }\n\n  run \"${_NB}\" delete \"home:Example Folder/Example todo description.\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Example File.todo.md\"    ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Example File.todo.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                    ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/1                      ]]\n  [[ \"${output}\" =~ ✔️                                           ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Example\\ File.todo.md  ]]\n}\n\n@test \"'todo delete notebook:folder/folder/<title>' deletes properly without errors.\" {\n  {\n    \"${_NB}\" init\n    \"${_NB}\" add \"Sample File.todo.md\"                                \\\n      --content \"# [ ] Sample todo description.\"\n\n    \"${_NB}\" add \"Example Folder/Sample Folder/Example File.todo.md\"  \\\n      --content \"# [ ] Example todo description.\"\n\n    \"${_NB}\" notebooks add \"one\"\n    \"${_NB}\" notebooks use \"one\"\n\n    [[ \"$(\"${_NB}\" notebooks current)\" == \"one\" ]]\n\n    [[   -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.todo.md\"  ]]\n  }\n\n  run \"${_NB}\" delete \"home:Example Folder/Sample Folder/Example todo description.\" --force\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  # Returns status 0:\n\n  [[ ${status} -eq 0 ]]\n\n  # Deletes file:\n\n  [[ ! -e \"${NB_DIR}/home/Example Folder/Sample Folder/Example File.todo.md\"    ]]\n\n  # Creates git commit:\n\n  cd \"${NB_DIR}/home\" || return 1\n  while [[ -n \"$(git status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git log\n  git log | grep -q '\\[nb\\] Delete: .*Example Folder/Sample Folder/Example File.todo.md'\n\n  # Prints output:\n\n  [[ \"${output}\" =~ Deleted:                                                  ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/1                     ]]\n  [[ \"${output}\" =~ ✔️                                                         ]]\n  [[ \"${output}\" =~ home:Example\\ Folder/Sample\\ Folder/Example\\ File.todo.md ]]\n}\n"
  },
  {
    "path": "test/todo-tasks.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031,SC2063,SC2076\n\nload test_helper\n\n# recursive ###################################################################\n\n@test \"'tasks --recursive' exits with 0 and lists todos and tasks recursively in the current notebook.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/One.todo.md\"           \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n- [ ] todo one task one.\n- [ ] todo one task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/Two.todo.md\"           \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description two.\n\n- [ ] todo two task one.\n- [x] todo two task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/Three.todo.md\"         \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description three.\n\n- [x] todo three task one.\n- [x] todo three task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Sample todo description one.\"    \\\n      --filename \"Sample Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"One.todo.md\"                          \\\n      --content \"$(cat <<HEREDOC\n# [x] Root todo description one.\n\n- [x] root todo one task one.\n- [x] root todo one task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Two.todo.md\"                          \\\n      --content \"$(cat <<HEREDOC\n# [ ] Root todo description two.\n\n- [ ] root todo two task one.\n- [x] root todo two task two.\nHEREDOC\n      )\"\n  }\n\n  run \"${_NB}\" tasks --recursive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0       ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/3.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\. ]]\n  [[    \"${lines[1]}\"   =~  ---                                           ]]\n  [[    \"${lines[2]}\"   =~  \\\n.*\\[.*Example\\ Folder/3\\ 1.*\\].*\\ .*\\[.*x.*\\].*\\ todo\\ three\\ task\\ one\\. ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*\\[.*Example\\ Folder/3\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ todo\\ three\\ task\\ two\\. ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Folder/2.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ two\\.     ]]\n  [[    \"${lines[5]}\"   =~  ---                                           ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*\\[.*Example\\ Folder/2\\ 1.*\\].*\\ .*\\[.*\\ .*\\].*\\ todo\\ two\\ task\\ one\\.  ]]\n  [[    \"${lines[7]}\"   =~  \\\n.*\\[.*Example\\ Folder/2\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ todo\\ two\\ task\\ two\\.   ]]\n\n  [[    \"${lines[8]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.     ]]\n  [[    \"${lines[9]}\"   =~  ---                                           ]]\n  [[    \"${lines[10]}\"  =~  \\\n.*\\[.*Example\\ Folder/1\\ 1.*\\].*\\ .*\\[.*\\ .*\\].*\\ todo\\ one\\ task\\ one\\.  ]]\n  [[    \"${lines[11]}\"  =~  \\\n.*\\[.*Example\\ Folder/1\\ 2.*\\].*\\ .*\\[.*\\ .*\\].*\\ todo\\ one\\ task\\ two\\.  ]]\n\n  [[    \"${lines[12]}\"   =~  \\\n.*\\[.*Sample\\ Folder/1.*\\].*\\ ✔️\\ .*\\[.*\\ .*\\].*\\ Sample\\ todo\\ description\\ one\\.     ]]\n\n  [[    \"${lines[13]}\"   =~  \\\n.*\\[.*4.*\\].*\\ ✔️\\ .*\\[.*\\ .*\\].*\\ Root\\ todo\\ description\\ two\\.  ]]\n  [[    \"${lines[14]}\"   =~  ---                                  ]]\n  [[    \"${lines[15]}\"   =~  \\\n.*\\[.*4\\ 1.*\\].*\\ .*\\[.*\\ .*\\].*\\ root\\ todo\\ two\\ task\\ one\\.    ]]\n  [[    \"${lines[16]}\"   =~  \\\n.*\\[.*4\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ root\\ todo\\ two\\ task\\ two\\.     ]]\n\n  [[    \"${lines[17]}\"   =~  \\\n.*\\[.*3.*\\].*\\ ✅\\ .*\\[.*\\x.*\\].*\\ Root\\ todo\\ description\\ one\\. ]]\n  [[    \"${lines[18]}\"   =~  ---                                  ]]\n  [[    \"${lines[19]}\"   =~  \\\n.*\\[.*3\\ 1.*\\].*\\ .*\\[.*\\x.*\\].*\\ root\\ todo\\ one\\ task\\ one\\.    ]]\n  [[    \"${lines[20]}\"   =~  \\\n.*\\[.*3\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ root\\ todo\\ one\\ task\\ two\\.     ]]\n}\n\n@test \"'tasks <notebook>: --recursive' exits with 0 and lists todos and tasks recursively in <notebook>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/One.todo.md\"           \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n- [ ] todo one task one.\n- [ ] todo one task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/Two.todo.md\"           \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description two.\n\n- [ ] todo two task one.\n- [x] todo two task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/Three.todo.md\"         \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description three.\n\n- [x] todo three task one.\n- [x] todo three task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Sample todo description one.\"    \\\n      --filename \"Sample Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"One.todo.md\"                          \\\n      --content \"$(cat <<HEREDOC\n# [x] Root todo description one.\n\n- [x] root todo one task one.\n- [x] root todo one task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Two.todo.md\"                          \\\n      --content \"$(cat <<HEREDOC\n# [ ] Root todo description two.\n\n- [ ] root todo two task one.\n- [x] root todo two task two.\nHEREDOC\n      )\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" tasks Example\\ Notebook: --recursive\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0       ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\. ]]\n  [[    \"${lines[1]}\"   =~  ---                                                                         ]]\n  [[    \"${lines[2]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3\\ 1.*\\].*\\ .*\\[.*x.*\\].*\\ todo\\ three\\ task\\ one\\. ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ todo\\ three\\ task\\ two\\. ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/2.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ two\\.     ]]\n  [[    \"${lines[5]}\"   =~  ---                                                                         ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/2\\ 1.*\\].*\\ .*\\[.*\\ .*\\].*\\ todo\\ two\\ task\\ one\\.  ]]\n  [[    \"${lines[7]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/2\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ todo\\ two\\ task\\ two\\.   ]]\n\n  [[    \"${lines[8]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/1.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.     ]]\n  [[    \"${lines[9]}\"   =~  ---                                                                         ]]\n  [[    \"${lines[10]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/1\\ 1.*\\].*\\ .*\\[.*\\ .*\\].*\\ todo\\ one\\ task\\ one\\.  ]]\n  [[    \"${lines[11]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/1\\ 2.*\\].*\\ .*\\[.*\\ .*\\].*\\ todo\\ one\\ task\\ two\\.  ]]\n\n  [[    \"${lines[12]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Sample\\ Folder/1.*\\].*\\ ✔️\\ .*\\[.*\\ .*\\].*\\ Sample\\ todo\\ description\\ one\\.     ]]\n\n  [[    \"${lines[13]}\"   =~  \\\n.*\\[.*Example\\ Notebook:4.*\\].*\\ ✔️\\ .*\\[.*\\ .*\\].*\\ Root\\ todo\\ description\\ two\\.  ]]\n  [[    \"${lines[14]}\"   =~  ---                                                    ]]\n  [[    \"${lines[15]}\"   =~  \\\n.*\\[.*Example\\ Notebook:4\\ 1.*\\].*\\ .*\\[.*\\ .*\\].*\\ root\\ todo\\ two\\ task\\ one\\.    ]]\n  [[    \"${lines[16]}\"   =~  \\\n.*\\[.*Example\\ Notebook:4\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ root\\ todo\\ two\\ task\\ two\\.     ]]\n\n  [[    \"${lines[17]}\"   =~  \\\n.*\\[.*Example\\ Notebook:3.*\\].*\\ ✅\\ .*\\[.*\\x.*\\].*\\ Root\\ todo\\ description\\ one\\. ]]\n  [[    \"${lines[18]}\"   =~  ---                                                    ]]\n  [[    \"${lines[19]}\"   =~  \\\n.*\\[.*Example\\ Notebook:3\\ 1.*\\].*\\ .*\\[.*\\x.*\\].*\\ root\\ todo\\ one\\ task\\ one\\.    ]]\n  [[    \"${lines[20]}\"   =~  \\\n.*\\[.*Example\\ Notebook:3\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ root\\ todo\\ one\\ task\\ two\\.     ]]\n}\n\n# selectors and listing #######################################################\n\n@test \"'tasks <notebook>:' with empty notebook exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" tasks Example\\ Notebook:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1               ]]\n  [[    \"${#lines[@]}\"  -eq 1               ]]\n\n  [[    \"${lines[0]}\"   =~  \\!.*\\ 0\\ tasks. ]]\n}\n\n@test \"'tasks <notebook>:' exits with 0 and lists todos and tasks at root level of <notebook>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/One.todo.md\"           \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n- [ ] todo one task one.\n- [ ] todo one task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/Two.todo.md\"           \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description two.\n\n- [ ] todo two task one.\n- [x] todo two task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/Three.todo.md\"         \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description three.\n\n- [x] todo three task one.\n- [x] todo three task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Sample todo description one.\"    \\\n      --filename \"Sample Folder/One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --filename \"One.todo.md\"                          \\\n      --content \"$(cat <<HEREDOC\n# [x] Root todo description one.\n\n- [x] root todo one task one.\n- [x] root todo one task two.\nHEREDOC\n      )\"\n\n    \"${_NB}\" add                                        \\\n      --filename \"Two.todo.md\"                          \\\n      --content \"$(cat <<HEREDOC\n# [ ] Root todo description two.\n\n- [ ] root todo two task one.\n- [x] root todo two task two.\nHEREDOC\n      )\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" tasks Example\\ Notebook:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0       ]]\n\n  [[ !  \"${output}\"   =~  Four    ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Notebook:4.*\\].*\\ ✔️\\ .*\\[.*\\ .*\\].*\\ Root\\ todo\\ description\\ two\\.  ]]\n  [[    \"${lines[1]}\"   =~  ---                                                     ]]\n  [[    \"${lines[2]}\"   =~  \\\n.*\\[.*Example\\ Notebook:4\\ 1.*\\].*\\ .*\\[.*\\ .*\\].*\\ root\\ todo\\ two\\ task\\ one\\.    ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*\\[.*Example\\ Notebook:4\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ root\\ todo\\ two\\ task\\ two\\.     ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Notebook:3.*\\].*\\ ✅\\ .*\\[.*\\x.*\\].*\\ Root\\ todo\\ description\\ one\\. ]]\n  [[    \"${lines[5]}\"   =~  ---                                                     ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*\\[.*Example\\ Notebook:3\\ 1.*\\].*\\ .*\\[.*\\x.*\\].*\\ root\\ todo\\ one\\ task\\ one\\.    ]]\n  [[    \"${lines[7]}\"   =~  \\\n.*\\[.*Example\\ Notebook:3\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ root\\ todo\\ one\\ task\\ two\\.     ]]\n}\n\n@test \"'tasks <notebook>:<folder>/' exits with 0 and lists todos and tasks in <folder>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/One.todo.md\"           \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n- [ ] todo one task one.\n- [ ] todo one task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/Two.todo.md\"           \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description two.\n\n- [ ] todo two task one.\n- [x] todo two task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --filename \"Example Folder/Three.todo.md\"         \\\n      --content \"# [x] Example todo description three.\" \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description three.\n\n- [x] todo three task one.\n- [x] todo three task two.\nHEREDOC\n      )\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Sample todo description one.\"    \\\n      --filename \"Sample Folder/One.todo.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" tasks Example\\ Notebook:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0       ]]\n\n  [[ !  \"${output}\"   =~  Four    ]]\n  [[ !  \"${output}\"   =~  Sample  ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\. ]]\n  [[    \"${lines[1]}\"   =~  ---                                                                         ]]\n  [[    \"${lines[2]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3\\ 1.*\\].*\\ .*\\[.*x.*\\].*\\ todo\\ three\\ task\\ one\\. ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ todo\\ three\\ task\\ two\\. ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/2.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ two\\.     ]]\n  [[    \"${lines[5]}\"   =~  ---                                                                         ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/2\\ 1.*\\].*\\ .*\\[.*\\ .*\\].*\\ todo\\ two\\ task\\ one\\.  ]]\n  [[    \"${lines[7]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/2\\ 2.*\\].*\\ .*\\[.*x.*\\].*\\ todo\\ two\\ task\\ two\\.   ]]\n\n  [[    \"${lines[8]}\"   =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/1.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.     ]]\n  [[    \"${lines[9]}\"   =~  ---                                                                         ]]\n  [[    \"${lines[10]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/1\\ 1.*\\].*\\ .*\\[.*\\ .*\\].*\\ todo\\ one\\ task\\ one\\.  ]]\n  [[    \"${lines[11]}\"  =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/1\\ 2.*\\].*\\ .*\\[.*\\ .*\\].*\\ todo\\ one\\ task\\ two\\.  ]]\n}\n\n# line wrapping ###############################################################\n\n@test \"'tasks <folder>/<id> <task-number>' exits with 0 and lists individual tasks with wrapping.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one with example sample demo test long title to test task list line-wrapping behavior one.\n- [] Task two with example sample demo test long title to test task list line-wrapping behavior two.\n- [x] Task three with example sample demo test long title to test task list line-wrapping behavior three.\n  - [ ] Task four with example sample demo test long title to test task list line-wrapping behavior four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks Example\\ Folder/1 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 3 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n\n  [[    \"${lines[0]}\"   =~ \"$(printf '\\033[?7l')\" ]]\n  [[    \"${lines[0]}\"   =~ \"$(printf '\\033[?7h')\" ]]\n\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[ !  \"${lines[1]}\"   =~ \"$(printf '\\033[?7l')\" ]]\n  [[ !  \"${lines[1]}\"   =~ \"$(printf '\\033[?7h')\" ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\ with\\ example\\ sample                        ]]\n  [[    \"${lines[2]}\"   =~  \\\nexample\\ sample\\ demo\\ test\\ long\\ title\\ to\\ test\\ task\\ list\\ line\\-wrapping\\ behavior\\ two\\.   ]]\n\n  [[ !  \"${lines[2]}\"   =~ \"$(printf '\\033[?7l')\" ]]\n  [[ !  \"${lines[2]}\"   =~ \"$(printf '\\033[?7h')\" ]]\n}\n\n@test \"'tasks <folder>/<id>' exits with 0 and lists multiple tasks without wrapping.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one with example sample demo test long title to test task list line-wrapping behavior one.\n- [] Task two with example sample demo test long title to test task list line-wrapping behavior two.\n- [x] Task three with example sample demo test long title to test task list line-wrapping behavior three.\n  - [ ] Task four with example sample demo test long title to test task list line-wrapping behavior four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 6 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n\n  [[    \"${lines[0]}\"   =~ \"$(printf '\\033[?7l')\" ]]\n  [[    \"${lines[0]}\"   =~ \"$(printf '\\033[?7h')\" ]]\n\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[ !  \"${lines[1]}\"   =~ \"$(printf '\\033[?7l')\" ]]\n  [[ !  \"${lines[1]}\"   =~ \"$(printf '\\033[?7h')\" ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\ with\\ example\\ sample                        ]]\n  [[    \"${lines[2]}\"   =~  \\\nexample\\ sample\\ demo\\ test\\ long\\ title\\ to\\ test\\ task\\ list\\ line\\-wrapping\\ behavior\\ one\\.   ]]\n\n  [[    \"${lines[2]}\"   =~ \"$(printf '\\033[?7l')\" ]]\n  [[    \"${lines[2]}\"   =~ \"$(printf '\\033[?7h')\" ]]\n\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\ with\\ example\\ sample                        ]]\n  [[    \"${lines[3]}\"   =~  \\\nexample\\ sample\\ demo\\ test\\ long\\ title\\ to\\ test\\ task\\ list\\ line\\-wrapping\\ behavior\\ two\\.   ]]\n\n  [[    \"${lines[3]}\"   =~ \"$(printf '\\033[?7l')\" ]]\n  [[    \"${lines[3]}\"   =~ \"$(printf '\\033[?7h')\" ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\ with\\ example\\ sample                   ]]\n  [[    \"${lines[4]}\"   =~  \\\nexample\\ sample\\ demo\\ test\\ long\\ title\\ to\\ test\\ task\\ list\\ line\\-wrapping\\ behavior\\ three\\. ]]\n\n  [[    \"${lines[4]}\"   =~ \"$(printf '\\033[?7l')\" ]]\n  [[    \"${lines[4]}\"   =~ \"$(printf '\\033[?7h')\" ]]\n\n  [[    \"${lines[5]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\ with\\ example\\ sample                        ]]\n  [[    \"${lines[5]}\"   =~  \\\nexample\\ sample\\ demo\\ test\\ long\\ title\\ to\\ test\\ task\\ list\\ line\\-wrapping\\ behavior\\ four\\.   ]]\n\n  [[    \"${lines[5]}\"   =~ \"$(printf '\\033[?7l')\" ]]\n  [[    \"${lines[5]}\"   =~ \"$(printf '\\033[?7h')\" ]]\n}\n\n# do task #####################################################################\n\n@test \"'tasks do <folder>/<id> <task-number>' with non-todo and open task with no space in brackets exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks \"do\" Example\\ Folder/1 2\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  .*\\[.*Example\\ Folder/1.*].*\\ Example\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  [^-]------------------------------------[^-]      ]]\n  [[    \"${lines[2]}\"   =~  \\\nDone:\\ .*\\[.*Example\\ Folder/1\\ 2.*\\].*\\ .*[.*x.*].*\\ Task\\ two\\.             ]]\n}\n\n@test \"'tasks do <folder>/<id> <task-number>' with non-todo and open task with space in brackets exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks \"do\" Example\\ Folder/1 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  .*\\[.*Example\\ Folder/1.*].*\\ Example\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  [^-]------------------------------------[^-]      ]]\n  [[    \"${lines[2]}\"   =~  \\\nDone:\\ .*\\[.*Example\\ Folder/1\\ 2.*\\].*\\ .*[.*x.*].*\\ Task\\ two\\.             ]]\n}\n\n@test \"'tasks do <folder>/<id> <task-number>' with open task with no space in brackets exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks \"do\" Example\\ Folder/1 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/Todo One.todo.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\nDone:\\ .*\\[.*Example\\ Folder/1\\ 2.*\\].*\\ .*[.*x.*].*\\ Task\\ two\\. ]]\n}\n\n@test \"'tasks do <folder>/<id> <task-number>' with open task with space in brackets exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks \"do\" Example\\ Folder/1 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/Todo One.todo.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\nDone:\\ .*\\[.*Example\\ Folder/1\\ 2.*\\].*\\ .*[.*x.*].*\\ Task\\ two\\. ]]\n}\n\n@test \"'tasks do <folder>/<id> <task-number>' with indented open task with space in brackets exits with 0 and marks task done.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks \"do\" Example\\ Folder/1 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/Todo One.todo.md\"\n\n  [[    \"${status}\"     -eq 0                                       ]]\n  [[    \"${#lines[@]}\"  -eq 3                                       ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\nDone:\\ .*\\[.*Example\\ Folder/1\\ 4.*\\].*\\ .*[.*x.*].*\\ Task\\ four\\.  ]]\n}\n\n# undo task ###################################################################\n\n@test \"'tasks undo <folder>/<id> <task-number>' with non-todo and indented closed task exits with 0 and marks task undone.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n  - [x] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks \"undo\" Example\\ Folder/1 4\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  .*\\[.*Example\\ Folder/1.*].*\\ Example\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  [^-]------------------------------------[^-]      ]]\n  [[    \"${lines[2]}\"   =~  \\\nUndone:\\ .*\\[.*Example\\ Folder/1\\ 4.*\\].*\\ .*[\\ ].*\\ Task\\ four\\.             ]]\n}\n\n@test \"'tasks undo <folder>/<id> <task-number>' with non-todo and closed task exits with 0 and marks task undone.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/File One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Title One\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks \"undo\" Example\\ Folder/1 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/File One.md\"\n\n  [[    \"${status}\"     -eq 0                                     ]]\n  [[    \"${#lines[@]}\"  -eq 3                                     ]]\n\n  [[    \"${lines[0]}\"   =~  .*\\[.*Example\\ Folder/1.*].*\\ Example\\ Title\\ One ]]\n  [[    \"${lines[1]}\"   =~  [^-]------------------------------------[^-]      ]]\n  [[    \"${lines[2]}\"   =~  \\\nUndone:\\ .*\\[.*Example\\ Folder/1\\ 3.*\\].*\\ .*[\\ ].*\\ Task\\ three\\.            ]]\n}\n\n@test \"'tasks undo <folder>/<id> <task-number>' with closed task exits with 0 and marks task undone.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [ ] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks \"undo\" Example\\ Folder/1 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  cat \"${NB_DIR}/home/Example Folder/Todo One.todo.md\"\n\n  [[    \"${status}\"     -eq 0                                       ]]\n  [[    \"${#lines[@]}\"  -eq 3                                       ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\nUndone:\\ .*\\[.*Example\\ Folder/1\\ 3.*\\].*\\ .*[\\ ].*\\ Task\\ three\\.  ]]\n}\n\n# tasks subcommand ############################################################\n\n@test \"'tasks open <folder>/<id>' exits with 0 and lists open tasks in the item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks open Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 5                           ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.   ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.   ]]\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.  ]]\n}\n\n@test \"'tasks closed <folder>/<id>' exits with 0 and lists closed tasks in the item.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                      \\\n      --filename  \"Example Folder/Todo One.todo.md\"   \\\n      --content   \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks closed Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 3                                   ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*\\[.*Example\\ Folder/1\\ 3.*\\].*\\ .*\\[.*x.*\\].*\\ Task\\ three\\.  ]]\n}\n\n@test \"'tasks <folder>/<id>' exits with 0 and lists tasks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                      \\\n      --filename \"Example Folder/Todo One.todo.md\"    \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" tasks Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 6                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.       ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.       ]]\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.  ]]\n  [[    \"${lines[5]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.      ]]\n}\n\n# todos tasks <id> <task-number> ##############################################\n\n@test \"'todos tasks open <folder>/<id> <not-valid-number>' exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks Example\\ Folder/1 123\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                   ]]\n  [[    \"${#lines[@]}\"  -eq 3                   ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  0\\ matching\\ tasks. ]]\n}\n\n@test \"'todos tasks closed <folder>/<id> 3' exits with 0 and lists task.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks closed Example\\ Folder/1 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 3                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.  ]]\n}\n\n@test \"'todos tasks <folder>/<id> 3' exits with 0 and lists task.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks Example\\ Folder/1 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 3                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.  ]]\n}\n\n# todos tasks #################################################################\n\n@test \"'todos tasks open <folder>/<id>' exits with 0 and lists open tasks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks open Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                           ]]\n  [[    \"${#lines[@]}\"  -eq 5                           ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.   ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.   ]]\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.  ]]\n}\n\n@test \"'todos tasks closed <folder>/<id>' exits with 0 and lists closed tasks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks closed Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                                   ]]\n  [[    \"${#lines[@]}\"  -eq 3                                   ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*\\[.*Example\\ Folder/1\\ 3.*\\].*\\ .*\\[.*x.*\\].*\\ Task\\ three\\.  ]]\n}\n\n@test \"'todos tasks <folder>/<id>' exits with 0 and lists tasks.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0                               ]]\n  [[    \"${#lines[@]}\"  -eq 6                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n\n  [[    \"${lines[2]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.       ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.       ]]\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.  ]]\n  [[    \"${lines[5]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.      ]]\n}\n\n# todo tasks <folder> #########################################################\n\n@test \"'todos tasks open <folder>' exits with 0 and lists open todos and tasks in folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n  - [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/Note One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Note Title One.\n\nExample content.\n\n- [x] Task one.\n- [ ] Task two.\n- [ ] Task three.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note Two.md\"      \\\n      --content   \"Example note content two.\"\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo Two.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [x] Task two.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Three.todo.md\"   \\\n      --content   \"# [x] Example todo description three.\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Four.todo.md\"    \\\n      --content   \"# [ ] Example todo description four.\"\n  }\n\n  run \"${_NB}\" todos tasks open Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 13  ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/6.*].*\\ ✔️\\ \\ *[\\ ].*\\ Example\\ todo\\ description\\ four\\.      ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*\\[.*Example\\ Folder/4.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n  [[    \"${lines[2]}\"   =~  .*------------------------------------.*                ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                               ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Folder/2.*].*\\ Example\\ Note\\ Title\\ One.              ]]\n  [[    \"${lines[5]}\"   =~  .*------------------------------------.*  ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                 ]]\n  [[    \"${lines[7]}\"  =~  \\\n.*[.*Example\\ Folder/2\\ 3.*].*\\ .*[\\ ].*\\ Task\\ three\\.               ]]\n\n  [[    \"${lines[8]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[9]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[10]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                             ]]\n  [[    \"${lines[11]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                             ]]\n  [[    \"${lines[12]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.                            ]]\n}\n\n@test \"'todos tasks closed <folder>' exits with 0 and lists closed todos and tasks in folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/Note One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Note Title One.\n\nExample content.\n\n- [x] Task one.\n- [ ] Task two.\n- [ ] Task three.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note Two.md\"      \\\n      --content   \"Example note content two.\"\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo Two.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [x] Task two.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Three.todo.md\"   \\\n      --content   \"# [x] Example todo description three.\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Four.todo.md\"    \\\n      --content   \"# [ ] Example todo description four.\"\n  }\n\n  run \"${_NB}\" todos tasks closed Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 10  ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/5.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\.  ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*\\[.*Example\\ Folder/4.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.    ]]\n  [[    \"${lines[2]}\"   =~  .*------------------------------------.*                  ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 2.*].*\\ .*[.*x.*].*\\ Task\\ two\\.                              ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Folder/2.*].*\\ Example\\ Note\\ Title\\ One.              ]]\n  [[    \"${lines[5]}\"   =~  .*------------------------------------.*  ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 1.*].*\\ .*[.*x.*].*\\ Task\\ one\\.              ]]\n\n  [[    \"${lines[7]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[8]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[9]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.                        ]]\n}\n\n@test \"'todos tasks <folder>' exits with 0 and lists todos and tasks in folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/Note One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Note Title One.\n\nExample content.\n\n- [x] Task one.\n- [ ] Task two.\n- [ ] Task three.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note Two.md\"      \\\n      --content   \"Example note content two.\"\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo Two.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [x] Task two.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Three.todo.md\"   \\\n      --content   \"# [x] Example todo description three.\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Four.todo.md\"    \\\n      --content   \"# [ ] Example todo description four.\"\n  }\n\n  run \"${_NB}\" todos tasks Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 17  ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/6.*].*\\ ✔️\\ \\ .*[\\ ].*\\ Example\\ todo\\ description\\ four\\.       ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*\\[.*Example\\ Folder/5.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\.  ]]\n  [[    \"${lines[2]}\"   =~  \\\n.*\\[.*Example\\ Folder/4.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.    ]]\n  [[    \"${lines[3]}\"   =~  .*------------------------------------.*                  ]]\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                                 ]]\n  [[    \"${lines[5]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 2.*].*\\ .*[.*x.*].*\\ Task\\ two\\.                              ]]\n\n  [[    \"${lines[6]}\"   =~  \\\n.*\\[.*Example\\ Folder/2.*].*\\ Example\\ Note\\ Title\\ One.              ]]\n  [[    \"${lines[7]}\"   =~  .*------------------------------------.*  ]]\n  [[    \"${lines[8]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 1.*].*\\ .*[.*x.*].*\\ Task\\ one\\.              ]]\n  [[    \"${lines[9]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                 ]]\n  [[    \"${lines[10]}\"  =~  \\\n.*[.*Example\\ Folder/2\\ 3.*].*\\ .*[\\ ].*\\ Task\\ three\\.               ]]\n\n  [[    \"${lines[11]}\"  =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[12]}\"  =~  .*------------------------------------.*              ]]\n  [[    \"${lines[13]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                             ]]\n  [[    \"${lines[14]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                             ]]\n  [[    \"${lines[15]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.                        ]]\n  [[    \"${lines[16]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.                            ]]\n}\n\n@test \"'todos tasks <folder>' exits with 0 and lists todos with and without tasks in folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note One.md\"      \\\n      --content   \"Example note content one.\"\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo Two.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 7 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/3.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.    ]]\n  [[    \"${lines[2]}\"   =~  .*------------------------------------.*                ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                               ]]\n  [[    \"${lines[4]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                               ]]\n  [[    \"${lines[5]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.                          ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.                              ]]\n}\n\n@test \"'todos tasks <folder>' with no tasks exits with 0 and lists todos.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note One.md\"      \\\n      --content   \"Example note content one.\"\n  }\n\n  run \"${_NB}\" todos tasks Example\\ Folder/\n\n  printf \"\\${status}:     '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}:     '%s'\\\\n\" \"${output}\"\n  printf \"\\${#lines[@]}:  '%s'\\\\n\" \"${#lines[@]}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 1 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n}\n\n# tasks done / undone #########################################################\n\n@test \"'todos tasks undone <folder>' exits with 0 and lists open todos and tasks in folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/Note One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Note Title One.\n\nExample content.\n\n- [x] Task one.\n- [ ] Task two.\n- [ ] Task three.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note Two.md\"      \\\n      --content   \"Example note content two.\"\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo Two.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [x] Task two.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Three.todo.md\"   \\\n      --content   \"# [x] Example todo description three.\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Four.todo.md\"    \\\n      --content   \"# [ ] Example todo description four.\"\n  }\n\n  run \"${_NB}\" todos tasks undone Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 13  ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/6.*].*\\ ✔️\\ \\ *[\\ ].*\\ Example\\ todo\\ description\\ four\\.      ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*\\[.*Example\\ Folder/4.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n  [[    \"${lines[2]}\"   =~  .*------------------------------------.*                ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                               ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Folder/2.*].*\\ Example\\ Note\\ Title\\ One.              ]]\n  [[    \"${lines[5]}\"   =~  .*------------------------------------.*  ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                 ]]\n  [[    \"${lines[7]}\"  =~  \\\n.*[.*Example\\ Folder/2\\ 3.*].*\\ .*[\\ ].*\\ Task\\ three\\.               ]]\n\n  [[    \"${lines[8]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[9]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[10]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 1.*].*\\ .*[\\ ].*\\ Task\\ one\\.                             ]]\n  [[    \"${lines[11]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 2.*].*\\ .*[\\ ].*\\ Task\\ two\\.                             ]]\n  [[    \"${lines[12]}\"  =~  \\\n.*[.*Example\\ Folder/1\\ 4.*].*\\ .*[\\ ].*\\ Task\\ four\\.                            ]]\n}\n\n@test \"'todos tasks done <folder>' exits with 0 and lists closed todos and tasks in folder.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [x] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n\n    \"${_NB}\" add                              \\\n      --filename \"Example Folder/Note One.md\" \\\n      --content \"$(cat <<HEREDOC\n# Example Note Title One.\n\nExample content.\n\n- [x] Task one.\n- [ ] Task two.\n- [ ] Task three.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n    \"${_NB}\" add                                    \\\n      --filename  \"Example Folder/Note Two.md\"      \\\n      --content   \"Example note content two.\"\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo Two.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description two.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [x] Task two.\n\n## Tags\n\n#tag2 #tag3\nHEREDOC\n)\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Three.todo.md\"   \\\n      --content   \"# [x] Example todo description three.\"\n\n    \"${_NB}\" add                                        \\\n      --filename  \"Example Folder/Todo Four.todo.md\"    \\\n      --content   \"# [ ] Example todo description four.\"\n  }\n\n  run \"${_NB}\" todos tasks \"done\" Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0   ]]\n  [[    \"${#lines[@]}\"  -eq 10  ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/5.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\.  ]]\n  [[    \"${lines[1]}\"   =~  \\\n.*\\[.*Example\\ Folder/4.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.    ]]\n  [[    \"${lines[2]}\"   =~  .*------------------------------------.*                  ]]\n  [[    \"${lines[3]}\"   =~  \\\n.*[.*Example\\ Folder/4\\ 2.*].*\\ .*[.*x.*].*\\ Task\\ two\\.                              ]]\n\n  [[    \"${lines[4]}\"   =~  \\\n.*\\[.*Example\\ Folder/2.*].*\\ Example\\ Note\\ Title\\ One.              ]]\n  [[    \"${lines[5]}\"   =~  .*------------------------------------.*  ]]\n  [[    \"${lines[6]}\"   =~  \\\n.*[.*Example\\ Folder/2\\ 1.*].*\\ .*[.*x.*].*\\ Task\\ one\\.              ]]\n\n  [[    \"${lines[7]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[8]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[9]}\"   =~  \\\n.*[.*Example\\ Folder/1\\ 3.*].*\\ .*[.*x.*].*\\ Task\\ three\\.                        ]]\n}\n\n# empty messages ##############################################################\n\n@test \"'todos tasks open <folder>/<id>' with closed todo with no open tasks exits with 0 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [x] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [x] Task one.\n- [x] Task two.\n- [x] Task three.\n- [x] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks open Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 3 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*                ]]\n  [[    \"${lines[2]}\"   =~  0\\ open\\ tasks.                                         ]]\n}\n\n@test \"'todos tasks open <folder>/<id>' with open todo with no open tasks exits with 0 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [x] Task one.\n- [x] Task two.\n- [x] Task three.\n- [x] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks open Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 3 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[2]}\"   =~  0\\ open\\ tasks.                                       ]]\n}\n\n@test \"'todos tasks closed <folder>/<id>' with no closed tasks exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tasks\n\n- [ ] Task one.\n- [] Task two.\n- [ ] Task three.\n- [ ] Task four.\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks closed Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 3 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*              ]]\n  [[    \"${lines[2]}\"   =~  0\\ closed\\ tasks\\.                                    ]]\n}\n\n@test \"'todos tasks <folder>/<id>' with no tasks prints todo.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                    \\\n      --filename \"Example Folder/Todo One.todo.md\"  \\\n      --content \"$(cat <<HEREDOC\n# [ ] Example todo description one.\n\n## Due\n\n2200-02-02\n\n## Tags\n\n#tag1 #tag2\nHEREDOC\n)\"\n  }\n\n  run \"${_NB}\" todos tasks Example\\ Folder/1\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 0 ]]\n  [[    \"${#lines[@]}\"  -eq 3 ]]\n\n  [[    \"${lines[0]}\"   =~  \\\n.*\\[.*Example\\ Folder/1.*].*\\ ✔️\\ [\\ ].*\\ Example\\ todo\\ description\\ one\\.  ]]\n  [[    \"${lines[1]}\"   =~  .*------------------------------------.*        ]]\n  [[    \"${lines[2]}\"   =~  0\\ tasks\\.                                      ]]\n}\n\n@test \"'todos tasks <folder>' with no todos or tasks exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add \"Example Folder/File One.md\" --content \"Example content one.\"\n    \"${_NB}\" add \"Example Folder/File Two.md\" --content \"Example content two.\"\n  }\n\n  run \"${_NB}\" todos tasks Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1 ]]\n  [[    \"${#lines[@]}\"  -eq 1 ]]\n\n  [[    \"${lines[0]}\"   =~  .*!.*\\ 0\\ tasks\\.   ]]\n}\n"
  },
  {
    "path": "test/todo.bats",
    "content": "#!/usr/bin/env bats\n# shellcheck disable=SC2030,SC2031,SC2063\n\nload test_helper\n\n# todos #######################################################################\n\n@test \"'todos' with empty notebook exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todos\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                         ]]\n  [[    \"${#lines[@]}\"  -eq 1                         ]]\n\n  [[    \"${lines[0]}\"   =~  \\!.*\\ No\\ todos\\ found\\.  ]]\n}\n\n@test \"'todos open' with empty notebook exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todos open\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                               ]]\n  [[    \"${#lines[@]}\"  -eq 1                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\!.*\\ No\\ open\\ todos\\ found\\.  ]]\n}\n\n@test \"'todos <notebook>:' with empty notebook exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" todos Example\\ Notebook:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                         ]]\n  [[    \"${#lines[@]}\"  -eq 1                         ]]\n\n  [[    \"${lines[0]}\"   =~  \\!.*\\ No\\ todos\\ found\\.  ]]\n}\n\n@test \"'todos open <notebook>:' with empty notebook exits with 1 and prints message.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n  }\n\n  run \"${_NB}\" todos open Example\\ Notebook:\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"     -eq 1                               ]]\n  [[    \"${#lines[@]}\"  -eq 1                               ]]\n\n  [[    \"${lines[0]}\"   =~  \\!.*\\ No\\ open\\ todos\\ found\\.  ]]\n}\n\n@test \"'todos <notebook>:<folder>/' exits with 0 and lists todos.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" todos Example\\ Notebook:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0     ]]\n\n  [[ !  \"${output}\"   =~  Four  ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\. ]]\n  [[    \"${lines[1]}\" =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/2.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ two\\.     ]]\n  [[    \"${lines[2]}\" =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/1.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.     ]]\n}\n\n# tags ########################################################################\n\n@test \"'todos --tags <tag>' exits with 0 and lists todos containing <tag>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                                                            \\\n      --content   \"# [ ] Example todo description one.${_NEWLINE}${_NEWLINE}#sample-tag\"    \\\n      --filename  \"One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                                                            \\\n      --content   \"# [ ] Example todo description two.${_NEWLINE}${_NEWLINE}#example-tag\"   \\\n      --filename  \"Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                                                            \\\n      --content   \"# [x] Example todo description three.${_NEWLINE}${_NEWLINE}example-tag\"  \\\n      --filename  \"Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                                                            \\\n      --content   \"# Example description four.${_NEWLINE}${_NEWLINE}#example-tag\"           \\\n      --filename  \"Four.md\"\n  }\n\n  run \"${_NB}\" todos --tags example-tag\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0     ]]\n\n  [[ !  \"${output}\"   =~  one   ]]\n  [[ !  \"${output}\"   =~  three ]]\n  [[ !  \"${output}\"   =~  four  ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*2.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ two\\.     ]]\n}\n\n@test \"'todos <tag>' exits with 0 and lists todos containing <tag>.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                                                            \\\n      --content   \"# [ ] Example todo description one.${_NEWLINE}${_NEWLINE}#sample-tag\"    \\\n      --filename  \"One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                                                            \\\n      --content   \"# [ ] Example todo description two.${_NEWLINE}${_NEWLINE}#example-tag\"   \\\n      --filename  \"Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                                                            \\\n      --content   \"# [x] Example todo description three.${_NEWLINE}${_NEWLINE}example-tag\"  \\\n      --filename  \"Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                                                            \\\n      --content   \"# Example description four.${_NEWLINE}${_NEWLINE}#example-tag\"           \\\n      --filename  \"Four.md\"\n  }\n\n  run \"${_NB}\" todos \\#example-tag\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0     ]]\n\n  [[ !  \"${output}\"   =~  one   ]]\n  [[ !  \"${output}\"   =~  three ]]\n  [[ !  \"${output}\"   =~  four  ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*2.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ two\\.     ]]\n}\n\n# todos closed / done #########################################################\n\n@test \"'todos closed <notebook>:<folder>/' exits with 0 and lists todos.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" todos closed Example\\ Notebook:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0     ]]\n\n  [[ !  \"${output}\"   =~  One   ]]\n  [[ !  \"${output}\"   =~  Two   ]]\n  [[ !  \"${output}\"   =~  Four  ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\. ]]\n}\n\n@test \"'todos done <notebook>:<folder>/' exits with 0 and lists todos.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" todos \"done\" Example\\ Notebook:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0     ]]\n\n  [[ !  \"${output}\"   =~  One   ]]\n  [[ !  \"${output}\"   =~  Two   ]]\n  [[ !  \"${output}\"   =~  Four  ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*\\[.*Example\\ Notebook:Example\\ Folder/3.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ three\\. ]]\n}\n\n# todos open ##################################################################\n\n@test \"'todos open <id>' exits with 0 and undos todo.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n  }\n\n  run \"${_NB}\" todos open Example\\ Folder/3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq  1 ]]\n  [[    \"${#lines[@]}\" -eq  1 ]]\n\n  [[    \"${lines[0]}\"   =~  .*!.*\\ No\\ open\\ todos\\ found\\. ]]\n}\n\n@test \"'todos open <notebook>:<folder>/' exits with 0 and lists open todos.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" todos open Example\\ Notebook:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\" -eq 0     ]]\n\n  [[ !  \"${output}\" =~  Three ]]\n  [[ !  \"${output}\" =~  Four  ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*[.*Example\\ Folder/2.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n  [[    \"${lines[1]}\" =~  \\\n.*[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n}\n\n@test \"'todos undone <notebook>:<folder>/' exits with 0 and lists open todos.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" todos \"undone\" Example\\ Notebook:Example\\ Folder/\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"   -eq 0     ]]\n\n  [[ !  \"${output}\"   =~  Three ]]\n  [[ !  \"${output}\"   =~  Four  ]]\n\n  [[    \"${lines[0]}\" =~  \\\n.*[.*Example\\ Folder/2.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n  [[    \"${lines[1]}\" =~  \\\n.*[.*Example\\ Folder/1.*].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ one\\.  ]]\n}\n\n# todo do #####################################################################\n\n@test \"'todo do <notebook>:<folder>/<id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" todo \"do\" Example\\ Notebook:Example\\ Folder/2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nDone:\\ .*\\[.*Example\\ Notebook:Example\\ Folder/2.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/One.todo.md\")    \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Two.todo.md\")    \\\n    <(printf \"# [x] Example todo description two.\\\\n\")\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Three.todo.md\")  \\\n    <(printf \"# [x] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/Example Notebook\" log | grep -q '\\[nb\\] Done: Example Folder/Two.todo.md'\n}\n\n@test \"'todo do <id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Three.todo.md\"\n  }\n\n  run \"${_NB}\" todo \"do\" 2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nDone:\\ .*\\[.*2.*\\].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/One.todo.md\")   \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Two.todo.md\")   \\\n    <(printf \"# [x] Example todo description two.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Three.todo.md\") \\\n    <(printf \"# [x] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Done: Two.todo.md'\n}\n\n@test \"'todo do' with no selector exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo \"do\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1                     ]]\n  [[ \"${lines[0]}\"  =~  Usage.*:              ]]\n  [[ \"${lines[1]}\"  =~  ${_ME}\\ todo          ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\" -eq 0                    ]]\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Done'\n}\n\n# todos close / done ##########################################################\n\n@test \"'todos close <id>' exits with 0 and checks todo.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n  }\n\n  run \"${_NB}\" todos close Example\\ Folder/2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 0    ]]\n\n  [[ !  \"${output}\"   =~  One   ]]\n  [[ !  \"${output}\"   =~  Three ]]\n  [[ !  \"${output}\"   =~  Four  ]]\n\n  [[    \"${lines[0]}\" =~  \\\nDone:\\ .*[.*Example\\ Folder/2.*].*\\ ✅\\ .*\\[.*x.*\\].*\\ Example\\ todo\\ description\\ two\\.  ]]\n}\n\n@test \"'todos done <id>' exits with 0 and checks todo.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    sleep 1\n\n    \"${_NB}\" add                                        \\\n      --content \"# Example description four.\"           \\\n      --filename \"Example Folder/Four.md\"\n  }\n\n  run \"${_NB}\" todos \"done\" Example\\ Folder/2\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[    \"${status}\"    -eq 1 ]]\n  [[    \"${#lines[@]}\" -eq 1 ]]\n\n  [[    \"${lines[0]}\"   =~  .*!.*\\ No\\ closed\\ todos\\ found\\. ]]\n}\n\n# todo undo #####################################################################\n\n@test \"'todo undo <notebook>:<folder>/<id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" notebooks add \"Example Notebook\"\n\n    \"${_NB}\" use \"Example Notebook\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"Example Folder/One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Example Folder/Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Example Folder/Three.todo.md\"\n\n    \"${_NB}\" use \"home\"\n  }\n\n  run \"${_NB}\" todo \"undo\" Example\\ Notebook:Example\\ Folder/3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0       ]]\n  [[ \"${output}\"    =~  \\\nUndone:\\ .*\\[.*Example\\ Notebook:Example\\ Folder/3.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ three\\.  ]]\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/One.todo.md\")    \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Two.todo.md\")    \\\n    <(printf \"# [ ] Example todo description two.\\\\n\")\n\n  diff                                                                \\\n    <(cat \"${NB_DIR}/Example Notebook/Example Folder/Three.todo.md\")  \\\n    <(printf \"# [ ] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/Example Notebook\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/Example Notebook\" log | grep -q '\\[nb\\] Undone: Example Folder/Three.todo.md'\n}\n\n@test \"'todo undo <id>' exits with 0, updates todo, and commits.\" {\n  {\n    \"${_NB}\" init\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description one.\"   \\\n      --filename \"One.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [ ] Example todo description two.\"   \\\n      --filename \"Two.todo.md\"\n\n    \"${_NB}\" add                                        \\\n      --content \"# [x] Example todo description three.\" \\\n      --filename \"Three.todo.md\"\n  }\n\n  run \"${_NB}\" todo \"undo\" 3\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0                 ]]\n  [[ \"${output}\"    =~  \\\nUndone:\\ .*\\[.*3.*\\].*\\ ✔️\\ \\ .*\\[\\ \\].*\\ Example\\ todo\\ description\\ three\\.  ]]\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/One.todo.md\")   \\\n    <(printf \"# [ ] Example todo description one.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Two.todo.md\")   \\\n    <(printf \"# [ ] Example todo description two.\\\\n\")\n\n  diff                                    \\\n    <(cat \"${NB_DIR}/home/Three.todo.md\") \\\n    <(printf \"# [ ] Example todo description three.\\\\n\")\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -q '\\[nb\\] Undone: Three.todo.md'\n}\n\n@test \"'todo undo' with no selector exits with 1 and prints help.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" todo \"undo\"\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"      -eq 1               ]]\n  [[ \"${lines[0]}\"    =~  Usage.*:        ]]\n  [[ \"${lines[1]}\"    =~  ${_ME}\\ todo    ]]\n\n  _files=($(ls \"${NB_DIR}/home/\"))\n\n  [[ \"${#_files[@]}\"  -eq 0               ]]\n\n  while [[ -n \"$(git -C \"${NB_DIR}/home\" status --porcelain)\" ]]\n  do\n    sleep 1\n  done\n  git -C \"${NB_DIR}/home\" log | grep -v -q '\\[nb\\] Undone'\n}\n"
  },
  {
    "path": "test/unset.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n# help ########################################################################\n\n@test \"'help unset' exits with 0 and prints help information.\" {\n  run \"${_NB}\" help unset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 0             ]]\n\n  [[ \"${lines[0]}\"  =~  Usage.*\\:     ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ unset ]]\n}\n\n# `reset` #####################################################################\n\n@test \"'reset' with argument unsets, prints, and exits.\" {\n  {\n    \"${_NB}\" init\n\n    run \"${_NB}\" settings set EDITOR sample\n\n    [[ \"$(EDITOR='' \"${_NB}\" settings get EDITOR)\" == 'sample'  ]]\n    [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"sample\"'             ]]\n  }\n\n  run \"${_NB}\" reset EDITOR\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".nbrc:\\\\n'%s'\\\\n\" \"$(cat \"${NBRC_PATH}\")\"\n\n  [[    \"${status}\"             -eq 0                           ]]\n  [[ !  \"$(cat \"${NBRC_PATH}\")\" =~  'NB_EDITOR=\"sample\"'        ]]\n  [[ !  \"$(cat \"${NBRC_PATH}\")\" =~  'NB_EDITOR=\"sample\"'        ]]\n  [[    \"${output}\"             =~  EDITOR                      ]]\n  [[    \"${output}\"             =~  restored\\ to\\ the\\ default  ]]\n  [[ !  \"${output}\"             =~  sample                      ]]\n}\n\n# `unset` #####################################################################\n\n@test \"'unset' with no argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" unset\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"    -eq 1             ]]\n  [[ \"${lines[0]}\"  =~  Usage.*\\:     ]]\n  [[ \"${lines[1]}\"  =~  \\ \\ nb\\ unset ]]\n}\n\n@test \"'unset' with invalid argument exits with error.\" {\n  {\n    \"${_NB}\" init\n  }\n\n  run \"${_NB}\" unset EXAMPLE\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${status}\"  -eq 1                     ]]\n  [[ \"${output}\"  =~ Setting\\ not\\ found\\:  ]]\n  [[ \"${output}\"  =~ EXAMPLE                ]]\n}\n\n@test \"'unset' with argument unsets, prints, and exits.\" {\n  {\n    \"${_NB}\" init\n\n    run \"${_NB}\" settings set EDITOR sample\n\n    [[ \"$(EDITOR='' \"${_NB}\" settings get EDITOR)\" == 'sample'  ]]\n    [[ \"$(cat \"${NBRC_PATH}\")\" =~ 'EDITOR=\"sample\"'             ]]\n  }\n\n  run \"${_NB}\" unset EDITOR\n\n  printf \"\\${status}: '%s'\\\\n\"        \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\"        \"${output}\"\n  printf \".nbrc:\\\\n'%s'\\\\n\"           \"$(cat \"${NBRC_PATH}\")\"\n  printf \"env:\\\\n'%s'\\\\n\"             \"$(\"${_NB}\" env)\"\n  printf \"set get editor:\\\\n'%s'\\\\n\"  \"$(EDITOR='' \"${_NB}\" set get editor)\"\n\n  [[    \"${status}\"             -eq 0                           ]]\n  [[ !  \"$(cat \"${NBRC_PATH}\")\" =~  'NB_EDITOR=\"sample\"'        ]]\n  [[ !  \"$(cat \"${NBRC_PATH}\")\" =~  'NB_EDITOR=\"sample\"'        ]]\n  [[    \"${output}\"             =~  EDITOR                      ]]\n  [[    \"${output}\"             =~  restored\\ to\\ the\\ default  ]]\n  [[ !  \"${output}\"             =~  sample                      ]]\n}\n"
  },
  {
    "path": "test/use.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n_setup_use() {\n  \"${_NB}\" init\n  mkdir -p \"${NB_DIR}/one\"\n  cd \"${NB_DIR}/one\" || return 1\n  git init\n  mkdir -p \"${NB_DIR}/two\"\n  cd \"${NB_DIR}\" || return 1\n}\n\n# `use <name>` ################################################################\n\n@test \"'use' exits with 1 and prints error message.\" {\n  {\n    _setup_use\n  }\n\n  run \"${_NB}\" use\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".current: %s\\\\n\" \"$(cat \"${NB_DIR}/.current\")\"\n\n  [[ ${status} -eq 1                          ]]\n  [[ \"${lines[1]}\" == \"  nb use <notebook>\"   ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"  ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'NB_NOTEBOOK_PATH=${NB_DIR}/home'\" \"'${lines[50]}'\"\n\n  [[ \"${output}\" =~ NB_NOTEBOOK_PATH=${NB_DIR}/home ]]\n}\n\n@test \"'use <invalid>' exits with 1 and prints error message.\" {\n  {\n    _setup_use\n  }\n\n  run \"${_NB}\" use not-a-repo\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  printf \".current: %s\\\\n\" \"$(cat \"${NB_DIR}/.current\")\"\n\n  [[ ${status} -eq 1                                                                ]]\n  [[ \"${lines[0]}\" == \"${_ERROR_PREFIX} Not found: $(_color_primary \"not-a-repo\")\"  ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"home\"                                        ]]\n\n  run \"${_NB}\" env\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'NB_NOTEBOOK_PATH=${NB_DIR}/home'\" \"'${lines[51]}'\"\n\n  [[ \"${output}\" =~ NB_NOTEBOOK_PATH=${NB_DIR}/home ]]\n}\n\n@test \"'repo use <name>' exits with 0 and sets <name> in .current.\" {\n  {\n    _setup_use\n    _expected=\"Now using: $(_color_primary 'one')\"\n  }\n\n  run \"${_NB}\" use one\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'${_expected}'\" \"'${output}'\"\n\n  [[ ${status} -eq 0                        ]]\n  [[ \"${output}\" == \"${_expected}\"          ]]\n  [[ \"$(cat \"${NB_DIR}/.current\")\" == \"one\" ]]\n\n  run \"${_NB}\" env\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n  _compare \"'NB_NOTEBOOK_PATH=${NB_DIR}/one'\" \"'${lines[51]}'\"\n\n  [[ \"${output}\" =~ NB_NOTEBOOK_PATH=${NB_DIR}/one ]]\n}\n\n# help ########################################################################\n\n@test \"'help use' exits with status 0.\" {\n  run \"${_NB}\" help use\n\n  [[ ${status} -eq 0 ]]\n}\n\n@test \"'help use' prints help information.\" {\n  run \"${_NB}\" help use\n\n  printf \"\\${status}: '%s'\\\\n\" \"${status}\"\n  printf \"\\${output}: '%s'\\\\n\" \"${output}\"\n\n  [[ \"${lines[0]}\" =~ Usage                 ]]\n  [[ \"${lines[1]}\" == \"  nb use <notebook>\" ]]\n}\n"
  },
  {
    "path": "test/version.bats",
    "content": "#!/usr/bin/env bats\n\nload test_helper\n\n@test \"'version' returns with 0 status.\" {\n  run \"${_NB}\" --version\n\n  [[ \"${status}\" -eq 0 ]]\n}\n\n@test \"'version' prints a version number.\" {\n  run \"${_NB}\" --version\n\n  printf \"'%s'\" \"${output}\"\n\n  echo \"${output}\" \\\n    | grep -q '[[:digit:]]\\+\\.[[:digit:]]\\+\\.[[:digit:]]\\+'\n}\n\n@test \"'--version' returns with 0 status.\" {\n  run \"${_NB}\" --version\n\n  [[ \"${status}\" -eq 0 ]]\n}\n\n@test \"'--version' prints a version number.\" {\n  run \"${_NB}\" --version\n\n  printf \"'%s'\" \"${output}\"\n\n  echo \"${output}\" \\\n    | grep -q '[[:digit:]]\\+\\.[[:digit:]]\\+\\.[[:digit:]]\\+'\n}\n"
  }
]