Skip to content

Instantly share code, notes, and snippets.

@zudsniper
Last active July 16, 2023 02:31
Show Gist options
  • Save zudsniper/5a04637fefd122ff37789083d73edbc7 to your computer and use it in GitHub Desktop.
Save zudsniper/5a04637fefd122ff37789083d73edbc7 to your computer and use it in GitHub Desktop.
🦠 a python script to fucking populate a markdown template with metadata from a yaml document or embedded header and output a pdf. HOW CAN THAT BE SO HARD
#!/usr/bin/python3
# markpdf.py v1.1.0
# -----------------
#
# @zudsniper
import argparse
import re
import yaml
from jinja2 import Template
import markdown
import pdfkit
from loguru import logger
from colorama import Fore, Style
# ========= LOGGER ========= #
# init logger
logger.remove(0)
#logger.add(sys.stderr, format="{time:MMMM D, YYYY > HH:mm:ss!UTC-6} | [<level>{level}</level>]: {message}")
logger.add(sys.stderr, format="{time:HH:mm:ss} | [<level>{level}</level>]: {message}")
# ======= MAIN FUNC ======== #
def main():
# Parse command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', default='in.md', help='Input Markdown file (default: in.md)')
parser.add_argument('-o', '--output', default='out.pdf', help='Output PDF file (default: out.pdf)')
parser.add_argument('-m', '--metadata', help='Metadata YAML file')
args = parser.parse_args()
# Read the input file
with open(args.input, 'r') as file:
file_content = file.read()
# Separate the YAML metadata from the rest of the Markdown content
pattern = re.compile(r'^---\n(.+?)\n---\n(.+)', re.DOTALL)
match = pattern.match(file_content)
if match:
yaml_metadata_str, markdown_content = match.groups()
yaml_metadata = yaml.safe_load(yaml_metadata_str)
else:
logger.error(f"{Fore.RED}No metadata found in the markdown file.{Style.RESET_ALL}")
# Render the template
template = Template(markdown_content)
rendered_markdown = template.render(yaml_metadata)
# Convert markdown to HTML
html = markdown.markdown(rendered_markdown)
# Convert HTML to PDF
pdfkit.from_string(html, args.output)
logger.info(f"{Fore.GREEN}PDF has been successfully generated at {args.output}{Style.RESET_ALL}")
if __name__ == "__main__":
main()

β™› markpdf.py β™•

easily convert markdown to pdf -- including variables provided in the header of the file or within a separate provided metadata.yaml file

Installation

Administrator Privileged Dependency

πŸ”΄ wkhtmltopdf is REQUIRED
Installation process varies based on OS.

  • Linux (debian based) sudo apt-get install wkhtmltopdf -y

  • MacOS brew install wkhtmltopdf

  • Windows idk use WSL
    nah probably just scoop get wkhtmltopdf

Other Requirements

  • Python3.9 or greater

  • All pip package dependencies

$ python3 -m pip install -r requirements.txt

from here, you should be able to run the script via

$ python3 markpdf.py -o <output_pdf_name> -i <input_markdown_name> [-m <metadata_yaml_file>] 

I don't see why this is actually required...

After this, install setuptools

$ python3 -m pip install setuptools

Usage

To place variables into the your pdf, use this format:

{{ variable_name }}

variables with this name and yaml metadata counterparts of the same name will be populated with their values when the script generates a pdf.


cool

colorama==0.4.6
Jinja2==3.1.2
loguru==0.7.0
Markdown==3.4.3
pdfkit==1.0.0
PyYAML==6.0
setuptools==67.6.1
from setuptools import setup, find_packages
setup(
name="markpdf",
version="0.1.0",
author="Jason McElhenney",
author_email="[email protected]",
description="A tool to populate markdown files with YAML metadata and convert to PDF",
long_description=open('README.md').read(),
long_description_content_type="text/markdown",
url="https://gh.zod.tf/markpdf",
packages=find_packages(),
install_requires=[
"pyyaml",
"jinja2",
"markdown",
"pdfkit",
"loguru",
"colorama"
],
entry_points={
'console_scripts': [
'markpdf=markpdf:main',
],
},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.9',
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment