Browse Source

Started including fbopt and lots of fixes. This is a backup commit.

dev
Franco Masotti 4 years ago
parent
commit
4b00b518b6
  1. 213
      fbopt
  2. 175
      spectrscan

213
fbopt

@ -0,0 +1,213 @@
#!/bin/bash
#
# fbopt version 0.4.1
#
# Written in 2018 by Franco Masotti/frnmst <franco.masotti@live.com>
#
# To the extent possible under law, the author(s) have dedicated all
# copyright and related and neighboring rights to this software to the public
# domain worldwide. This software is distributed without any warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication along
# with this software. If not, see
# <http://creativecommons.org/publicdomain/zero/1.0/>.
#
#
# See also https://frnmst.gitlab.io/notes/my-bash-option-parsing-template.html
#
show_help()
{
cat <<-EOF
Usage: spectrscan [OPTION] OUTFILE
An unintrusive frontend of scanimage which acts as a
paper to pdf converter suitable for texts.
If the ouput file exists then the new scanned documents will be added
as the tail of the existing one.
The default system scanner is used.
Mandatory arguments to long options are mandatory for short options too.
Options:
-h, --help print this help
-i, --imagemagick=OPTIONS pass options to ImageMagick
to post-process the documents
--list-modes list all possible scan modes
--list-resolutions list all possible resolutions
--list-sources list all possible sources
-m, --mode=MODE scan in Color, Lineart, Gray or whatever
supported method
--print-flags print the enabled options. This can also
be used to print the default options
-r, --resolution=RESOLUTION page resolution in DPI
-s, --source=SOURCE scan from the ADF, Flatbed or whatever
supported method
-t, --two-sided toggle preserve the order in double sided paper:
scan a batch of papers one side, then the other
--two-sided-reverse same as '--odd-even' but with the need of
reversing every single paper.
-u, --unpaper[=OPTIONS] enable unpaper. You may pass
options to unpaper
Exit status:
0 if OK,
1 if an error occurred.
This is free software: you are free to change and redistribute it. There
is NO WARRANTY, to the extent permitted by law.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
Copyright © 2017 Franco Masotti.
EOF
}
# A function that prints the variable name and value of all
# the flags enabled by the user. This is useful to check that
# all the flags are correct, as kind of a dry run.
show_flags()
{
local flags="${*}"
for flag in ${flags}; do
printf "%s='%s'\n" "${flag}" "${!flag}"
done
}
getopt_error()
{
local program_name="${0}"
printf "%s\n" "Try '"${program_name}" --help' for more information"
} 1>&2 2>&-
main()
{
# Create a new array from the reference of the input one.
# See https://stackoverflow.com/questions/1063347/passing-arrays-as-parameters-in-bash
# See some comments below.
declare -a argc=("${!1}")
local getopt_short_options='hi:mrstu::'
local getopt_long_options='help,imagemagick:,list-modes,list-resolutions,list-sources,mode:,print-flags,resolution:,source:,two-sided,two-sided-reverse,unpaper::'
# Set the default values for the flags.
local imagemagick='-normalize -level 70%,100%,1.0'
local mode='Lineart'
local resolution='300'
local source='ADF'
local unpaper='false'
local program_name="${0}"
opts="$(getopt \
--name "${program_name}" \
--shell bash \
--options "${getopt_short_options}" \
--longoptions "${getopt_long_options}" \
-- \
"${argc[@]}")"
getopt_retval=${?}
# Check that getopt works and that some kind of argument
# is passed to the script. This is "quotation hell".
a="'"${argc[@]}"'"
{ [ ${getopt_retval} -ne 0 ] || [ -z "${a}" ]; } && getopt_error && return 1
eval set -- "${opts}"
# Option parsing.
while [ "${1}" != '--' ]; do
case "${1}" in
-h | --help ) help='true' ;;
-i | --imagemagick ) imagemagick="${2}";
shift 1 ;;
--list-modes ) list_modes='true' ;;
--list-sources ) list_sources='true' ;;
--list-resolutions ) list_resolutions='true' ;;
-m | --mode ) mode="${2}";
shift 1 ;;
--print-flags ) print_flags='true' ;;
-r | --resolution ) resolution="${2}";
shift 1 ;;
-s | --source ) source="${2}";
shift 1 ;;
-t | --two-sided ) two_sided='true' ;;
--two-sided-reverse ) two_sided_reverse='true' ;;
-u | --unpaper ) unpaper="${2}";
shift 1 ;;
esac
# Iterate through all arguments.
shift 1
done
shift 1
# Everything else after '--' is an argument.
argc="${*}"
# Check that the flags that must be non empty are actually not empty.
# A user might infact circumvent getopt's mechanisms like this
# ./program -flag ''
# This can also be done inside the option parser loop but to avoid nestings
# I prefer it done here.
{ [ -z "${imagemagick}" \
|| [ -z "${mode}" ] \
|| [ -z "${resolution}" ] \
|| [ -z "${source}"; } \
&& getopt_error && return 1
[ "${print_flags}" = 'true' ] \
&& show_flags \
'flag_a' \
'flag_b' \
'flag_c' \
'flag_d' \
'flag_e' \
'flag_f' \
&& return 0
[ "${help}" = 'true' ] && show_help && return 0
# Override values of optional parameters.
[ -z "${flag_f}" ] && flag_f='true'
# From now on you should call a function or an external program
# using the values of the flag variables.
[ "${list_modes}" = 'true' ] && get_supported_modes && return ${?}
[ "${list_resolutions}" = 'true' ] && get_supported_resolutions && return ${?}
[ "${list_sources}" = 'true' ] && get_supported_sources && return ${?}
local output_file="${1}"
[ -z "${output_file}" ] && getopt_error && return 1
preliminary_controls \
"${imagemagick}" \
"${mode}" \
"${resolution}" \
"${source}" \
"${unpaper}" \
"${output_file}"
}
# Test dependencies and versions.
# getopt must return 4 to be fully compatible. See getopt's manual.
which bash getopt 1>/dev/null 2>/dev/null && { getopt -T; [ ${?} -eq 4 ]; }
# Get and pass argc to the main function.
# All this work with an array must be done to preserve
# quotations for arguments that have whitespaces.
# See https://lists.debian.org/debian-user/2007/12/msg01244.html
declare -a opts=()
for opt in "${@}"; do
opts=("${opts[@]}" "${opt}")
done
main 'opts[@]'

175
spectrscan

@ -21,73 +21,15 @@
# You should have received a copy of the GNU General Public License
# along with spectrscan. If not, see <http://www.gnu.org/licenses/>.
#
tmp_dir="$(pwd)/.spectrscan-$RANDOM"
src_dir="$(pwd)"
imagemagick_options="-normalize -level 70%,100%,1.0"
mode="Lineart"
resolution="600"
source="ADF"
odd_even="false"
unpaper_options="true"
output_file=""
########
########
help()
{
cat <<-EOF
Usage: spectrscan [OPTIONS] OUTFILE
An unintrusive frontend of scanimage which acts as a
paper to pdf converter suitable for texts.
If the ouput file exists then the new scanned documents will be added
as the tail of the existing one.
The default system scanner is used.
Options:
-h, --help print this help
-i, --imagemagick-options pass options to ImageMagick
to post-process the documents
-m, --mode scan in Color, Lineart, Gray or whatever
supported method
--list-modes list all possible scan modes
-o, --odd-even toggle preserve the order in double sided paper:
scan a batch of papers one side, then the other
-r, --resolution page resolution in DPI
--list-resolutions list all possible resolutions
-s, --source scan from the ADF, Flatbed or whatever
supported method
--list-sources list all possible sources
-u, --unpaper-options pass options to unpaper
to post-process the documents
Current enabled options:
--imagemagick-options="$imagemagick_options"
--mode "$mode" --odd-even="$odd_even" --resolution "$resolution"
--source "$source" --unpaper-options="$unpaper_options"
The magic values of "true" and "false" can be used
to enable or disable:
--odd-even=<value>
--unpaper-options=<value> (if "false", unpaper is disabled)
Dependencies: GNU Bash; GNU Core Utilities; Gawk; SANE; ImageMagick
unpaper; PDFtk; GNU Parallel; Netpbm
Exit status:
0 if OK,
1 if an error occurred.
Copyright © 2017 Franco Masotti. License GPLv3+: GNU GPL version 3 or
later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it. There
is NO WARRANTY, to the extent permitted by law.
EOF
}
init()
{
mkdir "$tmp_dir"
@ -179,7 +121,7 @@ pnm_to_pdf()
# A hack to avoid GNU Parallel's message
mkdir -p ~/.parallel && touch ~/.parallel/will-cite
# n = number of new pages
# Time complexity: O(n/#cores)
# Time complexity: O(n/#threads)
export -f convert_single
export unpaper_options
export imagemagick_options
@ -233,7 +175,7 @@ chain()
scan
fi
# Feeder out of documents
# Feeder out of documents.
if [ $? -eq 7 ]; then
printf "No paper inserted\n" 1>&2
return 1
@ -244,97 +186,30 @@ chain()
cleanup
}
getopt_error()
get_supported_parameters()
{
printf "%s\n" "Try 'spectrscan --help' for more information"
} 1>&2-
scanimage -A | grep -e '--source' -e '--mode' -e '--resolution'
}
get_supported_resolutions()
{
printf "%s\n" "$(scanimage -A | grep resolution | head -n1 \
| awk '{print $2}' | tr '|' ' ' | tr -d 'dpi')"
local supported_params="${1}"
echo "${supported_params}" | awk '{print $2}' | tr '|' ' ' | tr -d 'dpi'
}
get_supported_modes()
{
printf "%s\n" "$(scanimage -A | grep mode | head -n2 \
| tail -n 1 | awk '{print $2}' | tr '|' ' ')"
}
local supported_params="${1}"
get_supported_sources()
{
printf "%s\n" "$(scanimage -A | grep source | head -n1 \
| awk '{print $2}' | tr '|' ' ')"
echo "${supported_params}" | grep mode | awk '{print $2}' | tr '|' ' '
}
probe_for_scanner()
{
scanimage -n
if [ $? -eq 1 ]; then
printf "false"
else
printf "true"
fi
}
option_parser()
get_supported_sources()
{
local argc="$1"
local options="i::hm:o::r:s:u::"
local long_options="help,imagemagick-options::,list-modes,\
list-resolutions,list-sources,mode:,odd-even::,resolution:,\
source:,unpaper-options::"
local opts=""
local opt=""
[ -z "$argc" ] && getopt_error && return 1
opts="$(getopt --options $options --longoptions $long_options --name spectrscan -- $argc)"
[ $? -ne 0 ] && getopt_error && return 1
eval set -- "$opts"
while true ; do
case "$1" in
-h | --help ) shift; help; return 2 ;;
-i | --imagemagick-options )
case "$2" in
* ) imagemagick_options="$2"; shift 2 ;;
esac ;;
-m | --mode )
case "$2" in
"" ) getopt_error && return 1 ;;
* ) mode="$2"; shift 2 ;;
esac ;;
--list-modes ) shift; get_supported_modes; return 2 ;;
-o | --odd-even )
case "$2" in
"true" | "" ) odd_even="true"; shift 2 ;;
"false" ) odd_even="false"; shift 2 ;;
* ) getopt_error && return 1 ;;
esac ;;
-r | --resolution )
case "$2" in
"" ) getopt_error && return 1 ;;
* ) resolution="$2"; shift 2 ;;
esac ;;
--list-resolutions ) shift; get_supported_resolutions; \
return 2 ;;
-s | --source )
case "$2" in
"" ) getopt_error && return 1 ;;
* ) source="$2"; shift 2 ;;
esac ;;
--list-sources ) shift; get_supported_sources; return 2 ;;
-u | --unpaper-options )
unpaper_options="$2"; shift 2 ;;
-- ) shift; break ;;
* ) return 1 ;;
esac
done
local supported_params="${1}"
output_file="$1"
echo "${supported_params}" | grep source | awk '{print $2}' | tr '|' ' '
}
check_supported_parameters()
@ -345,6 +220,7 @@ check_supported_parameters()
local parameter_full_name=""
local p=""
#TODO.
parameter_full_name="supported_${parameter}"
eval "$parameter_full_name='$(get_supported_${parameter})'"
for p in ${!parameter_full_name}; do
@ -360,29 +236,16 @@ check_supported_parameters()
preliminary_controls()
{
if [ -z "$output_file" ]; then
printf "Missing output file\n" 1>&2-
getopt_error
return 1
fi
printf "Probing scanner and its options...\n" 1>&2-
if [ "$(probe_for_scanner)" = "false" ]; then
printf "No scanner detected\n" 1>&2-
return 1
fi
params="$(get_supported_parameters)"
[ ${?} -ne 0 ] && return ${?}
{ check_supported_parameters "modes" "$mode" \
&& check_supported_parameters "resolutions" "$resolution" \
&& check_supported_parameters "sources" "$source"; } || return 1
}
main()
{
local argc="$1"
option_parser "$argc" && { preliminary_controls && chain; }
chain
}
main "$*"
. ./fbopt