Skip to content

Instantly share code, notes, and snippets.

@zudsniper
Last active July 12, 2023 18:44
Show Gist options
  • Save zudsniper/4712559905b68e30697be48ba60e6912 to your computer and use it in GitHub Desktop.
Save zudsniper/4712559905b68e30697be48ba60e6912 to your computer and use it in GitHub Desktop.
🚫 [BROKEN] Generate a PDF from a Markdown file with a metadata.yaml file provided, or via the values provided in the document header.
#!/bin/bash
# mdpdf_pop.sh v2.0.1
# ------------
#
# @zudsniper
# ANSI color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
GRAY='\033[0;37m'
NC='\033[0m' # No Color
# Function to print usage
print_usage() {
echo -e "${YELLOW}Usage:${NC} $0 -i <input.md> -o <output.pdf> [-m <metadata.yaml>]"
echo -e "${YELLOW}Options:${NC}"
echo -e " -i, --input Input markdown file"
echo -e " -o, --output Output PDF file"
echo -e " -m, --metadata Metadata YAML file (optional)"
echo -e " -h, --help Display this help message"
}
# Parse command-line arguments
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-i|--input)
INPUT="$2"
shift # past argument
shift # past value
;;
-o|--output)
OUTPUT="$2"
shift # past argument
shift # past value
;;
-m|--metadata)
METADATA="$2"
shift # past argument
shift # past value
;;
-h|--help)
print_usage
exit 0
;;
*) # unknown option
shift # past argument
;;
esac
done
# Check if input and output files are provided
if [[ -z "$INPUT" || -z "$OUTPUT" ]]; then
echo -e "${RED}Error: Input and output files must be provided.${NC}"
print_usage
exit 1
fi
# Check if input file exists
if [[ ! -f "$INPUT" ]]; then
echo -e "${RED}Error: Input file $INPUT not found.${NC}"
exit 1
fi
# Check Python version
PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:3])))')
echo -e "${GRAY}Python version: $PYTHON_VERSION${NC}"
if [[ $(echo "$PYTHON_VERSION >= 3.9" | bc -l) -eq 0 ]]; then
echo -e "${RED}Python 3.9 or greater is required.${NC}"
exit 1
fi
# Install dependencies
pip3 install --user jinja2 pyyaml
# Load metadata from YAML file if provided, else from markdown file
if [[ -n "$METADATA" && -f "$METADATA" ]]; then
METADATA_CONTENT=$(python3 -c "import yaml; print(yaml.safe_load(open('$METADATA')))")
else
METADATA_CONTENT=$(python3 -c "import yaml; print(yaml.safe_load(open('$INPUT')))")
fi
# Replace variables in markdown file
IN_FILLED=$(echo "$INPUT" | sed 's/.md/_filled.md/')
cp "$INPUT" "$IN_FILLED"
for key in $(echo "$METADATA_CONTENT" | python3 -c "import sys, json; print(' '.join(json.load(sys.stdin).keys()))"); do
value=$(echo "$METADATA_CONTENT" | python3 -c "import sys, json; print(json.load(sys.stdin)['$key'])")
sed -i "s/\$$key\$/$value/g" "$IN_FILLED"
done
# Remove YAML header
sed -i '/^---$/,/^---$/d' "$IN_FILLED"
# Convert to PDF
mdpdf "$IN_FILLED" "$OUTPUT"
# Clean up
rm "$IN_FILLED"
echo -e "${GREEN}PDF generated successfully.${NC}"
#!/bin/bash
# mdpdf_pop.sh v0.8.0
# ------------
# Sunsetting!
#
# @zudsniper
# Default values
INPUT_FILE="in.md"
OUTPUT_FILE="out.pdf"
METADATA_FILE="metadata.yaml"
# Print usage
print_usage() {
echo -e "\033[1;32mUsage:\033[0m"
echo " $0 -i <input_file> -o <output_file> [-m <metadata_file>]"
echo -e "\033[1;32mOptions:\033[0m"
echo " -i, --input Input Markdown file (default: in.md)"
echo " -o, --output Output PDF file (default: out.pdf)"
echo " -m, --metadata Metadata YAML file (default: metadata.yaml)"
echo " -h, --help Show this help message"
}
# Parse command-line options
while (( "$#" )); do
case "$1" in
-i|--input)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
INPUT_FILE=$2
shift 2
else
echo -e "\033[0;31mError: Argument for $1 is missing\033[0m" >&2
exit 1
fi
;;
-o|--output)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
OUTPUT_FILE=$2
shift 2
else
echo -e "\033[0;31mError: Argument for $1 is missing\033[0m" >&2
exit 1
fi
;;
-m|--metadata)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
METADATA_FILE=$2
shift 2
else
echo -e "\033[0;31mError: Argument for $1 is missing\033[0m" >&2
exit 1
fi
;;
-h|--help)
print_usage
exit 0
;;
-*|--*=) # unsupported flags
echo -e "\033[0;31mError: Unsupported flag $1\033[0m" >&2
exit 1
;;
*) # preserve positional arguments
PARAMS="$PARAMS $1"
shift
;;
esac
done
# Check for Python 3.9 or greater
VERSION=$(python3 --version | awk '{print $2}')
echo -e "\033[0;37mPython version: $VERSION\033[0m"
IFS='.' read -ra VERSION_PARTS <<< "$VERSION"
if [[ ${VERSION_PARTS[0]} -lt 3 || ${VERSION_PARTS[1]} -lt 9 ]]; then
echo -e "\033[0;31mPython 3.9 or greater is required.\033[0m"
exit 1
fi
# Check for pip
if ! command -v pip3 &> /dev/null; then
echo -e "\033[0;31mpip is not installed. Please install it and try again.\033[0m"
exit 1
fi
# Install necessary Python packages
pip3 install jinja2 pyyaml
# Check for mdpdf
if ! command -v mdpdf &> /dev/null; then
echo -e "\033[0;31mmdpdf is not installed. Please install it and try again.\033[0m"
exit 1
fi
# Check for input file
if [[ ! -f "$INPUT_FILE" ]]; then
echo -e "\033[0;31mInput file $INPUT_FILE not found.\033[0m"
exit 1
fi
# If no metadata file is provided, check if metadata exists in input file
if [[ ! -f "$METADATA_FILE" ]]; then
if grep -q "^---$" "$INPUT_FILE"; then
# Metadata exists in input file, use it
METADATA_FILE="$INPUT_FILE"
else
echo -e "\033[0;31mNo metadata provided. Please provide a metadata.yaml file.\033[0m"
exit 1
fi
fi
# Separate the YAML metadata from the rest of the Markdown content
YAML_METADATA=$(sed -n '/^---$/,/^---$/p' "$INPUT_FILE")
MARKDOWN_CONTENT=$(sed '/^---$/,/^---$/d' "$INPUT_FILE")
# Render the template
python3 -c "
import yaml
import jinja2
# Load the YAML metadata
metadata = yaml.safe_load('''$YAML_METADATA''')
# Load the Jinja2 template
template = jinja2.Template('''$MARKDOWN_CONTENT''')
# Render the template with the metadata
result = template.render(metadata)
# Write the result to out.md
with open('in_filled.md', 'w') as f:
f.write(result)
"
# Convert the resulting Markdown file to PDF with mdpdf
mdpdf in_filled.md $OUTPUT_FILE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment