|
#!/bin/bash |
|
|
|
# The MIT License (MIT) |
|
# |
|
# Copyright (c) 2013 https://gist.github.com/rbf |
|
# |
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of |
|
# this software and associated documentation files (the "Software"), to deal in |
|
# the Software without restriction, including without limitation the rights to |
|
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
|
# the Software, and to permit persons to whom the Software is furnished to do so, |
|
# subject to the following conditions: |
|
# |
|
# The above copyright notice and this permission notice shall be included in all |
|
# copies or substantial portions of the Software. |
|
# |
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
|
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
|
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
|
### File info: |
|
|
|
GP_VERSION="v2.6-SNAPSHOT" |
|
GP_RAW_URL="https://gist.github.com/rbf/6064734/raw" |
|
GP_SOURCE="${GP_RAW_URL}/process-md" |
|
GP_DOC="https://gist.github.com/rbf/6064734" |
|
GP_INSTALL_PATH="/usr/local/bin/" |
|
|
|
### |
|
|
|
GP_COMMAND_BASENAME=$(basename "${GP_SOURCE}") |
|
GP_COMMAND_NAME="${0#${GP_INSTALL_PATH}}" |
|
|
|
GP_CURL_BASE="curl -sSL ${GP_SOURCE}" |
|
GP_CURL_COMMAND_BASE="bash <(${GP_CURL_BASE})" |
|
|
|
GP_INSTALL_CURL="curl -sSL https://gist.github.com/rbf/6064734/raw/install" |
|
GP_INSTALL_BASH_CURL="bash <(${GP_INSTALL_CURL})" |
|
|
|
GP_INSTALLED_SCRIPT="${GP_INSTALL_PATH}${GP_COMMAND_BASENAME}" |
|
|
|
# Flags defaulted to false |
|
GP_DATE_OUTPUT_FILES="false" |
|
|
|
millisecs(){ |
|
if date --version 2>/dev/null 1>/dev/null |
|
then |
|
# centos |
|
current_millisecs="$(date +"%s%N")" |
|
echo "${current_millisecs%??????}" # remove last 6 digits to go from nanosecs to millisecs |
|
else |
|
# mac |
|
# older version of 'date' without %N for nanoseconds |
|
current_millisecs="$(python -c "import time; import re; print re.sub('\.', '', '%.3f' % time.time())" 2>/dev/null)" |
|
if [ $? == 0 ] |
|
then |
|
echo "${current_millisecs}" |
|
else |
|
# python not available: use seconds precision |
|
current_millisecs="$(date +"%s")" |
|
echo "${current_millisecs}000" # add 3 zeros to go from secs to millisecs |
|
fi |
|
fi |
|
} |
|
|
|
formatmilliseconds(){ |
|
# Output milliseconds in seconds: |
|
# 443123 => 443.123s |
|
# 3123 => 3.123s |
|
# 30 => 0.030s |
|
printf "%013d" "${1}" | sed -e 's|\([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\)\([0-9][0-9][0-9]\).*|\1.\2|' -e 's|^0*\([0-9]*[0-9]\..*\)|\1s|' |
|
} |
|
|
|
GP_SCRIPT_START_TIME="$(millisecs)" |
|
|
|
# Log functions |
|
|
|
if [ -t 1 ] |
|
then |
|
GP_OUTPUT_IN_TERMINAL="true" |
|
else |
|
GP_OUTPUT_IN_TERMINAL="false" |
|
fi |
|
|
|
if ${GP_OUTPUT_IN_TERMINAL} |
|
then |
|
|
|
LOG_PREFIX_INFO="$(tput sgr0)" # Reset color |
|
LOG_SUFFIX_INFO="$(tput sgr0)" # Reset color |
|
|
|
# LOG_PREFIX_WARN="$(tput setaf 4)" # Blue |
|
LOG_PREFIX_WARN="$(tput setaf 3)" # Yellow |
|
LOG_SUFFIX_WARN="$(tput sgr0)" # Reset color |
|
|
|
LOG_PREFIX_ERROR="$(tput setaf 1)" # Red |
|
LOG_SUFFIX_ERROR="$(tput sgr0)" # Reset color |
|
|
|
else |
|
|
|
LOG_PREFIX_INFO="[INFO] " |
|
LOG_SUFFIX_INFO="" |
|
|
|
LOG_PREFIX_WARN="[WARN] " |
|
LOG_SUFFIX_WARN="" |
|
|
|
LOG_PREFIX_ERROR="[ERROR] " |
|
LOG_SUFFIX_ERROR="" |
|
|
|
fi |
|
|
|
echo_info(){ |
|
echo "${LOG_PREFIX_INFO}${1}${LOG_SUFFIX_INFO}" |
|
} |
|
|
|
echo_info_wait(){ |
|
echo -n "${LOG_PREFIX_INFO}${1}" |
|
} |
|
|
|
echo_log_same_line (){ |
|
echo "${1}${LOG_SUFFIX_INFO}" |
|
} |
|
|
|
|
|
echo_warn(){ |
|
echo "${LOG_PREFIX_WARN}${1}${LOG_SUFFIX_WARN}" |
|
} |
|
|
|
echo_error(){ |
|
# In red and to sdterr |
|
echo "${LOG_PREFIX_ERROR}${1}${LOG_SUFFIX_ERROR}" 1>&2; |
|
} |
|
|
|
echo_error_stdout(){ |
|
# In red and to sdterr |
|
echo "${LOG_PREFIX_ERROR}${1}${LOG_SUFFIX_ERROR}"; |
|
} |
|
|
|
echo_error_rewrite_line(){ |
|
# In red and to sdterr |
|
echo -e "\r${LOG_PREFIX_ERROR}${1}${LOG_SUFFIX_ERROR}" 1>&2; |
|
} |
|
|
|
if [ "$(dirname ${GP_COMMAND_NAME})" == "/dev/fd" ] |
|
then |
|
# We are using the script directly form the CURL'ed version |
|
GP_COMMAND_NAME="${GP_CURL_COMMAND_BASE}" |
|
fi |
|
|
|
helphint() { |
|
echo_info "Main usage: ${GP_COMMAND_NAME:-${GP_COMMAND_BASENAME}} [-bfFhnoOrv] [--output=<format>[,<format>...]] [<path-pattern> [<target-path>]]" |
|
echo_info "Type '${GP_COMMAND_NAME:-${GP_COMMAND_BASENAME}} --help' for more info." |
|
echo_info "For more info visit ${GP_DOC}" |
|
} |
|
|
|
checkflags(){ |
|
GP_CHECKING_FLAGS="true" |
|
for flag in "${@}" |
|
do |
|
if parseflag "${flag}" |
|
then |
|
[ "${flag:0:1}" == "-" ] && GP_FOUND_FLAGS+=("${flag}") |
|
else |
|
GP_INVALID_FLAG_FOUND="true" |
|
echo_error "Invalid option: ${flag%=*}" |
|
fi |
|
[ $GP_PARAM_FOUND ] && [ "${flag:0:1}" == "-" ] && GP_OPTION_FOUND_AFTER_PARAM="true" |
|
done |
|
if [ "${GP_INVALID_FLAG_FOUND}" != "" ] || [ $GP_OPTION_FOUND_AFTER_PARAM ] |
|
then |
|
[ $GP_OPTION_FOUND_AFTER_PARAM ] && echo_error "Options are expected at the begin of the parameter list." |
|
helphint |
|
exit 1 |
|
fi |
|
unset GP_CHECKING_FLAGS |
|
} |
|
|
|
# Usage: echoarraywithmaxwidth <max line length> <array name> [<item separator>] [<line prefix>] |
|
echoarraywithmaxwidth(){ |
|
declare -i ea_line_length |
|
ea_separator="${3:-", "}" |
|
ea_result="" |
|
ea_array=() |
|
for (( i = 0; i < "$(eval echo \"\${#${2}[@]}\")"; i++ )); do |
|
ea_array+=("$(eval echo \"\${${2}[${i}]}\")") |
|
done |
|
for word in "${ea_array[@]}"; do |
|
word="${word}${ea_separator}" |
|
[ $((( ${ea_line_length} + ${#word} ))) -ge ${1} ] && ea_result+="\n${4}" && ea_line_length=0 |
|
ea_result+="${word}" |
|
ea_line_length+=${#word} |
|
done |
|
echo -e "${ea_result%${ea_separator}}" |
|
} |
|
|
|
# "<format-name>=<extension>" |
|
GP_SUPPORTED_OUTPUT_FORMATS+=("pdf=pdf") |
|
GP_SUPPORTED_OUTPUT_FORMATS+=("doc=docx") |
|
GP_SUPPORTED_OUTPUT_FORMATS+=("word=docx") |
|
GP_SUPPORTED_OUTPUT_FORMATS+=("docx=docx") |
|
GP_SUPPORTED_OUTPUT_FORMATS+=("odt=odt") |
|
GP_SUPPORTED_OUTPUT_FORMATS+=("openoffice=odt") |
|
GP_SUPPORTED_OUTPUT_FORMATS+=("epub=epub") |
|
GP_SUPPORTED_OUTPUT_FORMATS+=("html=html") |
|
|
|
outputformatextension(){ |
|
for format in "${GP_SUPPORTED_OUTPUT_FORMATS[@]}" |
|
do |
|
if [ "${format%%=*}" == "$(echo ${1} | tr '[A-Z]' '[a-z]')" ] |
|
then |
|
echo "${format##*=}" |
|
fi |
|
done |
|
} |
|
|
|
checkoutputformats(){ |
|
GP_PDFTEX_REQUIRED=false |
|
for format in ${@} |
|
do |
|
GP_OUTPUT_FORMAT_EXTENTION="$(outputformatextension ${format})" |
|
if [ ! "${GP_OUTPUT_FORMAT_EXTENTION}" ] |
|
then |
|
echo_error "${format} format not supported." |
|
GP_UNSUPPORTED_FORMAT_FOUND="true" |
|
elif [ "${GP_OUTPUT_FORMAT_EXTENTION}" == "pdf" ] |
|
then |
|
GP_PDFTEX_REQUIRED=true |
|
fi |
|
done |
|
[ ${GP_UNSUPPORTED_FORMAT_FOUND} ] && helphint && exit 1 |
|
} |
|
|
|
# "<synonym>=<factor>" |
|
GP_SUPPORTED_LINESPACING_SYNONYMS+=("single=1") |
|
GP_SUPPORTED_LINESPACING_SYNONYMS+=("light=1.2") |
|
GP_SUPPORTED_LINESPACING_SYNONYMS+=("spaced=1.5") |
|
GP_SUPPORTED_LINESPACING_SYNONYMS+=("double=2") |
|
|
|
linespacingfactor(){ |
|
# Supported values are from 0.1 to 9.9, or synonyms defined above. |
|
if [ -n "$(echo "${1}" | grep "^\([1-9]\|[1-9]\.[0-9]\|0\.[1-9]\)$")" ] |
|
then |
|
echo "${1}" |
|
return 0 |
|
fi |
|
for synonym in "${GP_SUPPORTED_LINESPACING_SYNONYMS[@]}" |
|
do |
|
if [ "${synonym%%=*}" == "$(echo ${1} | tr '[A-Z]' '[a-z]')" ] |
|
then |
|
echo "${synonym##*=}" |
|
return 0 |
|
fi |
|
done |
|
return 1 |
|
} |
|
|
|
printlinespacingsynonyms(){ |
|
for synonym in "${GP_SUPPORTED_LINESPACING_SYNONYMS[@]}" |
|
do |
|
echo "${1}- ${synonym%%=*}, for ${synonym##*=}" |
|
done |
|
} |
|
|
|
GP_FILENAME_EXAMPLE_DOCUMENT="example.md" |
|
GP_FILENAME_EXAMPLE_IMAGE="sample-image.jpg" |
|
|
|
downloadexample(){ |
|
read -p " > Do you want to download an example Markdown file and one sample image from ${GP_RAW_URL}? [y/n] " GP_ANSWER |
|
if [ "${GP_ANSWER:0:1}" != "y" ] |
|
then |
|
echo_error "Aborted by user." |
|
return 1 |
|
fi |
|
GP_TEMP_DIR_EXAMPLE="$(mktemp -d example_tmp_XXXXXX)" |
|
if [ "$?" != "0" ] |
|
then |
|
echo_error "Error writing to the current directory. Wrong rights?" |
|
return 1 |
|
fi |
|
curl -sSL "${GP_RAW_URL}/${GP_FILENAME_EXAMPLE_DOCUMENT}" -o "${GP_TEMP_DIR_EXAMPLE}/${GP_FILENAME_EXAMPLE_DOCUMENT}" |
|
if [ "$?" != "0" ] |
|
then |
|
echo_error "Error downloading the example file." |
|
return 1 |
|
fi |
|
curl -sSL "${GP_RAW_URL}/${GP_FILENAME_EXAMPLE_IMAGE}" -o "${GP_TEMP_DIR_EXAMPLE}/${GP_FILENAME_EXAMPLE_IMAGE}" |
|
if [ "$?" != "0" ] |
|
then |
|
echo_error "Error downloading the example image." |
|
return 1 |
|
fi |
|
echo_info "Example file downloaded successfully into directory '${GP_TEMP_DIR_EXAMPLE}'." |
|
echo_info "Cd into the example directory:" |
|
echo_info " cd ${GP_TEMP_DIR_EXAMPLE}" |
|
echo_info "And then type following command to generate a PDF file from it in the './target' folder:" |
|
echo_info " ${GP_COMMAND_NAME:-${GP_COMMAND_BASENAME}}" |
|
echo_info "Or type following command to generate both PDF and HTML versions in the folder './example-output-directory' and opening them:" |
|
echo_info " ${GP_COMMAND_NAME:-${GP_COMMAND_BASENAME}} --open-files --output=pdf,html example example-output-directory" |
|
} |
|
|
|
|
|
parseflag(){ |
|
if [ "${1}" == "--help" ] || [ "${1}" == "-h" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
printhelp |
|
exit 0 |
|
elif [ "${1}" == "--version" ] || [ "${1}" == "-v" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
printversion |
|
exit 0 |
|
elif [ "${1}" == "--install" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
installscript |
|
exit 0 |
|
elif [ "${1}" == "--update" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
updatescript |
|
exit |
|
elif [ "${1}" == "--uninstall" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
uninstallscript |
|
exit 0 |
|
elif [ "${1}" == "--example" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
downloadexample |
|
exit |
|
elif [ "${1}" == "--doctor" ] || [ "${1}" == "--verify-installation" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
verify_installation |
|
exit |
|
elif [ "${1}" == "--install-sublimetext2-build-system" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
install_sublimetext2_build_system |
|
exit |
|
elif [ "${1}" == "--dry-run" ] || [ "${1}" == "-n" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_DRYRUN="true" |
|
shift |
|
elif [ "${1}" == "--flat" ] || [ "${1}" == "-f" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_FLAT="true" |
|
shift |
|
elif [ "${1}" == "--path-name" ] || [ "${1}" == "-F" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_FLAT="true" |
|
GP_PATH_IN_TARGET_FILENAME="true" |
|
shift |
|
elif [ "${1}" == "--recursive" ] || [ "${1}" == "-r" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_PROCESS_RECURSIVELY="true" |
|
shift |
|
elif [ "${1}" == "--bulk" ] || [ "${1}" == "-b" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_BULK="true" |
|
shift |
|
elif [ "${1}" == "--bulk-force" ] || [ "${1}" == "-B" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_BULK="force" |
|
shift |
|
elif [ "${1}" == "--omit-version" ] || [ "${1}" == "-m" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_INCLUDE_GIT_VERSION="false" |
|
shift |
|
elif [ "${1}" == "--date-files" ] || [ "${1}" == "-d" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_DATE_OUTPUT_FILES="true" |
|
shift |
|
elif [ "${1}" == "--open-target-folder" ] || [ "${1}" == "-o" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_OPEN_TARGET_FOLDER="true" |
|
shift |
|
elif [ "${1}" == "--open-files" ] || [ "${1}" == "-O" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_OPEN_FILES="true" |
|
shift |
|
elif [ "${1}" == "--links-as-notes" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_LINKS_AS_NOTES="true" |
|
shift |
|
elif [ "${1%=*}" == "--output" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
if [ "${1:8:1}" == "=" ] && [ "${1:9}" != "" ] |
|
then |
|
GP_OUTPUT_FORMATS+=($(echo ${1#--output=} | tr ',' ' ')) |
|
shift |
|
else |
|
echo_error "--output option needs an argument." |
|
helphint |
|
exit 1 |
|
fi |
|
elif [ "${1%=*}" == "--language" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
if [ "${1:10:1}" == "=" ] && [ "${1:11}" != "" ] |
|
then |
|
GP_OUTPUT_LANGUAGES+=($(echo ${1#--language=} | tr ',' ' ')) |
|
shift |
|
else |
|
echo_error "--language option needs an argument." |
|
helphint |
|
exit 1 |
|
fi |
|
elif [ "${1:0:2}" == "-p" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
if [ "${1:2:1}" == "=" ] && [ "${1:3}" != "" ] |
|
then |
|
GP_OUTPUT_FILE_BASENAME_FORMAT="${1#-p=}" |
|
shift |
|
else |
|
echo_error "-p option needs an argument." |
|
helphint |
|
exit 1 |
|
fi |
|
elif [ "${1%=*}" == "--output-filename-format" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
if [ "${1:24:1}" == "=" ] && [ "${1:25}" != "" ] |
|
then |
|
GP_OUTPUT_FILE_BASENAME_FORMAT="${1#--output-filename-format=}" |
|
shift |
|
else |
|
echo_error "--output-filename-format option needs an argument." |
|
helphint |
|
exit 1 |
|
fi |
|
elif [ "${1:0:2}" == "-l" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
if [ "${1:2:1}" == "=" ] && [ "${1:3}" != "" ] |
|
then |
|
GP_LINESPACING="$(linespacingfactor ${1#-l=})" |
|
if [ "$?" != "0" ] |
|
then |
|
echo_error "${1#-l=} is not a valid linespacing factor." |
|
helphint |
|
exit 1 |
|
fi |
|
shift |
|
else |
|
echo_error "-l option needs an argument." |
|
helphint |
|
exit 1 |
|
fi |
|
elif [ "${1%=*}" == "--linespacing" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
if [ "${1:13:1}" == "=" ] && [ "${1:14}" != "" ] |
|
then |
|
GP_LINESPACING="$(linespacingfactor ${1#--linespacing=})" |
|
if [ "$?" != "0" ] |
|
then |
|
echo_error "${1#--linespacing=} is not a valid linespacing factor." |
|
helphint |
|
exit 1 |
|
fi |
|
shift |
|
else |
|
echo_error "--linespacing option needs an argument." |
|
helphint |
|
exit 1 |
|
fi |
|
elif [ "${1}" == "--pdf" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_OUTPUT_FORMATS+=("pdf") |
|
shift |
|
elif [ "${1}" == "--html" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_OUTPUT_FORMATS+=("html") |
|
shift |
|
elif [ "${1}" == "--doc" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_OUTPUT_FORMATS+=("doc") |
|
shift |
|
elif [ "${1}" == "--odt" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 0 |
|
GP_OUTPUT_FORMATS+=("odt") |
|
shift |
|
elif [ "${1:0:1}" == "-" ] |
|
then |
|
[ $GP_CHECKING_FLAGS ] && return 1 |
|
fi |
|
[ $GP_CHECKING_FLAGS ] && GP_PARAM_FOUND="true" # Param as value passed to the script without "--". Only two are expected, and right to the end of the param list. |
|
} |
|
|
|
checkgitstatus(){ |
|
GP_GIT_REPO_HERE=false |
|
GP_GIT_THINGS_TO_COMMIT=false |
|
GP_GIT_UNTRACKED_FILES=false |
|
|
|
git rev-parse --git-dir 1>/dev/null 2>/dev/null |
|
[ $? -eq 0 ] && GP_GIT_REPO_HERE=true |
|
|
|
git diff-index --quiet HEAD 1>/dev/null 2>/dev/null |
|
[ $? -ne 0 ] && $GP_GIT_REPO_HERE && GP_GIT_THINGS_TO_COMMIT=true |
|
|
|
git ls-files --others --exclude-standard --error-unmatch "./$(git rev-parse --show-cdup 2>/dev/null)" 1>/dev/null 2>/dev/null |
|
[ $? -eq 0 ] && $GP_GIT_REPO_HERE && GP_GIT_UNTRACKED_FILES=true |
|
} |
|
|
|
# Following function is only relevant PDF generated from Markdown files within a git repo. |
|
# It tries to generate a sensible subtitle including versioning info and it |
|
# warns in case of a dirty git repo. |
|
# When generating on a clean tagged version of the repo, the subtitle will be the tag name, e.g. v1.2 |
|
# If not, it will include the number of commits after the last tag, e.g. v1.2-23-g123dv2x i.e. $(git describe --always) |
|
generatedocumentsubtitle(){ |
|
$GP_INCLUDE_GIT_VERSION || return 0 |
|
GP_DOCUMENT_SUBTITLE= |
|
checkgitstatus |
|
if $GP_GIT_REPO_HERE |
|
then |
|
GP_DOCUMENT_SUBTITLE="$(git describe --always)" |
|
if $GP_GIT_THINGS_TO_COMMIT || $GP_GIT_UNTRACKED_FILES |
|
then |
|
GP_DOCUMENT_SUBTITLE=" \textcolor{red}{$(git describe --always)}\footnote{" |
|
GP_DOCUMENT_SUBTITLE+="The git repository of the source file '$(basename ${1//_/\\_})' had " # underscore chars are not allowed in this footnote (?) |
|
$GP_GIT_THINGS_TO_COMMIT && GP_DOCUMENT_SUBTITLE+="uncommitted changes" |
|
$GP_GIT_UNTRACKED_FILES && $GP_GIT_THINGS_TO_COMMIT && GP_DOCUMENT_SUBTITLE+=" and " |
|
$GP_GIT_UNTRACKED_FILES && GP_DOCUMENT_SUBTITLE+="untracked files" |
|
GP_DOCUMENT_SUBTITLE+=" when this PDF was generated. This output may not be reproducible.}" |
|
fi |
|
fi |
|
echo "${GP_DOCUMENT_SUBTITLE}" |
|
} |
|
|
|
# Append a suffix ('+') to the filenames being generated on a dirty git repo |
|
# to avoid overwriting the file generated on a clean, tagged repo state. |
|
filenamesuffix(){ |
|
GP_FILENAME_SUFFIX= |
|
checkgitstatus |
|
if $GP_GIT_REPO_HERE |
|
then |
|
if $GP_GIT_THINGS_TO_COMMIT || $GP_GIT_UNTRACKED_FILES |
|
then |
|
GP_FILENAME_SUFFIX="+" |
|
fi |
|
fi |
|
echo "${GP_FILENAME_SUFFIX}" |
|
} |
|
GP_FILENAME_SUFFIX=$(filenamesuffix) |
|
|
|
applyoutputfilebasenamepattern(){ |
|
finalfilename="${GP_OUTPUT_FILE_BASENAME_FORMAT}${GP_FILENAME_SUFFIX}.${GP_TARGET_FILE_EXTENSION}" |
|
|
|
finalfilename="${finalfilename//"%f"/${GP_CURRENT_FILE_BASENAME}}" # Original files name |
|
finalfilename="${finalfilename//"%v"/$(git describe --always 2>/dev/null || echo "")}" # Git version if any |
|
finalfilename="${finalfilename//"%n"/${GP_OUTPUT_COUNTER}}" # No-padded counter |
|
finalfilename="$(eval "$(echo "echo \"${finalfilename}\"" | \ |
|
sed "s|\(\%0[0-9]*\)n|\$(printf '\1d' ${GP_OUTPUT_COUNTER})|g")")" # Padded counter(s) |
|
# sory for that previous line :S Happy to learn it better! |
|
finalfilename="${finalfilename//"%a"/$(date +"%a")}" # Short date, Sun |
|
finalfilename="${finalfilename//"%A"/$(date +"%A")}" # Long date, Sunday |
|
finalfilename="${finalfilename//"%b"/$(date +"%b")}" # Short Month, Feb |
|
finalfilename="${finalfilename//"%B"/$(date +"%B")}" # Long Month, February |
|
finalfilename="${finalfilename//"%d"/$(date +"%d")}" # Day of the month |
|
finalfilename="${finalfilename//"%H"/$(date +"%H")}" # Hour in 24 hour format (00..23) |
|
finalfilename="${finalfilename//"%I"/$(date +"%I")}" # Hour in 12 hour format (01..12) (this can be used with %p to append Am or PM) |
|
finalfilename="${finalfilename//"%j"/$(date +"%j")}" # Day of the year |
|
finalfilename="${finalfilename//"%m"/$(date +"%m")}" # Month in number format (01..12) |
|
finalfilename="${finalfilename//"%M"/$(date +"%M")}" # Minute (00..59) |
|
finalfilename="${finalfilename//"%p"/$(date +"%p")}" # Locale either AM or PM |
|
finalfilename="${finalfilename//"%S"/$(date +"%S")}" # Second |
|
finalfilename="${finalfilename//"%u"/$(date +"%u")}" # Day of the week |
|
finalfilename="${finalfilename//"%V"/$(date +"%V")}" # Week number of year with Monday as first day of week (01..53) |
|
finalfilename="${finalfilename//"%Y"/$(date +"%Y")}" # Year |
|
finalfilename="${finalfilename//"%z"/$(date +"%z")}" # Numeric timezone (e.g., -0400) or %Z with timezone abbreviation. |
|
|
|
echo "${finalfilename}" |
|
} |
|
|
|
declare -i GP_OUTPUT_COUNTER=0 |
|
|
|
declinepathpartsforfile(){ |
|
(( GP_OUTPUT_COUNTER++ )) |
|
GP_CURRENT_DIR="$(dirname "${1}")" |
|
GP_CURRENT_FILENAME="$(basename "${1}")" |
|
GP_CURRENT_FILE_BASENAME="${GP_CURRENT_FILENAME%.*}" |
|
GP_TARGET_CURRENT_DIR="${GP_TARGET_DIR}" |
|
! [ $GP_FLAT ] && GP_TARGET_CURRENT_DIR="${GP_TARGET_CURRENT_DIR}/${GP_CURRENT_DIR}" |
|
GP_TARGET_CURRENT_FILENAME="$(applyoutputfilebasenamepattern)" |
|
[ $GP_PATH_IN_TARGET_FILENAME ] && GP_TARGET_CURRENT_FILENAME="$(echo "${GP_CURRENT_DIR#.}" | tr '/' '-')-${GP_TARGET_CURRENT_FILENAME}" |
|
GP_TARGET_CURRENT_FILEPATH="${GP_TARGET_CURRENT_DIR}/${GP_TARGET_CURRENT_FILENAME#-}" |
|
# Remove unnecessary (but not wrong) "/./" from path for enhanced prompt in stdout |
|
GP_TARGET_CURRENT_FILEPATH="${GP_TARGET_CURRENT_FILEPATH/\/.\///}" |
|
GP_TARGET_CURRENT_FILEPATH="./${GP_TARGET_CURRENT_FILEPATH#./}" |
|
GP_TARGET_FILEPATHS+=("${GP_TARGET_CURRENT_FILEPATH}") |
|
} |
|
|
|
dodryrun(){ |
|
GP_OUTPUT_FORMATS_PRETTY_PRINTED=$(echo "${GP_OUTPUT_FILE_EXTENSIONS[@]}" | tr '[:lower:]' '[:upper:]' | sed -e "s/ /, /g" -e "s/\(.*\), /\1 and /") |
|
echo_info "Would generate ${GP_OUTPUT_FORMATS_PRETTY_PRINTED} files from ${GP_MD_FILES_COUNT} Markdown file(s):" |
|
for file in "${GP_MD_FILES[@]}" |
|
do |
|
for GP_TARGET_FILE_EXTENSION in "${GP_OUTPUT_FILE_EXTENSIONS[@]}" |
|
do |
|
declinepathpartsforfile "${file}" |
|
echo_info " ${file} --> ${GP_TARGET_CURRENT_FILEPATH}" |
|
done |
|
done |
|
} |
|
|
|
check_pdftex_available(){ |
|
if [ "$(which pdftex)" == "" ] |
|
then |
|
echo_error "pdftex not found!" |
|
echo_error "pdftex is required to genereate PDF documents from the Markdown files." |
|
echo_error "For installing info visit: http://johnmacfarlane.net/pandoc/installing.html" |
|
echo_error "In the link above, pandoc recommends installing BasicTeX package at http://www.tug.org/mactex/morepackages.html" |
|
GP_PDFTEX_AVAILABLE=false |
|
fi |
|
} |
|
|
|
check_pandoc_available(){ |
|
if [ "$(which pandoc)" == "" ] |
|
then |
|
echo_error "pandoc not found!" |
|
echo_error "For installing info visit: http://johnmacfarlane.net/pandoc/installing.html" |
|
GP_PANDOC_AVAILABLE=false |
|
fi |
|
} |
|
|
|
are_required_tools_available(){ |
|
check_pandoc_available |
|
$GP_PDFTEX_REQUIRED && check_pdftex_available |
|
( ! $GP_PANDOC_AVAILABLE || ! $GP_PDFTEX_AVAILABLE ) && return 1 || return 0 |
|
} |
|
|
|
printversion(){ |
|
print_version_echo_fn="${1:-echo_info}" |
|
"${print_version_echo_fn}" "${GP_COMMAND_NAME} ${GP_VERSION}" |
|
check_pandoc_available |
|
$GP_PANDOC_AVAILABLE && "${print_version_echo_fn}" "$(pandoc --version | head -1)" |
|
check_pdftex_available 2>/dev/null |
|
$GP_PDFTEX_AVAILABLE && "${print_version_echo_fn}" "$(pdftex --version | head -1)" |
|
} |
|
|
|
verify_installation(){ |
|
[ -z "$(which ${GP_COMMAND_BASENAME})" ] && echo_warn "${GP_COMMAND_BASENAME} not reachable from the PATH, but used from $0" && GP_DOCTOR_ALL_OK=false |
|
are_required_tools_available |
|
[ $? == 0 ] || GP_DOCTOR_ALL_OK=false |
|
$GP_DOCTOR_ALL_OK && echo_info "Your system is ready to process Markdown files." && return 0 || return 1 |
|
} |
|
|
|
GP_BABEL_LANGUAGES=("afrikaans" "bahasa" "breton" "catalan" "croatian" \ |
|
"czech" "danish" "dutch" "english" "USenglish" "american" "UKenglish" \ |
|
"british esperanto" "estonian" "finnish" "french" "francais" "galician" \ |
|
"austrian" "german" "germanb greek" "hebrew" "magyar" "hungarian" \ |
|
"irish" "italian" "lowersorbian" "norsk" "nynorsk" "polish" "portuges" \ |
|
"portuguese" "brazilian" "brazil romanian" "russian" "scottish" \ |
|
"spanish" "slovak" "slovene" "swedish" "turkish" "uppersorbian" "welsh") |
|
|
|
checkbabellanguage(){ |
|
for babel_language in "${GP_BABEL_LANGUAGES[@]}" |
|
do |
|
if [ "$(echo ${babel_language} | tr '[A-Z]' '[a-z]')" == "$(echo ${1} | tr '[A-Z]' '[a-z]')" ] |
|
then |
|
echo "${babel_language}" |
|
break |
|
fi |
|
done |
|
} |
|
|
|
checkoutputlanguages(){ |
|
for language in ${@} |
|
do |
|
if [ ! "$(checkbabellanguage ${language})" ] |
|
then |
|
echo_error "'${language}' language not supported." |
|
echo_error "PDF generation uses 'babel' package, therefore the supported languages are: " |
|
echo_error " $(echoarraywithmaxwidth 100 GP_BABEL_LANGUAGES ", " "[INFO] ")" |
|
GP_UNSUPPORTED_LANGUAGE_FOUND="true" |
|
fi |
|
done |
|
[ ${GP_UNSUPPORTED_LANGUAGE_FOUND} ] && helphint && exit 1 |
|
} |
|
|
|
|
|
GP_ST2_SETTINGS_FOLDER=~/Library/Application\ Support/Sublime\ Text\ 2/Packages/User |
|
GP_TEMP_FOLDER_FOR_ST2_BUILD_SYSTEM_FILE="/tmp" |
|
GP_ST2_BUILD_SYSTEM_BASENAME=Generate\ PDF.sublime-build |
|
|
|
install_sublimetext2_build_system(){ |
|
verify_installation 1>/dev/null |
|
! $GP_DOCTOR_ALL_OK && echo_error "Please fix your installation before installing the 'Sublime Text 2' build system." && exit 1 |
|
|
|
if [ -d "${GP_ST2_SETTINGS_FOLDER}" ] |
|
then |
|
GP_INSTALL_ST2_BUILD_FILE_TO_TEMP_DIR=false |
|
else |
|
echo_error "Unable to find 'Sublime Text 2' user settings folder in '${GP_ST2_SETTINGS_FOLDER}'." |
|
if [ -d "${GP_TEMP_FOLDER_FOR_ST2_BUILD_SYSTEM_FILE}" ] |
|
then |
|
GP_INSTALL_ST2_BUILD_FILE_TO_TEMP_DIR=true |
|
else |
|
echo_error "Unable to generate build system file for 'Sublime Text 2' into ${GP_TEMP_FOLDER_FOR_ST2_BUILD_SYSTEM_FILE}." |
|
echo_info "For more info visit ${GP_DOC}" |
|
return 1 |
|
fi |
|
fi |
|
|
|
if $GP_INSTALL_ST2_BUILD_FILE_TO_TEMP_DIR |
|
then |
|
GP_ST2_BUILD_SYSTEM_FILENAME="${GP_TEMP_FOLDER_FOR_ST2_BUILD_SYSTEM_FILE}/${GP_ST2_BUILD_SYSTEM_BASENAME}" |
|
else |
|
GP_ST2_BUILD_SYSTEM_FILENAME="${GP_ST2_SETTINGS_FOLDER}/${GP_ST2_BUILD_SYSTEM_BASENAME}" |
|
fi |
|
|
|
cat << EOF >> "${GP_ST2_BUILD_SYSTEM_FILENAME}" |
|
{ |
|
"selector": "text.html.markdown", |
|
"cmd": ["process-md", "--recursive", "--open-files", "--links-as-notes", "/\$file_name"], |
|
"path": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/texbin", |
|
"working_dir": "\${project_path}", |
|
"variants": [ |
|
{ |
|
"cmd": ["process-md", "--recursive", "--open-files", "/\$file_name"], |
|
"name": "Generate PDF (disable links as footnotes)" |
|
}, |
|
{ |
|
"cmd": ["process-md", "--recursive", "--links-as-notes", "--open-files"], |
|
"name": "Generate PDF from all Markdown files in project" |
|
}, |
|
{ |
|
"cmd": ["process-md", "--recursive", "--open-files"], |
|
"name": "Generate PDF from all Markdown files in project (disable links as footnotes)" |
|
} |
|
] |
|
} |
|
EOF |
|
|
|
if [ $? == 0 ] && [ -f "${GP_ST2_BUILD_SYSTEM_FILENAME}" ] |
|
then |
|
if $GP_INSTALL_ST2_BUILD_FILE_TO_TEMP_DIR |
|
then |
|
echo_info "Please manually copy the file '${GP_ST2_BUILD_SYSTEM_FILENAME}' to the appropriate folder." |
|
echo_info "Afterwards, you will find it in the menu 'Tools' > 'Build System' > '$(basename "${GP_ST2_BUILD_SYSTEM_FILENAME}" ".sublime-build")'" |
|
else |
|
echo_info "Build system definition for 'Sublime Text 2' successfully installed to:" |
|
echo_info " ${GP_ST2_BUILD_SYSTEM_FILENAME}" |
|
echo_info "You will find it in the menu 'Tools' > 'Build System' > '$(basename "${GP_ST2_BUILD_SYSTEM_FILENAME}" ".sublime-build")'" |
|
fi |
|
else |
|
echo_error "Installation of build system definition for 'Sublime Text 2' failed!" |
|
echo_info "For more info visit ${GP_DOC}" |
|
fi |
|
} |
|
|
|
printhelp(){ |
|
less << EOF |
|
Version |
|
======= |
|
|
|
$(printversion "echo") |
|
|
|
|
|
Usage |
|
===== |
|
|
|
$ ${GP_COMMAND_BASENAME} [option] [<path-pattern> [<target-path>]] |
|
|
|
|
|
Options |
|
======= |
|
|
|
-b, --bulk |
|
Allow to process more than 10 files. This is a security to avoid |
|
triggering this command by error on a directory with lots of subdirectories |
|
like '/' or '~'. |
|
|
|
--doc |
|
Generate Word files for each Markdown file. Equivalent to '--output=doc'. |
|
|
|
--doctor, --verify-installation |
|
Performs a check to verify that the 'process-md' is correctly installed, |
|
and that the required tools are also available. |
|
|
|
-d, --date-files |
|
Prefix generated files with the current date (i.e. adds "%Y%m%d_" at the beginning |
|
of the output filename pattern). |
|
|
|
--example |
|
Downloads an example Markdown document from ${GP_DOC} locally so that you can |
|
apply 'process-md' on it to better understand how Markdown works. |
|
|
|
-f, --flat |
|
Gather all generated files into the target directory, without |
|
replicating the original subfolder structure. |
|
|
|
-F, --path-name |
|
Include the original path of the Markdown files in the generated |
|
file, to avoid name clashes when gathering all files in the target |
|
directory. Implies '--flat'. |
|
|
|
-h, --help |
|
Print this help and exit. Other parameters and options are ignored. |
|
|
|
--html |
|
Generate HTML files for each Markdown file. Equivalent to '--output=html'. |
|
|
|
-l=<factor>, --linespacing=<factor> |
|
Specify the linespacing factor of the PDF output (using the 'setspace' package). |
|
The factor must be any number between 0.1 and 9.9. Following synomyns are also |
|
accepted: |
|
$(printlinespacingsynonyms " ") |
|
Defaults to '${GP_SUPPORTED_LINESPACING_SYNONYMS[0]%%=*}'. |
|
|
|
--language=<language>[,<language>...] |
|
Specify the languages of the resulting file. It is mainly used for PDF |
|
generation, with the 'babel' package. Therefore, valid values are: |
|
$(echoarraywithmaxwidth 70 GP_BABEL_LANGUAGES ", " " ") |
|
By default 'english' is used if nothing else is specified. |
|
|
|
--links-as-notes |
|
Make footnotes with URL of external links when possible (e.g. PDF, HTML). |
|
Note: This will fail if there are links in section titles. |
|
|
|
-m, --omit-version |
|
If the original Markdown files are in a git repository, by default the git |
|
version (as in "git describe --always") is included in the filename and as a subtitle |
|
in generated PDF files. This flag overrides this behaviour so that the git version is |
|
not shown. |
|
|
|
-n, --dry-run |
|
Only list what files would be generated with the given parameters |
|
without actually generating any files. |
|
|
|
--output=<format>[,<format>...] |
|
Specify which files should be generated for each Markdown file. Valid |
|
values are '--ouput=pdf,word,openoffice,html' and some synonyms: 'doc' |
|
and 'docx' are synonims of 'word'; 'odt' is synonym of 'openoffice'. |
|
By default 'pdf' is generated if nothing else is specified. |
|
|
|
-o, --open-target-folder |
|
[Mac OS X only] |
|
After successful generation, open the target folder in Finder. |
|
|
|
-O, --open-files |
|
[Mac OS X only] |
|
After successful generation, open the generated files in the default application. |
|
If more than 10 files would open, this will fall back to '--open-target-folder' to |
|
avoid issues with the operating system. |
|
|
|
--odt |
|
Generate OpenOffice files for each Markdown file. Equivalent to '--output=odt'. |
|
|
|
-p=<format>, --output-filename-pattern=<format> |
|
Pattern for the basename part of the generated files. The extension will be appended |
|
for each type of output file. No spaces might be used in the pattern. |
|
|
|
By default the generated files have the same basename |
|
than their original Markdown files with the git version of the file as suffix, if |
|
their are in a git repository (i.e. by default -p=%f_%v or -p=%f). Following parameters |
|
are recognized: |
|
|
|
%f - Original file basename |
|
%v - Git version (as in 'git describe --always') if any, or blank |
|
%n - Counter (Use '%0xn' for a counter padded with 'x' number of zeros) |
|
|
|
%a - Short date (Sun) |
|
%A - Long date (Sunday) |
|
%b - Short Month (Feb) |
|
%B - Long Month (February) |
|
%d - Day of the month |
|
%H - Hour in 24 hour format (00..23) |
|
%I - Hour in 12 hour format (01..12) (see '%p') |
|
%j - Day of the year |
|
%m - Month in number format (01..12) |
|
%M - Minute (00..59) |
|
%p - Locale either AM or PM |
|
%S - Second (00..59) |
|
%u - Day of the week |
|
%V - Week number of year with Monday as first day of week (01..53) |
|
%Y - Year (2013) |
|
%z - Numeric timezone (+0100) |
|
%Z - Timezone abbreviation. (CET) |
|
|
|
|
|
--pdf |
|
Generate PDF files for each Markdown file. Equivalent to '--output=pdf'. |
|
|
|
-r, --recursive |
|
By default only Markdown files in the current directory are processed. This |
|
flag forces the processing of all Markdown files in the current directory |
|
and its subdirectories (up to a max depth of 12 levels). |
|
|
|
--uninstall |
|
Delete the script from '/usr/local/bin' and exit. Other parameters |
|
and options are ignored. |
|
|
|
--update |
|
Update the script installed in '/usr/local/bin' and exit. Other parameters |
|
and options are ignored. |
|
|
|
-v, --version |
|
Print the version of the script and related tools and exit. Other parameters |
|
and options are ignored. |
|
|
|
|
|
Extras |
|
====== |
|
|
|
--install-sublimetext2-build-system |
|
[Mac OS X only] |
|
Install a build system definition for the text editor 'Sublime Text 2'[^1] |
|
to call 'process-md'. This allows to easily produce PDF documents from the |
|
current Markdown file open in the editor using 'pdftex' via 'pandoc' with |
|
the keystroke 'cmd-B'. And well, that is pretty handy. |
|
|
|
[^1]: http://www.sublimetext.com |
|
|
|
|
|
Examples |
|
======== |
|
|
|
$ ${GP_COMMAND_BASENAME} |
|
All .md and .markdown files in the current directory |
|
are converted in PDF in the ./target directory. |
|
|
|
$ ${GP_COMMAND_BASENAME} -r |
|
All .md and .markdown files in the current directory and its |
|
subdirectories are converted in PDF in the ./target directory, |
|
maintaining its original sub-folder structure. |
|
|
|
$ ${GP_COMMAND_BASENAME} --output=word |
|
All .md and .markdown files in the current directory |
|
are converted in docx in the ./target directory. |
|
|
|
$ ${GP_COMMAND_BASENAME} api |
|
All .md and .markdown files in the current directory |
|
containing "api" (case sensitive) in the file name are |
|
converted in PDF in the ./target directory. |
|
|
|
$ ${GP_COMMAND_BASENAME} -r ./doc/*a |
|
All .md and .markdown files in the "doc/" subdirectory and its |
|
subdirectories containing "a" (case sensitive) in the file name or |
|
the path are converted in PDF in the ./target directory, maintaining |
|
its original sub-folder structure. |
|
|
|
$ ${GP_COMMAND_BASENAME} api pdfs |
|
All .md and .markdown files in the current directory |
|
containing "api" (case sensitive) in the file name are |
|
converted in PDF in the ./pdfs directory. |
|
|
|
$ ${GP_COMMAND_BASENAME} -r . . |
|
All .md and .markdown files in the current directory |
|
and its subfolders are converted in PDF in the current directory, |
|
maintaining its original sub-folder structure, i.e. next to their .md |
|
counterparts. |
|
|
|
For more info visit ${GP_DOC} |
|
|
|
EOF |
|
} |
|
|
|
updatescript(){ |
|
if [ ! -e "${GP_INSTALLED_SCRIPT}" ] |
|
then |
|
echo_error "${GP_INSTALLED_SCRIPT} not found" |
|
echo_error "Run following command to install: ${GP_INSTALL_BASH_CURL}" |
|
exit 1 |
|
fi |
|
|
|
GP_INSTALLING_VERSION="$(eval "${GP_INSTALL_CURL}" | grep "GP_INSTALL_VERSION=" | head -1 | sed "s/GP_INSTALL_VERSION=\"\(.*\)\"/\1/")" |
|
if [ "${GP_VERSION}" == "${GP_INSTALLING_VERSION}" ] |
|
then |
|
echo_info "Already up-to-date." |
|
exit 0 |
|
fi |
|
|
|
echo_info "'${GP_COMMAND_NAME} ${GP_VERSION}' is currently installed." |
|
echo_info "There is a newer released version: ${GP_INSTALLING_VERSION}." |
|
read -p " > Do you want to install '${GP_COMMAND_NAME} ${GP_INSTALLING_VERSION}'? [y/n] " GP_ANSWER |
|
if [ "${GP_ANSWER:0:1}" != "y" ] |
|
then |
|
echo_info "Update aborted by user." |
|
exit 0 |
|
fi |
|
eval ${GP_INSTALL_BASH_CURL} |
|
} |
|
|
|
installscript(){ |
|
if [ "${0}" == "${GP_INSTALLED_SCRIPT}" ] |
|
then |
|
echo_info "Already using ${0}." |
|
exit 0 |
|
fi |
|
$(are_required_tools_available) || exit 1 |
|
if [ -e "${GP_INSTALLED_SCRIPT}" ] |
|
then |
|
echo_info "Currently installed: ${GP_INSTALL_PATH}" |
|
"${GP_INSTALLED_SCRIPT}" --version | head -1 |
|
echo_info "You are installing version ${GP_VERSION}." |
|
read -p "Do you want to continue? [y/n] " GP_ANSWER |
|
if [ "${GP_ANSWER:0:1}" == "n" ] |
|
then |
|
exit 0 |
|
fi |
|
fi |
|
if [ -e "${GP_INSTALLED_SCRIPT}" ] |
|
then |
|
rm "${GP_INSTALLED_SCRIPT}" |
|
fi |
|
if [ "$(dirname ${0})" == "/dev/fd" ] |
|
then |
|
# We are installing from the piped version, and we have to redownload a new version of the file |
|
# since the current one (often in /dev/fd/63) has already been consumed up to here |
|
eval ${GP_INSTALL_BASH_CURL} |
|
else |
|
cp -v "${0}" "${GP_INSTALLED_SCRIPT}" |
|
fi |
|
if [ $? != 0 ] |
|
then |
|
echo_error "Error installing script to ${GP_INSTALLED_SCRIPT}" |
|
exit 1 |
|
fi |
|
chmod +x "${GP_INSTALLED_SCRIPT}" |
|
if [ $? == 0 ] |
|
then |
|
echo_info "Successfully installed to ${GP_INSTALLED_SCRIPT}" |
|
else |
|
echo_error "Error installing script to ${GP_INSTALLED_SCRIPT}" |
|
exit 1 |
|
fi |
|
} |
|
|
|
uninstallscript(){ |
|
if [ ! -e "${GP_INSTALLED_SCRIPT}" ] |
|
then |
|
echo_warn "${GP_INSTALLED_SCRIPT} not found" |
|
exit 0 |
|
fi |
|
echo_info "This action will remove ${GP_INSTALLED_SCRIPT}" |
|
read -p "Do you want to continue? [y/n] " GP_ANSWER |
|
if [ "${GP_ANSWER:0:1}" == "n" ] |
|
then |
|
exit 0 |
|
fi |
|
rm -v ${GP_INSTALLED_SCRIPT} |
|
if [ $? == 0 ] |
|
then |
|
echo_info "${GP_INSTALLED_SCRIPT} removed successfully" |
|
else |
|
echo_error "Removing ${GP_INSTALLED_SCRIPT} failed" |
|
exit 1 |
|
fi |
|
} |
|
|
|
# Expand one-letter params |
|
|
|
GP_PARAMS="${@}" |
|
while [ "true" ] |
|
do |
|
GP_PARAMS_PARSED=$(echo "params: ${GP_PARAMS}" | sed "s/\( -[a-zA-Z]\)\([a-zA-Z]\)/\1 -\2/g") |
|
if [ "${GP_PARAMS}" == "${GP_PARAMS_PARSED#params: }" ] |
|
then |
|
break |
|
else |
|
GP_PARAMS="${GP_PARAMS_PARSED#params: }" |
|
fi |
|
done |
|
set -- ${GP_PARAMS} |
|
|
|
checkflags ${@} |
|
|
|
for flag in "${@}" |
|
do |
|
parseflag "${flag}" |
|
done |
|
|
|
for flag in "${GP_FOUND_FLAGS[@]}" |
|
do |
|
shift |
|
done |
|
|
|
GP_OUTPUT_LANGUAGES="${GP_OUTPUT_LANGUAGES:-english}" |
|
checkoutputlanguages "${GP_OUTPUT_LANGUAGES[@]}" |
|
|
|
GP_OUTPUT_FORMATS="${GP_OUTPUT_FORMATS:-pdf}" |
|
checkoutputformats "${GP_OUTPUT_FORMATS[@]}" |
|
|
|
$(are_required_tools_available) || exit 1 |
|
|
|
checkgitstatus |
|
|
|
if $GP_GIT_REPO_HERE && $GP_INCLUDE_GIT_VERSION |
|
then |
|
GP_OUTPUT_FILE_BASENAME_FORMAT="${GP_OUTPUT_FILE_BASENAME_FORMAT:-"%f_%v"}" |
|
else |
|
GP_OUTPUT_FILE_BASENAME_FORMAT="${GP_OUTPUT_FILE_BASENAME_FORMAT:-"%f"}" |
|
fi |
|
|
|
if $GP_DATE_OUTPUT_FILES |
|
then |
|
GP_OUTPUT_FILE_BASENAME_FORMAT="%Y%m%d_${GP_OUTPUT_FILE_BASENAME_FORMAT}" |
|
fi |
|
|
|
|
|
# Gather file extensions for output formats and remove duplicates |
|
for format in "${GP_OUTPUT_FORMATS[@]}" |
|
do |
|
GP_OUTPUT_FILE_EXTENSIONS+=($(outputformatextension ${format})) |
|
done |
|
GP_OUTPUT_FILE_EXTENSIONS=($(printf "%s\n" "${GP_OUTPUT_FILE_EXTENSIONS[@]}" | sort -u)) |
|
|
|
# Gather Markdown files to process |
|
while read -r line |
|
do |
|
GP_MD_FILES+=("${line}") |
|
done <<< "$(find . -maxdepth 1$([ $GP_PROCESS_RECURSIVELY ] && echo "2") -type f -path "*${1}*" \( -iname "*.md" -or -iname "*.markdown" \) -print)" |
|
|
|
GP_MD_FILES_COUNT=${#GP_MD_FILES[@]} |
|
GP_MD_FILES_MAX=10 |
|
|
|
GP_BASE_DIR="$(pwd)" |
|
GP_TARGET_DIR="${2:-target}" |
|
|
|
if [ ${#GP_MD_FILES[0]} -eq 0 ] |
|
then |
|
echo_warn "No Markdown file found in the current directory$([ $GP_PROCESS_RECURSIVELY ] && echo " and its subfolders")." |
|
helphint |
|
exit 0 |
|
fi |
|
|
|
[ "${GP_DRYRUN}" == "true" ] && dodryrun && exit |
|
|
|
if [ ${GP_MD_FILES_COUNT} -gt ${GP_MD_FILES_MAX} ] |
|
then |
|
GP_ARGUMENTS="${1} ${2}" |
|
GP_ARGUMENTS="$(echo " ${1} ${2}" | sed 's/ *$//g')" |
|
echo_warn "${GP_MD_FILES_COUNT} Markdown files found! That sounds like a lot..." |
|
echo_info "Use '${GP_COMMAND_NAME} --dry-run${GP_ARGUMENTS}' to see a list of what would be generated." |
|
if [ "${GP_BULK}" == "true" ] |
|
then |
|
echo_info "Use '${GP_COMMAND_NAME} --bulk-force${GP_ARGUMENTS}' to avoid this question and directly proceed with the file generation." |
|
read -p " > Do you want to continue? [y/n] " GP_ANSWER |
|
if [ "${GP_ANSWER:0:1}" != "y" ] |
|
then |
|
exit 0 |
|
fi |
|
elif [ "${GP_BULK}" == "" ] |
|
then |
|
echo_info "Use '${GP_COMMAND_NAME} --bulk${GP_ARGUMENTS}' to proceed with the file generation." |
|
exit 0 |
|
fi |
|
fi |
|
|
|
[ "${GP_LINKS_AS_NOTES}" == "true" ] && GP_LINKS_AS_NOTES_COMMAND="--variable=links-as-notes" |
|
|
|
for file in "${GP_MD_FILES[@]}" |
|
do |
|
for GP_TARGET_FILE_EXTENSION in "${GP_OUTPUT_FILE_EXTENSIONS[@]}" |
|
do |
|
echo_info_wait "Processing file: $file " |
|
declinepathpartsforfile "${file}" |
|
mkdir -p "${GP_TARGET_CURRENT_DIR}" |
|
|
|
# Since pandoc looks for images relatives to where it is called (https://github.com/jgm/pandoc/issues/917) |
|
# we have to cd into the directory of the given file before pandoc'ing it, |
|
# and we have to pass the full path in the -o parameter. |
|
cd "${GP_CURRENT_DIR}" |
|
|
|
# Comments to options used below: |
|
# --variable=documentclass:scrartcl \ => this class allow \subtitle{} used below |
|
# --variable=linkcolor:black \ => the default is magenta |
|
# --variable=links-as-notes \ => only for external links, it doesn't work if links in section titles |
|
# --variable=papersize:"a4paper, DIV=9" \ => Bigger DIV values make thiner borders. |
|
# DIVcalc tends to make too low values of DIV (thing text widths), |
|
# and DIV10 gives problems with TOC (???) |
|
|
|
# Other valid options: |
|
# --variable=date:"$(date +"%d %b %Y" || echo "")" \ |
|
# --variable=lang:"french" \ |
|
|
|
pandoc_start="$(millisecs)" |
|
|
|
GP_PANDOC_OUTPUT=$(pandoc \ |
|
--table-of-contents \ |
|
--number-sections \ |
|
--smart \ |
|
--variable=documentclass:scrartcl \ |
|
--variable=papersize:"a4paper, DIV=9" \ |
|
--variable=lang:"$(echoarraywithmaxwidth 1000 GP_OUTPUT_LANGUAGES ",")" \ |
|
--variable=linkcolor:black \ |
|
--variable=header-includes:"\usepackage{setspace} \setstretch{${GP_LINESPACING:-1}}" \ |
|
--variable=header-includes:"\subtitle{$(generatedocumentsubtitle "${GP_CURRENT_FILENAME}")}" \ |
|
--variable=header-includes:"\ifdefined \includegraphics \renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=0.9\textwidth,height=0.9\textheight,keepaspectratio]{#1}} \fi" \ |
|
--variable=date:"\today" \ |
|
${GP_LINKS_AS_NOTES_COMMAND} \ |
|
-o "${GP_BASE_DIR}/${GP_TARGET_CURRENT_FILEPATH#./}" \ |
|
"${GP_CURRENT_FILENAME}" \ |
|
2>&1) # capture pandoc stderr output |
|
|
|
if [ $? == 0 ] |
|
then |
|
pandoc_duration="$(( $(millisecs) - ${pandoc_start} ))" |
|
echo_log_same_line "---> ${GP_TARGET_CURRENT_FILEPATH} - OK [$(formatmilliseconds ${pandoc_duration})]" |
|
GP_GENERATED_FILES+=("${GP_BASE_DIR}/${GP_TARGET_CURRENT_FILEPATH#./}") |
|
else |
|
pandoc_duration="$(( $(millisecs) - ${pandoc_start} ))" |
|
echo_error_rewrite_line "Processing file: $file -X-> ${GP_TARGET_CURRENT_FILEPATH} - FAILED [$(formatmilliseconds ${pandoc_duration})]" |
|
GP_ERRORS+=("$(echo "${file} - Failed generation of PDF"; \ |
|
echo_error_stdout "Expected target file: ${GP_TARGET_CURRENT_FILEPATH}"; \ |
|
echo_error_stdout "${GP_PANDOC_OUTPUT}"; \ |
|
echo_error_stdout;)") |
|
fi |
|
global_pandoc_duration=$(( ${global_pandoc_duration} + ${pandoc_duration} )) |
|
cd "${GP_BASE_DIR}" |
|
done |
|
done |
|
|
|
GP_SCRIPT_FINISH_TIME="$(( $(millisecs) - ${GP_SCRIPT_START_TIME} ))" |
|
|
|
if [ ${#GP_GENERATED_FILES[@]} -eq 1 ] && [ ${#GP_GENERATED_FILES[@]} -eq ${#GP_TARGET_FILEPATHS[@]} ] |
|
then |
|
echo_info "One file successfully generated in $(formatmilliseconds ${GP_SCRIPT_FINISH_TIME})." |
|
elif [ ${#GP_GENERATED_FILES[@]} -gt 1 ] && [ ${#GP_GENERATED_FILES[@]} -eq ${#GP_TARGET_FILEPATHS[@]} ] |
|
then |
|
echo_info "${#GP_GENERATED_FILES[@]} files successfully generated in $(formatmilliseconds ${GP_SCRIPT_FINISH_TIME})." |
|
elif [ ${#GP_GENERATED_FILES[@]} -gt 0 ] |
|
then |
|
echo_info "${#GP_GENERATED_FILES[@]} out of ${#GP_TARGET_FILEPATHS[@]} file(s) successfully generated in $(formatmilliseconds ${GP_SCRIPT_FINISH_TIME})." |
|
fi |
|
|
|
if [ ${#GP_GENERATED_FILES[@]} -gt 0 ] && [ ${#GP_GENERATED_FILES[@]} -le 10 ] |
|
then |
|
[ "${GP_OPEN_TARGET_FOLDER}" == "true" ] && open "${GP_TARGET_DIR}" |
|
[ "${GP_OPEN_FILES}" == "true" ] && open "${GP_GENERATED_FILES[@]}" |
|
elif [ ${#GP_GENERATED_FILES[@]} -gt 10 ] |
|
then |
|
if [ "${GP_OPEN_TARGET_FOLDER}" == "true" ] || [ "${GP_OPEN_FILES}" == "true" ] |
|
then |
|
open "${GP_TARGET_DIR}" |
|
fi |
|
fi |
|
|
|
if [ ${#GP_ERRORS[@]} -eq 0 ] |
|
then |
|
exit 0 |
|
fi |
|
|
|
echo_error |
|
echo_error "====================================================================" |
|
echo_error "pandoc failed to generate PDF for ${#GP_ERRORS[@]} file(s)" |
|
echo_error "====================================================================" |
|
|
|
if [ "${GP_LINKS_AS_NOTES}" == "true" ] |
|
then |
|
echo_error |
|
echo_error "--------------------------------------------------------------------" |
|
echo_error "Option '--links-as-notes' will fail if there are links in section " |
|
echo_error "titles. Try to generate the files again without this option. " |
|
echo_error "--------------------------------------------------------------------" |
|
fi |
|
|
|
|
|
for i in "${GP_ERRORS[@]}" |
|
do |
|
echo_error |
|
echo_error "--------------------------------------------------------------------" |
|
echo_error "${i}" |
|
echo_error "--------------------------------------------------------------------" |
|
echo_error |
|
done |
|
|
|
exit 1 |
Thats's sounds awesome... Do you know how to make a similar thing on Windows?