diff --git a/.Rhistory b/.Rhistory new file mode 100644 index 0000000..e69de29 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d344ba6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.json diff --git a/README.md b/README.md index 1a41cfa..f6b5c04 100644 --- a/README.md +++ b/README.md @@ -3,98 +3,92 @@ Shell Scripts to Facilitate Effective Note Taking ## Introduction -Essentially I ~~used to~~ have a dozen shell scripts in `~/bin` that I use to capture notes, -this is an attempt to wrap them into a single script and then have aliases to make them quick to access. +This is a **self-contained** shell script that uses pre-existing tools (such as TMSU and recoll) to provide an interface for markdown notes. -![](./MainMenu.png) +It's command based and prints out available subcommands for any given command, these means you can use a directory of markdown files like a personal wiki, much like OneNote/Evernote/Notable, for example: -The idea is that it is just a menu to dispatch different scripts so I could -share those scripts with classmates. - -## Design Philosophy +![Mindmap of Program Flow](./usage.svg "Diagram of the flow of the script") -- ****cadmus**** acts as a menu for scripts to acheive things - - the script name ~~will~~ should always be printed to the terminal so the individual - script can be repurposed with out fishing through code. -- Subscripts ~~will~~ should take *only one* argument (or `STDIN`) - - If the first argument is either `-h` or `--help` help will be printed and then `exit 0` - - This might lead to some limitations but the simplicity is for sanity, modularity and extensibility. - - Will always return absolute path. - - I played around with relative path but it got confusing when calling the script from inside a function inside a script, so instead if you want a relative path you should do `scriptname './' | xargs realpath --relative-to='./'` -- Be a Front end to tie together different scripts and tools -- Don't replicate work other people have done. -- Plain Text, Open Source. -- Be Modular - - Pipe in input, output goes to STDOUT - - Leave Aliases and piping to the user - - See [Recommended Aliases](#recommended-aliases) -- ****cadmus**** will take the notes directory from the global variable `CADMUS_NOTES_DIR` - - The Actual work will be done by subscripts denoted by `description.bash` - - The subscripts will take the note directory as an argument so they are portable and modular - - The Arguments will be shifted and then all passed down to subfunctions +and an overview of what it looks like in the terminal + +![](./media/Many_Examples.png) + +For example if you wanted to extract all the tags from your markdown notes (either `#tags` or from the YAML), cadmus has a tool for that: + +![](./media/TagsExample.gif) + + +Ultimately the idea is it is to act a menu to dispatch different scripts I already had so I could +more easily share those scripts with classmates. + +The real heavy lifting is done by Pandoc, Recoll, ripgrep, skim/fzf, TMSU etc. ## Installation -To install: +### Automatic + +Copy this into your shell: + + +``` bash +cd $(mktemp -d) +wget https://raw.githubusercontent.com/RyanGreenup/cadmus/master/install.sh +bash install.sh +``` + + +- Cadmus will work from within a self-contained directory and add a symlink to `~/.local/bin` + - in this way it's zero lock-in, it does not modify your curr directory of Markdown files. +- Installation will automatically create a config file in its directory (which is by default `~/.cadmus` +- The script will list any [dependencies](#dependencies) that are not satisfied. + +### Manual + +To install manually: 1. satisfy [the dependencies](#Dependencies) 2. [Set up Recoll](#Configuring-recoll) -3. Download cadmus and put it in the `PATH` +3. Download cadmus and put it into the `PATH` ```bash - mkdir ~/.cadmus && \ git clone https://github.com/RyanGreenup/cadmus ~/.cadmus \ - || echo "Delete ~/.cadmus first" - ln -s ~/.cadmus/bin/cadmus $HOME/bin/ + || echo "Delete $HOME/.cadmus first" + mkdir -p $HOME/.local/bin + ln -s "$HOME/.cadmus/bin/cadmus" "$HOME/.local/bin/" ``` - 3. If you haven't already add `$HOME/bin` to the `$PATH` variable, something like this should be fairly shell agnostic: + 3. According to the [*SystemD Standard*](https://www.freedesktop.org/software/systemd/man/file-hierarchy.html) `~/.local/bin` should be in `$PATH`, if you are using some other init implementation you can add this directory to `"$PATH"` it by doing something like this: ``` bash - echo $PATH | grep "$HOME/bin" &> /dev/null && echo "$HOME/bin in path already" || ls "$HOME/bin" &> /dev/null && echo 'PATH="$PATH:$HOME/bin"' >> $HOME/.profile + ## Should work in bash/zsh/fish + echo $PATH | grep "$HOME/.local/bin" &> /dev/null && echo "$HOME/.local/bin in path already" || ls "$HOME/.local/bin" &> /dev/null && echo 'PATH="$PATH:$HOME/.local/bin"' >> $HOME/.profile ``` -4. You will probably need to change the directory to your notes in the script: +> When first run, the script will prompt you to make a config file in the directory in which it is run. - ```bash - which cadmus | xargs xdg-open - ``` - - ``` - readonly NOTES_DIR="$HOME/Notes/" - readonly SERVER_DIR="/var/www/html/MD" - readonly MKDOCS_YML="$HOME/Notes/mkdocs.yml" - ``` +### Assumptions + +It is assumed that: + +1. Notes are: + 1. *Markdown* files with a `.md` extension + 3. Recoll updates it's index on the fly + * The notes directory will need to be indexed by *Recoll* in order for + the results to show up when using `cadmus search`. +3. SSD + * I use an SSD and so I let some scripts be pretty inefficient (for example something like `grep | cut | + xargs find` to avoid creating a variable), I don't know if HDD performance would be great. +5. All Notes have Unique Names +6. On *MacOS* you'll need to define `xdg-open` and have GNU coreutils, so do something like: + ```bash + alias xdg-open='open &>/dev/null' + alias realpath=grealpath &>/dev/null + ``` +[*nushell*]: https://github.com/nushell/nushell +[*Fish*]: https://fishshell.com/ +[*OMF*]: https://github.com/oh-my-fish/oh-my-fish - - ---> - + ### Configuring recoll Currently the search just uses the default recoll config, I intend to modify this to use `~/.cadmus` as a config directory so as to not interfere with the default config. @@ -116,47 +110,29 @@ then select *index configuration* and configure recoll to have `~/Notes/MD` as t | If you want to change the notes directory change the variable `NOTES_DIR` in ****cadmus**** | --> -## Usage -It's all Menu driven so just follow the diagram to do what you need. -![Mindmap of Program Flow](./usage.svg "Diagram of the flow of the script") +## Design Philosophy -### Assumptions - -It is assumed that: - -1. Notes are: - 1. *Markdown* files with a `.md` extension - 2. Underneath `~/Notes` (you ma) - 3. Recoll updates it's index on the fly - * `~/Notes` will need to be indexed by *Recoll* so the results will show up. -3. SSD - * I use an SSD and some scripts are pretty inefficient (like `grep | cut | - xargs find` to avoid creating a variable), I don't know if things like - would work on a HDD. -5. All Notes have Unique Names -6. On *MacOS* you'll need to define `xdg-open` so do something like: - ```bash - alias xdg-open='open &>/dev/null' - ``` - - - -[*nushell*]: https://github.com/nushell/nushell -[*Fish*]: https://fishshell.com/ -[*OMF*]: https://github.com/oh-my-fish/oh-my-fish +- ****cadmus**** acts as a menu for scripts to acheive things + - The Actual work will be done by subscripts denoted by `description.bash` + - The subscripts will take the note directory as an argument so they are portable and modular + - The Arguments will be shifted and then all passed down to subfunctions + - the script name ~~will~~ should always be printed to the terminal so the individual + script can be repurposed with out fishing through code. +- Subscripts ~~will~~ should take *only one* argument (or `STDIN`) + - If the first argument is either `-h` or `--help` help will be printed and then `exit 0` + - This might lead to some limitations but the simplicity is for sanity, modularity and extensibility. + - Will always return absolute path. + - I played around with relative path but it got confusing when calling the script from inside a function inside a script, so instead if you want a relative path you should do `scriptname './' | xargs realpath --relative-to='./'` +- Be a Front end to tie together different scripts and tools +- Don't replicate work other people have done. +- Plain Text, Free as in Speech and Beer. +- try to make modular subscripts: + - Pipe in input, output goes to STDOUT + - Leave Aliases and piping to the user + - See [Recommended Aliases](#recommended-aliases) ## Dependencies @@ -164,55 +140,60 @@ It is assumed that: This was a dependency but I switched to java script - [R](https://en.wikipedia.org/wiki/R_(programming_language)) --> -- [highlight](https://www.archlinux.org/packages/community/x86_64/highlight/) -- [recode](https://www.archlinux.org/packages/extra/x86_64/recode/) -- [node](https://nodejs.org/en/) +- [bat](https://github.com/sharkdp/bat) +- [cut](https://www.gnu.org/software/coreutils/manual/html_node/The-cut-command.html) +- [fd](https://github.com/sharkdp/fd) +- [find](https://man7.org/linux/man-pages/man1/find.1.html) - [fzf](https://github.com/junegunn/fzf) -- [skim](https://github.com/lotabout/skim) -- [rg](https://www.google.com/search?client=firefox-b-d&q=ripgrep+github) - - Make sure to include `pcre2`, this comes in *Arch*, if using `cargo`: - ```bash - cargo install ripgrep --features 'pcre2' - ``` +- [GNU realpath](https://www.gnu.org/software/coreutils/manual/html_node/realpath-invocation.html#realpath-invocation) +- [grep](https://www.gnu.org/software/grep/) +- [highlight](https://www.archlinux.org/packages/community/x86_64/highlight/) +- jq [Arch](https://www.archlinux.org/packages/community/x86_64/jq/) | [brew](https://formulae.brew.sh/formula/jq#default) | [ubuntu](https://packages.ubuntu.com/search?keywords=jq) +- [mdcat](https://aur.archlinux.org/packages/mdcat/)AUR +- [node](https://nodejs.org/en/) +- [Pandoc](https://github.com/jgm/pandoc) - [perl](https://wiki.archlinux.org/index.php/Perl) - [python](https://www.python.org/download/releases/3.0/) -- [tmsu](https://aur.archlinux.org/packages/tmsu/)AUR - [ranger](https://www.archlinux.org/packages/community/any/ranger/) -- [mdcat](https://aur.archlinux.org/packages/mdcat/)AUR -- [xclip](https://www.archlinux.org/packages/extra/x86_64/xclip/) -- [sd](https://github.com/chmln/sd) -- [fd](https://github.com/sharkdp/fd) -- [sed](https://www.gnu.org/software/sed/) -- [cut](https://www.gnu.org/software/coreutils/manual/html_node/The-cut-command.html) -- [grep](https://www.gnu.org/software/grep/) -- [find](https://man7.org/linux/man-pages/man1/find.1.html) -- [GNU realpath](https://www.gnu.org/software/coreutils/manual/html_node/realpath-invocation.html#realpath-invocation) +- [recode](https://www.archlinux.org/packages/extra/x86_64/recode/) - [Recoll](https://www.lesbonscomptes.com/recoll/) -- [Pandoc](https://github.com/jgm/pandoc) -- [bat](https://github.com/sharkdp/bat) +- [rg](https://www.google.com/search?client=firefox-b-d&q=ripgrep+github) + - Make sure to include `pcre2`, this comes in *Arch*, if using `cargo`: + ```bash + cargo install ripgrep --features 'pcre2' + ``` + +- [sd](https://github.com/chmln/sd) +- [sed](https://www.gnu.org/software/sed/) +- [skim](https://github.com/lotabout/skim) +- [tmsu](https://aur.archlinux.org/packages/tmsu/)AUR +- [xclip](https://www.archlinux.org/packages/extra/x86_64/xclip/) ### Recommended for all Features -- [WeasyPrint](https://aur.archlinux.org/packages/python-weasyprint/) -- [tectonic](https://tectonic-typesetting.github.io/en-US/) -- [nvim](https://neovim.io/) +- [ip](https://jlk.fjfi.cvut.cz/arch/manpages/man/ip.8) + - if you're on mac [this stackExchange](https://superuser.com/a/898971) answer suggests [iproute2](https://formulae.brew.sh/formula/iproute2mac#default) may work - [Kitty](https://sw.kovidgoyal.net/kitty/) - I've also heard good things about [iterm2](https://www.iterm2.com/) - [MkDocs](https://pypi.org/project/mkdocs-material-extensions/) - - [MkDocs Material Theme](https://github.com/squidfunk/mkdocs-material) - [MkDocs Material Extensions](https://pypi.org/project/mkdocs-material-extensions/) + - [MkDocs Material Theme](https://github.com/squidfunk/mkdocs-material) +- [nvim](https://neovim.io/) +- [tectonic](https://tectonic-typesetting.github.io/en-US/) +- [WeasyPrint](https://aur.archlinux.org/packages/python-weasyprint/) + +### Interesting / Helpful / Recommended Generally (Not strictly necessary) + +- [guake](http://guake-project.org/) or [yakuake](https://kde.org/applications/en/system/org.kde.yakuake) - [MarkText](https://github.com/marktext/marktext) -- [VNote](https://github.com/tamlok/vnote) - -### recommended / Interesting / Helpful packages not required - -- [readability-cli](https://gitlab.com/gardenappl/readability-cli) - mdless +- [readability-cli](https://gitlab.com/gardenappl/readability-cli) +- [VNote](https://github.com/tamlok/vnote) - VSCode ### PATH -If installed with `pip` or `cargo` it will be necessary to add these directories to your `PATH`: +If any dependencies are installed with `pip` or `cargo` it will be necessary to add these directories to your `PATH`: ``` bash ## bash @@ -238,7 +219,29 @@ set PATH "$HOME/.cargo/bin $PATH ## Recommended Aliases -I wrote all this with aliases in mind, when I settle on some aliases i'll put up my `fish` functions. (I also wanted to do some autocomplete.) +I wrote all this with aliases in mind, when I settle on some aliases i'll put up my `fish` functions. (I also wanted autocomplete) + + +## Why / Comparison with other tools + +So the boxes I needed ticked are, more or less: +𐄞 +| | FOSS | Offline | Linux/BSD? | terminal? | RawFiles? | Markdown | AnyEditor? | +|-----------|------|---------|------------|-----------|-----------|----------|------------| +| OneNote | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| EverNote | ❌ | ? | ❌ | ❌ | ❌ | ❌ | ❌ | +| Notable | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | +| Zim | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | +| Obsidian | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | +| dokuwiki | ✅ | ❌ | ✅ | ❌ | ✅ | ✅* | ✅ | +| joplin | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ † | +| mediawiki | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ ‡ | +| Org-Mode | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | +| Cadmus | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + +> † You can't open the files from vim with FZF so it gets a no.
+> ‡ Unlike dokuwiki everything is in a database so it gets a no
+> \* With a Plugin
## Related diff --git a/bin/NoteFind.sh b/bin/NoteFind.sh index b43ae6b..38a810b 100755 --- a/bin/NoteFind.sh +++ b/bin/NoteFind.sh @@ -91,7 +91,7 @@ readFirstArgument () { SkimNotes () { ## Change directory if One was specified, exit if no directory exists - + cd "${1}" FILE="$(SkimGrep)" diff --git a/bin/cadmus b/bin/cadmus index 87d885d..d08381e 100755 --- a/bin/cadmus +++ b/bin/cadmus @@ -1,8 +1,12 @@ #! /usr/bin/env bash -readonly NOTES_DIR="$HOME/Notes/MD/notes" ## TODO Global Variables are bad -readonly SERVER_DIR="/srv/www/html/MD" -readonly RECOLL_CONFIG_DIR="$HOME/.cadmus" -readonly MKDOCS_YML="$HOME/Notes/mkdocs.yml" ## This may be above the notes directory, the + IFS=$'\t\n' # Split on newlines and tabs (but not on spaces) + readonly script_name=$(basename "${0}") + script_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) + readonly script_dir=$(realpath "${script_dir}""/""${script_name}" | xargs dirname) +readonly CONFIG=$(realpath "${script_dir}/../config.json") # one directory above +## readonly SERVER_DIR="/srv/www/html/MD" +## readonly RECOLL_CONFIG_DIR="$HOME/.cadmus" +## readonly MKDOCS_YML="$HOME/Notes/mkdocs.yml" ## This may be above the notes directory, the ## notes directory may not contain all the ## images for want of seperation and mkdocs is ## fidally, so specify the path to mkdocs.yml. @@ -18,7 +22,7 @@ set -o pipefail # * Main Functions main() { - + checkConfig setvars [[ -z "${1:-}" ]] && mainHelp && exit 0 arguments "${@:-}" @@ -26,12 +30,14 @@ main() { function setvars() { - IFS=$'\t\n' # Split on newlines and tabs (but not on spaces) - readonly script_name=$(basename "${0}") - script_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) - readonly script_dir=$(realpath "${script_dir}""/""${script_name}" | xargs dirname) readonly TERMINAL="kitty" readonly TERMINAL_EXEC='kitty -- ' + + + readonly NOTES_DIR="$(cat "${CONFIG}" | jq -r '.notesDir')" + readonly SERVER_DIR="$(cat "${CONFIG}" | jq -r '.serverDir')" + readonly RECOLL_CONFIG_DIR="$(cat "${CONFIG}" | jq -r '.recollConfigDir')" + readonly MKDOCS_YML="$(cat "${CONFIG}" | jq -r '.mkdocsConfigDir')" ## This may be above the notes directory, the } @@ -55,7 +61,7 @@ function mainHelp() { echo -e " ⎋ \e[1;36m convert \e[0m \e[1;34m ┊┊┊ 📁\e[0m Convert Clipboard Contents to Different Formats " echo -e " 🧰 \e[1;37m misc \e[0m \e[1;34m ┊┊┊ 📁\e[0m Miscelanneous Tools nice to have on hand " echo -e " 🌏\e[1;92m publish\e[0m \e[1;34m ┊┊┊ 📁\e[0m Publish with \e[1;34m \e[4m\e[3mMkDocs\e[0m\e[0m🐍" - echo -e " 🕮 \e[1;93m preview \e[0m \e[1;34m ┊┊┊ 🎆\e[0m Preview with \e[1;34m \e[4m\e[3mMarkServ\e[0m\e[0m (use chrome for this)" + echo -e " 🕮 \e[1;93m preview \e[0m \e[1;34m ┊┊┊ 🎆\e[0m Preview with \e[1;34m \e[4m\e[3mMarkServ\e[0m\e[0m (use 'preview!' for global)" echo -e " 🕮 \e[1;94m help \e[0m \e[1;34m ┊┊┊ 🎆\e[0m Open help for correspoding functions " echo echo -e " \e[3m\e[1m• Legend\e[0m " @@ -66,6 +72,33 @@ function mainHelp() { } # ** Main Arguments - Level 0 +# *** Config +checkConfig () { + if [[ -f "${CONFIG}" ]]; then + echo "Config Detected" + else + echo -e "No config File detected at ${CONFIG}" + echo -e "Would you like to generate a config?" + echo + echo -e "Press y to continue or any other key to exit." + echo + read -d '' -s -n1 choice + if [[ "${choice}" == "y" ]]; then + config_json=$("${script_dir}/makeConfig.bash") + if [[ "${config_json}" != "" ]]; then + echo "${config_json}" > "${CONFIG}" + echo -e "This is the Config:\n" + highlight "${CONFIG}" + else + echo "Config not Generated" + exit 1 + fi + else + exit 0 + fi + fi + +} # *** Switch arguments () { @@ -90,8 +123,14 @@ arguments () { ;; publish|pub) shift; CadmusPublish "${@:-}" ;; + publish) shift; CadmusPublish "${@:-}" + ;; preview|p) shift; cd "${NOTES_DIR}" && markserv || echo -e " \n \e[1;34m maybe fix this with:\n\tsudo fuser 35729/tcp -k \n \tor\n\tkillall markserv \e[0m\n" ;; + preview!) shift; previewGlobal + ;; + help) subHelp && exit 0 + ;; --*) >&2 echo "bad option $1" ;; *) >&2 echo -e "argument \e[1;35m${1}\e[0m has no definition." @@ -290,7 +329,7 @@ makeNewNote () { echo -e "Please Choose Relevant Tags (Use Tab for Multi Select)" echo -e "\n\t(Press any key to continue)" read -d '' -s -n1 choice - + ## Choose Tags TAGS="$(node "${script_dir}"/tags/yaml-parse.js "${NOTES_DIR}" 2>/dev/null | sort -u| sk -m)" @@ -522,6 +561,28 @@ CadmusConvert () { } +# *** Preview Global +previewGlobal() { + MARKSERVPORT="28754" + cd "${NOTES_DIR}" + printQR + markserv -p "${MARKSERVPORT}" -a 0.0.0.0 || echo -e " \n \e[1;34m maybe fix this with:\n\tsudo fuser 35729/tcp -k \n \tor\n\tkillall markserv \e[0m\n" + + + + +} + +# **** Print QR + printQR () { + command -v qrencode >/dev/null 2>&1 || { echo -e >&2 "I require qrencode but it's not installed.\nNo QR Code can be printed."; return; } + command -v ip >/dev/null 2>&1 || { echo -e >&2 "I requre ip but it's not installed.\nNo QR Code can be printed."; return; } + + CURRENTIP="$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')" + qrencode -t UTF8 "http://${CURRENTIP}:${MARKSERVPORT}" + + } + # **** Help function ConvertHelp () { diff --git a/bin/makeConfig.bash b/bin/makeConfig.bash new file mode 100755 index 0000000..b05d24a --- /dev/null +++ b/bin/makeConfig.bash @@ -0,0 +1,142 @@ +#! /usr/bin/env bash +# +# Author: Ryan Greenup + +# * Shell Settings +set -o errexit # abort on nonzero exitstatus +set -o nounset # abort on unbound variable +set -o pipefail # don't hide errors within pipes + +# * Main Function +main() { + + # Use STDERR so as to not clog STDIN + # Is there a better way to do this? + echoerr() { echo -e "$@" 1>&2; } + + + check_for_dependencies + setVars + readFirstArgument "${@}" + AskValues + + if [ "${promptComplete}" != "Completed" ]; then + exit 1 + fi + + MakeConfig "${@}" + +} + +# ** Helper Functions +# *** Check for Dependencies +check_for_dependencies () { + + for i in ${DependArray[@]}; do + command -v "$i" >/dev/null 2>&1 || { echo >&2 "I require $i but it's not installed. Aborting."; exit 1; } + done + + +} + +# **** List of Dependencies + +declare -a DependArray=( + "jq" + "cat" + "xclip" + ) + + +# *** Set variables below main +setVars () { + readonly script_name=$(basename "${0}") + readonly script_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) + IFS=$'\t\n' # Split on newlines and tabs (but not on spaces) +} + +# **** Print Help +Help () { + + + echo + echo -e " \e[3m\e[1mMakeConfig.sh \e[0m; Helpful Shell Scripts for Markdown Notes" + echo -e " \e[1;31m--------------------------\e[0m " + echo + echo -e " \e[3m\e[1m• Usage \e[0m " + echo + echo -e " "${script_name}" [-h]" + echo -e " "${script_name}" [--help]" + echo + echo -e " Fully Interactive, just follow the prompts" + echo + echo -e " \e[3m By Design: No Options; No Arguments\e[0m" + echo + echo -e " \e[3m\e[1m• Compatability \e[0m " + echo + echo -e " This prints everything to STDERR to that STDOUT only has" + echo -e " The config file in it, I'm not sure if that's an issue " + echo + exit 0 +} + + +# *** Read First Argument +readFirstArgument () { + + if [[ "${1:-}" == "-h" ]] || [[ "${1:-}" == "--help" ]]; then + Help && exit 0 + fi + +} + +# *** +AskValues () { + echoerr "Please Enter the Directory of you Markdown Files" + echoerr "\t (This directory should contain index.md or home.md)" + read NOTES_DIR + NOTES_DIR="$(echo "${NOTES_DIR/\~/$HOME}")" + read -d '' -s -n1 choice +# NOTES_DIR="$(cd /; sk --height 40% -i -c 'fd {}' )" + [[ -d "${NOTES_DIR}" ]] || echoerr -e "\n \e[3m\e[1m \e[1;31m ⚠ WARNING: \e[0m No Such Directory!" + + + echoerr "\nPlease Enter the Directory of the recoll config you want to use" + echoerr "\t Leave it blank to use the default config" + echoerr "\t This is not implemented so don't worry" + read RECOLL_CONFIG_DIR + RECOLL_CONFIG_DIR="$(echo "${RECOLL_CONFIG_DIR/\~/$HOME}")" + [[ -d "${RECOLL_CONFIG_DIR}" ]] || echoerr "\n \e[3m\e[1m \e[1;31m ⚠ WARNING: \e[0m No Such Directory!" + + echoerr "\nPlease Enter the location of your mkdocs yml" + echoerr "\t (If you're not going to use this just leave it blank and press Enter)" + read MKDOCS_YML + MKDOCS_YML="$(echo "${MKDOCS_YML/\~/$HOME}")" + [[ -f "${MKDOCS_YML}" ]] || echoerr -e "\n \e[3m\e[1m \e[1;31m ⚠ WARNING: \e[0m No Such File!" + + echoerr "\nPlease Enter the Directory in which you want mkdocs to build your static site" + echoerr "\t (If you're not going to use this just leave it blank and press Enter)" + read SERVER_DIR + SERVER_DIR="$(echo "${SERVER_DIR/\~/$HOME}")" + [[ -d "${SERVER_DIR}" ]] || echoerr -e "\n \e[3m\e[1m \e[1;31m ⚠ WARNING: \e[0m No Such Directory!" + + promptComplete="Completed" + +} +# *** Make Config +MakeConfig () { + +JSON_STRING=$( jq -n \ + --arg nd "$NOTES_DIR" \ + --arg sd "$SERVER_DIR" \ + --arg rc "$RECOLL_CONFIG_DIR" \ + --arg mk "$MKDOCS_YML" \ + '{notesDir: $nd, serverDir: $sd, recollConfigDir: $rc, mkdocsConfigDir: $mk}' ) + + echo "$JSON_STRING" + + exit 0 +} + +# * Call Main Function +main "${@}" diff --git a/cadmus b/cadmus deleted file mode 100644 index 8c98006..0000000 --- a/cadmus +++ /dev/null @@ -1,124 +0,0 @@ -#! /usr/bin/env bash -# -# Author: Ryan Greenup -# abort on nonzero exitstatus -set -o errexit -# abort on unbound variable -set -o nounset -# don't hide errors within pipes -set -o pipefail - - -## * Main Functions - -main() { - - setvars - [[ -z "${1:-}" ]] && mainHelp - arguments "${@:-}" -} - -function setvars() { - - IFS=$'\t\n' # Split on newlines and tabs (but not on spaces) - readonly script_name=$(basename "${0}") - readonly script_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) - readonly TERMINAL="kitty" - readonly TERMINAL_EXEC='kitty -- ' - readonly NOTES_DIR="$HOME/Notes" - - -} - - -# * Sub-functions -# ** Help - -function mainHelp() { - - echo - echo -e " \e[3m\e[1m Cadmus\e[0m; Helpful Shell Scripts for Markdown Notes" - echo -e " \e[1;31m -------------------------\e[0m " - echo - - echo -e " \e[1;91m \e[1m Command \e[0m\e[0m \e[1;34m┊┊┊ \e[0m Description " - echo -e " ..............\e[1;34m┊┊┊\e[0m........................................... " - echo -e " 🔍 \e[1;93m find \e[0m \e[1;34m ┊┊┊ \e[0m Find Notes based on FileName" - echo -e " 🔎 \e[1;32m search \e[0m \e[1;34m ┊┊┊ \e[0m Search through Notes using Recoll" - echo -e " 🏷 \e[1;33m tags \e[0m \e[1;34m ┊┊┊ \e[0m Use TMSU to work with tags" - echo -e " 🔧 \e[1;34m tools \e[0m \e[1;34m ┊┊┊ \e[0m Tools for Editing" - echo -e " 📝 \e[1;35m export \e[0m \e[1;34m ┊┊┊ \e[0m Export Notes to Different Formats " - echo -e " ⎋ \e[1;36m convert \e[0m \e[1;34m ┊┊┊ \e[0m Convert Clipboard Contents to Different Formats " - echo -e " 🧰 \e[1;37m misc \e[0m \e[1;34m ┊┊┊ \e[0m Miscelanneous Tools nice to have on hand " - echo -e " 🌏\e[1;92m publish\e[0m \e[1;34m ┊┊┊ \e[0m Publish with \e[1;34m \e[4m\e[3mMkDocs\e[0m\e[0m🐍" - echo -e " 🕮 \e[1;92m preview \e[0m \e[1;34m ┊┊┊ \e[0m Preview with \e[1;34m \e[4m\e[3mMarkServ\e[0m\e[0m " - - echo - } - -# ** Main Arguments - Level 0 -# -arguments () { - - while test $# -gt 0 - do - case "$1" in - --help) Help - ;; - -h) Help - ;; - find) shift; NoteFind "${@:-}" ## Don't steal function name - ;; - search) echo "begin note search" - ;; - tags) echo "begin tags" - ;; - tools) echo "begin tools" - ;; - export) echo "begin export" - ;; - convert) echo "begin convert" - ;; - misc) echo "begin misc" - ;; - publish) echo "begin publish" - ;; - preview) echo "begin preview" - ;; - --*) >&2 echo "bad option $1" - ;; - *) >&2 echo -e "argument \e[1;35m${1}\e[0m has no definition." - ;; - esac - shift - done -} - -# *** Find - -function NoteFind() { - - bash "NoteFind.sh "${@:-}"" -} - -mytest() { - echo "This is a test" - exit 0 -} - -Help () { - # Display Help - echo "Add description of the script functions here." - echo - echo "Syntax: scriptTemplate [-g|h|t|v|V]" - echo "options:" - echo "g Print the GPL license notification." - echo "h Print this Help." - echo "v Verbose mode." - echo "V Print software version and exit." - exit 0 -} - - -main "${@}" - diff --git a/install.sh b/install.sh index 32a347f..85d0b92 100755 --- a/install.sh +++ b/install.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +INSTALL_DIR="$HOME/.cadmus" +BIN_DIR="$HOME/.local/bin/" main () { me=`basename "$0"` @@ -6,16 +8,24 @@ main () { HelpStatement $1 UninstallQ $1 printThis - check_for_dependencies download_the_repo - Install_tools "S" + Install_bin + check_path + check_for_dependencies + + echo -e "\nInstallation Complete \n" +} + +check_path () { + echo "$PATH" | grep -q '.local/bin' || echo "bin-dir is not in path, you'll need to add it to the path" } function UninstallQ() { if [ "$1" == "-rm" ] || [ "$1" == "--rm" ]; then - echo "Removing with Stow" - Install_tools "D" + echo "Removing..." + rm "$HOME/.local/bin/cadmus" + rm "${INSTALL_DIR}" exit 0 fi @@ -24,7 +34,7 @@ function UninstallQ() { HelpStatement() { if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then - echo -e "To uninstall do `basename $0` --rm is the script name, + echo -e "To uninstall do `basename $0` --rm , If you are on Arch stow 2.3.1-2 is broken, downgrade with @@ -53,7 +63,7 @@ printThis () { safePrint $me - echo "Are you happy to proceed? Press y to continue" + echo -e "\nAre you happy to proceed? Press y to continue \n" read -d '' -s -n1 proceedQ if [ "$proceedQ" != "y" ]; then exit 0 @@ -62,71 +72,100 @@ printThis () { safePrint () { if hash highlight 2>/dev/null; then - highlight "$@" + highlight "${1}" --syntax=bash --stdout else - cat "$@" + cat "${1}" fi } check_for_dependencies () { - echo "Press Any Key to Check for dependencies, press the c Key to Skip this" - read -d '' -s -n1 CheckDepQ - if [ "$CheckDepQ" == "c" ]; then - return - fi + ## echo "Press Any Key to Check for dependencies, press the c Key to Skip this" + ## read -d '' -s -n1 CheckDepQ + ## if [ "$CheckDepQ" == "c" ]; then + ## return + ## fi + ## + depLog="$(mktemp)" for i in ${StringArray[@]}; do - command -v "$i" >/dev/null 2>&1 || { echo >&2 "I require $i but it's not installed. Aborting."; exit 1; } + command -v "$i" >/dev/null 2>&1 || { echo $i >> "${depLog}"; } done - echo "All Dependencies Satisfied" + if [[ $(cat "${depLog}") == "" ]]; then + echo -e "\nAll Dependencies Satisfied\n" + else + echo -e "\e[1;31m \nMissing the Following Dependencies \e[0m \n" + echo -e " \e[1;31m -------------------------\e[0m " + echo -e "\e[1;32m \n" + addBullets "$(cat "${depLog}")" + echo -e "\e[0m \n" + echo -e "They are listed in \e[1;34m "${depLog}" \e[0m \n" + fi +} + +addBullets() { + command -v sed >/dev/null 2>&1 || { echo >&2 "I require sed but it's not installed. Aborting."; exit 1; } + echo "$1" | sed 's/^/\t‣\ /g' } download_the_repo () { - echo "Press y to download the repo" - read -d '' -s -n1 downloadQ - if [ "$downloadQ" != "y" ]; then - return - fi + if [[ -d "${INSTALL_DIR}" ]]; then + echo -e "Detected a cadmus install" - mkdir -p $HOME/DotFiles/ - cd $HOME/DotFiles - - - if [[ -d ".git" ]]; then - echo "Detected a Git Repo, Press y to add a submodule or any key to exit" - - read -d '' -s -n1 CheckDepQ - if [ "$CheckDepQ" != "y" ]; then - echo "You pressed any key" + if [ -f "${INSTALL_DIR}/config.json" ]; then + oldConfigFile="$(mktemp)" && cat "${INSTALL_DIR}/config.json" > "${oldConfigFile}" + echo -e "\n\tConfig File Backed up for later restore\n" fi - git submodule add https://github.com/RyanGreenup/cadmus && echo "Submodule succesfully added" - - elif [[ -f ".git" ]]; then - echo "You have a file called .git In there, delete that first."; + ask_to_remove + download_the_repo + return else - git clone https://github.com/RyanGreenup/cadmus + git clone https://github.com/RyanGreenup/cadmus "$HOME/.cadmus" fi - echo "Repository is downloaded" + echo -e "Repository is downloaded\n\n" + if [[ "$CheckDepQ" == "y" ]] && [[ -f "${oldConfigFile}" ]]; then + echo -e "Press y to restore the old config or any other key to continue otherwise\n" + read -d '' -s -n1 CheckDepQ + cp "${oldConfigFile}" "${INSTALL_DIR}/config.json" + echo -e "Config Successfully restored" + fi } -Install_tools () { +ask_to_remove () { + echo "press y to remove "${INSTALL_DIR}"" - DIR=$(dirname "$0") - cd "$DIR" && cd ../ - echo "Stow package $DIR, target $HOME" - stow -t $HOME -$1 "$(basename "$DIR")" + read -d '' -s -n1 CheckDepQ + if [ "$CheckDepQ" == "y" ]; then + rm -rf "${INSTALL_DIR}" + else + exit 1 + fi +} + +Install_bin() { + if [ -f "${BIN_DIR}/cadmus" ]; then + echo -e "The executable \e[1;32m "${BIN_DIR}"/cadmus \e[0m already exists, it must be replaced, press y to continue or any key to exit" + read -d '' -s -n1 CheckDepQ + if [ "$CheckDepQ" == "y" ]; then + rm "${BIN_DIR}/cadmus" + else + exit 1 + fi + Install_bin + else + ln -s "$HOME/.cadmus/bin/cadmus" "$HOME/.local/bin/" && echo -e "\nSuccessfully created symlink from $HOME/.cadmus/bin/cadmus to $HOME/.local/bin/ \n" + fi } # Declare an array of string with type -declare -a StringArray=("R" +declare -a StringArray=( "highlight" "node" "nvim" @@ -135,11 +174,15 @@ declare -a StringArray=("R" "sk" "rg" "perl" + "tectonic" "stow" "python" "tmsu" "ranger" "mdcat" + "jq" + "shift" + "ip" "xclip" "sd" "fd" diff --git a/media/Many_Commands_Bigger.png b/media/Many_Commands_Bigger.png new file mode 100644 index 0000000..9f3efc9 Binary files /dev/null and b/media/Many_Commands_Bigger.png differ diff --git a/media/Many_Examples.png b/media/Many_Examples.png new file mode 100644 index 0000000..c57039f Binary files /dev/null and b/media/Many_Examples.png differ diff --git a/media/TagsExample.gif b/media/TagsExample.gif new file mode 100644 index 0000000..c51b51f Binary files /dev/null and b/media/TagsExample.gif differ diff --git a/sd b/sd new file mode 100644 index 0000000..e69de29 diff --git a/sed b/sed new file mode 100644 index 0000000..e69de29