diff options
Diffstat (limited to 'home')
| -rw-r--r-- | home/zaread.nix | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/home/zaread.nix b/home/zaread.nix new file mode 100644 index 0000000..487740a --- /dev/null +++ b/home/zaread.nix @@ -0,0 +1,257 @@ +{ pkgs, lib, ... }: + +let + zareadScript = pkgs.writeShellScriptBin "zaread" '' + # zaread cache path + ZA_CACHE_DIR="''${XDG_CACHE_HOME:-"$HOME"/.cache}/zaread/" + # zaread config path + ZA_CONFIG="''${XDG_CONFIG_HOME:-"$HOME"/.config}/zaread/zareadrc" + + # Default reader, i.e. command, which script uses to open pdf, epub and converted files + READER="${pkgs.zathura}/bin/zathura" + # Default converters, i.e. commands, which script uses to convert files to pdf + MOBI_CMD="${pkgs.calibre}/bin/ebook-convert" + OFFICE_CMD="${pkgs.libreoffice-fresh}/bin/soffice" + MD_CMD="${pkgs.md2pdf or pkgs.pandoc}/bin/${if pkgs ? md2pdf then "md2pdf" else "pandoc"}" + TYPST_CMD="${pkgs.typst}/bin/typst" + TYPST_ARG="compile" # Can be changed to "watch" + MD_ARG="" + MOBI_ARG="" + OFFICE_ARG="--headless" + # If you want to use other commands set these vars in $ZA_CONFIG. Some cli + # arguments are hardcoded so some commands won't work. Check that first. + + # Sources the variables from config file if exists + # shellcheck disable=1090 + [ -f "$ZA_CONFIG" ] && . "$ZA_CONFIG" + + # if $ZA_CACHE_DIR doesn't exist, we create it. + [ ! -d "$ZA_CACHE_DIR" ] && mkdir -p "$ZA_CACHE_DIR" + + # Exit if called without arguments + if [ "$#" = 0 ]; then + echo "No files to open." + exit + fi + + if [ "$#" != 1 ]; then + echo "More than one filename given. Closing." + exit 1 + fi + + path="$1" + + if [ ! -f "$path" ]; then + echo "File doesn't exist." + exit 1 + fi + + if ! command -v "$READER" >/dev/null; then + echo "$READER is not on the $PATH." + echo "Closing." + exit 1 + fi + + echo "\$READER='$READER' is in the \$PATH. Starting script..." + + ## create position and file variables ## + + # complete file name (path excluded): + file="$(basename "$path")" + echo "Filename: $file" + case "$path" in + # complete directory path: + # if it has been inserted absolute path ($path starts with '/') + /*) + directory="$(dirname "$path")" + ;; + # else (relative path inserted) + *) + directory="''${PWD}/$(dirname "$path")" + # directory="$(echo "$dir" | tr -s '/')" + ;; + esac + + echo "Directory: $directory/" + echo "Path: $directory/$file" + + # get file type + + # if the file is itself a pdf, a djvu or an epub, or we already have a pdf converted version, + # then we don't need a converter. But if it's an already converted document, then + # file position is different: we must distinguish between original and converted files + file_mt="$(file --mime-type "$directory/$file")" + file_mt="''${file_mt#*: }" + echo "Mime type: $file_mt" + + cd "$directory" || { + echo "Couldn't cd into $directory" + exit 1 + } + + # $pdffile is a string composed this way: CRC_BYTECOUNT_$filename.[pdf,epub] + # if the converted file exists, then it's named like $pdffile + pdffile="$(cksum "$file" | sed -E 's/^([0-9]+) ([0-9]+) (.*)$/\1_\2_\3.pdf/')" + echo "Converted pdf filename: $pdffile" + + file_converter="" + # If the converted file exists we can just open it. + if [ -f "$ZA_CACHE_DIR/$pdffile" ]; then + file_converter="none_converted" + else + case "$file_mt" in + "application/pdf" | "image/vnd.djvu" | "application/epub+zip") + # If the file is a pdf, a djvu or an epub we don't need to convert it. + file_converter="none_original" + ;; + "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | \ + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | \ + "application/vnd.openxmlformats-officedocument.presentationml.presentation" | \ + "application/msword" | \ + "application/vnd.ms-excel" | \ + "application/vnd.ms-powerpoint" | \ + "application/vnd.oasis.opendocument.text" | \ + "application/vnd.oasis.opendocument.spreadsheet" | \ + "application/vnd.oasis.opendocument.presentation" | \ + "text/rtf" | \ + "text/csv") + # If the file is an office file (ooxml or the old format or an + # opendocument) we convert it using $OFFICE_CMD. + file_converter="$OFFICE_CMD" + ;; + "application/octet-stream" | \ + "application/x-mobipocket-ebook") + + case "$file" in + *.mobi) + # If the file is a mobi ebook we convert it using $MOBI_CMD. + file_converter="$MOBI_CMD" + ;; + esac + ;; + "text/plain" | \ + "text/x-c" | \ + "text/x-objective-c" | \ + "text/x-script.python" ) + case "$file" in + *.md) + # If the file is a markdown we convert it using $MD_CMD. + file_converter="$MD_CMD" + ;; + *.typ) + file_converter="$TYPST_CMD" + ;; + esac + ;; + esac + fi + + case "$file_converter" in + "") + echo "The file format is unsupported." + exit 2 + ;; + "none_original") + echo "The file is already in PDF format. We just open it." + eval "$READER" \""$directory/$file"\" + ;; + "none_converted") + echo "We already converted this file. We just open it." + eval "$READER" \""$ZA_CACHE_DIR/$pdffile"\" + ;; + *) + # So the file is not a pdf or an epub, and a converted version + # doesn't exist, but its format may be convertible + if command -v "$file_converter" >/dev/null; then + echo "We are starting to convert the file \"$file\" using $file_converter" + # If converter tools are changed in $ZA_CONFIG check calling + # commands bellow. They may need to be called with different + # arguments and format. + case "$file_converter" in + "$OFFICE_CMD") + eval "$OFFICE_CMD" "$OFFICE_ARG" --convert-to pdf \""$directory/$file"\" --outdir \""$ZA_CACHE_DIR"\" + # We need to handle cases where file starts with a . and + # that's the only one . in filename, i.e. filename hasn't + # got extension + case "$file" in + .*.*) + # If it has one more . after the first character + # which is a ., we'll consider that as an + # extension, so we can use parameter expansion, + # and we need this case for the next one to work. + tmpfile="''${file%.*}.pdf" + ;; + .*) + # If this case was the first it would also match cases with 2 .'s in the filename. + # If the filename starts with a . and it hasn't got an + # extension, we just add .pdf to the filename to get + # tmpfilename + tmpfile="$file.pdf" + ;; + *) + # In the rest of cases we can use parameter expansion + tmpfile="''${file%.*}.pdf" + ;; + esac + mv "$ZA_CACHE_DIR/$tmpfile" "$ZA_CACHE_DIR/$pdffile" + ;; + "$MOBI_CMD") + eval "$MOBI_CMD" "$MOBI_ARG" \""$directory/$file"\" \""$ZA_CACHE_DIR/$pdffile"\" + ;; + "$MD_CMD") + if [ "$MD_CMD" = "${pkgs.pandoc}/bin/pandoc" ]; then + eval "$MD_CMD" "$MD_ARG" \""$directory/$file"\" -o \""$ZA_CACHE_DIR/$pdffile"\" + else + eval "$MD_CMD" "$MD_ARG" \""$directory/$file"\" -o \""$ZA_CACHE_DIR/$pdffile"\" + fi + ;; + "$TYPST_CMD") + eval "$TYPST_CMD" "$TYPST_ARG" \""$directory/$file"\" \""$ZA_CACHE_DIR/$pdffile"\" --open "$READER" + exit + ;; + esac + else + echo "The command we need to convert '$file_converter' is not in \$PATH." + exit 4 + fi + echo "Now we can open the file $ZA_CACHE_DIR/$pdffile" + # ...and after the conversion we open the file + eval "$READER" \""$ZA_CACHE_DIR/$pdffile"\" + ;; + esac + ''; +in +{ + home.packages = [ zareadScript ]; + + xdg.desktopEntries.zaread = { + name = "zaread"; + exec = "${zareadScript}/bin/zaread %f"; + icon = "org.pwmt.zathura"; + comment = "Lightweight ebook and office document reader"; + terminal = false; + noDisplay = true; + categories = [ + "Office" + "Viewer" + ]; + mimeType = [ + "application/pdf" + "image/vnd.djvu" + "application/epub+zip" + "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + "application/vnd.openxmlformats-officedocument.presentationml.presentation" + "application/msword" + "application/vnd.ms-excel" + "application/vnd.ms-powerpoint" + "application/vnd.oasis.opendocument.text" + "application/vnd.oasis.opendocument.spreadsheet" + "application/vnd.oasis.opendocument.presentation" + "text/rtf" + "text/csv" + "application/x-mobipocket-ebook" + "text/plain" + ]; + }; +} |
