-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
1,205 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
name: CI | ||
on: | ||
push: | ||
tags: 'v*' | ||
workflow_dispatch: | ||
jobs: | ||
build: | ||
if: github.event.base_ref == 'refs/heads/master' | ||
runs-on: windows-latest | ||
continue-on-error: true | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-python@v2 | ||
with: | ||
python-version: '3.8' | ||
architecture: 'x86' | ||
|
||
- name: Get Python Version | ||
shell: powershell | ||
run: python -V | ||
|
||
- name: Create .env | ||
shell: powershell | ||
run: | | ||
rm -r .env -ErrorAction Ignore; | ||
python -m venv .env; | ||
.env/Scripts/activate; | ||
pip install -r requirements.txt | ||
- name: Build | ||
shell: powershell | ||
working-directory: mdpdfbook | ||
run: | | ||
rm -r dist -ErrorAction Ignore; | ||
rm -r build -ErrorAction Ignore; | ||
rm *.spec -ErrorAction Ignore; | ||
../.env/Scripts/activate; | ||
pyinstaller --noconfirm --clean --onefile --name 'mdpdfbook' __main__.py; | ||
rm -r build -ErrorAction Ignore; | ||
rm *.spec -ErrorAction Ignore | ||
- name: Create Release | ||
id: create_release | ||
uses: actions/create-release@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
tag_name: ${{ github.ref }} | ||
release_name: ${{ github.ref }} | ||
draft: false | ||
prerelease: false | ||
- name: Upload Release Asset | ||
id: upload-release-asset | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
asset_path: mdpdfbook/dist/mdpdfbook.exe | ||
asset_name: mdpdfbook.exe | ||
asset_content_type: application/octet-stream |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2021 Geraked | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Convert MD to PDF | ||
|
||
![GitHub release (latest by date)](https://img.shields.io/github/v/release/geraked/mdpdfbook) | ||
[![CI](https://github.com/geraked/mdpdfbook/actions/workflows/main.yml/badge.svg)](https://github.com/geraked/crack-qv/actions/workflows/main.yml) | ||
|
||
## Author | ||
|
||
**Rabist** - view on [LinkedIn](https://www.linkedin.com/in/rabist) | ||
|
||
## License | ||
|
||
Licensed under [MIT](LICENSE). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
Python command line application to convert Markdown to PDF. | ||
.. currentmodule:: mdpdf | ||
.. moduleauthor:: Norman Lorrain <[email protected]> | ||
""" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
This is the entry point for the command-line interface (CLI) application. | ||
Itcan be used as a handy facility for running the task from a command line. | ||
To learn more about Click visit the | ||
`project website <http://click.pocoo.org/5/>`_. There is also a very | ||
helpful `tutorial video <https://www.youtube.com/watch?v=kNke39OZ2k0>`_. | ||
""" | ||
import click | ||
import glob | ||
|
||
from mdpdf.converter import Converter | ||
from mdpdf.headfoot import Header, Footer | ||
from mdpdf.properties import setTitle, setSubject, setAuthor, setKeywords, setPaperSize | ||
from mdpdf import log | ||
|
||
# TODO: consider pip install click-config-file | ||
|
||
|
||
@click.command() | ||
@click.option( | ||
"--output", "-o", metavar="FILE", required=True, help="Destination for file output." | ||
) | ||
@click.option("--header", "-h", metavar="<template>", help="Sets the header template.") | ||
@click.option("--footer", "-f", metavar="<template>", help="Footer template.") | ||
@click.option("--title", "-t", default="", help="PDF title.") | ||
@click.option("--subject", "-s", default="", help="PDF subject.") | ||
@click.option("--author", "-a", default="", help="PDF author.") | ||
@click.option("--keywords", "-k", default="", help="PDF keywords.") | ||
@click.option( | ||
"--paper", | ||
"-p", | ||
default="letter", | ||
type=click.Choice(["letter", "A4"], case_sensitive=False), | ||
help="Paper size (default letter).", | ||
) | ||
@click.version_option() | ||
@click.argument("inputs", nargs=-1) | ||
def cli( | ||
output: str, | ||
header: str, | ||
footer: str, | ||
title: str, | ||
subject: str, | ||
author: str, | ||
keywords: str, | ||
paper: str, | ||
inputs, | ||
): | ||
"""Convert Markdown to PDF. | ||
\b | ||
For options below, <template> is a quoted, comma- | ||
delimited string, containing the left, centre, | ||
and right, header/footer fields. Format is | ||
"[left],[middle],[right]" | ||
\b | ||
Possible values to put here are: | ||
- Empty string | ||
- Arbitrary text | ||
- {page} current page number | ||
- {header} current top-level body text heading | ||
- {date} current date""" | ||
|
||
ctx = click.get_current_context() | ||
if not output: | ||
ctx.fail("No output specified.") | ||
|
||
try: | ||
if header: | ||
Header.setFmt(header) | ||
if footer: | ||
Footer.setFmt(footer) | ||
except Exception as e: | ||
ctx.fail(f"{e} in header/footer template.") | ||
|
||
if title: | ||
setTitle(title) | ||
|
||
if author: | ||
setAuthor(author) | ||
|
||
if subject: | ||
setSubject(subject) | ||
|
||
if keywords: | ||
setKeywords(keywords) | ||
|
||
if paper: | ||
setPaperSize(paper) | ||
|
||
if inputs: | ||
log.init() | ||
globlist = [] | ||
for i in inputs: | ||
log.debug(i) | ||
matches = glob.glob(i) | ||
if matches: | ||
globlist.extend(matches) | ||
else: | ||
ctx.fail(f"File not found: {i}.") | ||
converter = Converter(output) | ||
converter.convert(globlist) | ||
else: | ||
ctx.fail("No input specified.") | ||
|
||
|
||
if __name__ == "__main__": | ||
import sys | ||
|
||
cli.main(sys.argv[1:]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import commonmark | ||
|
||
from . import log | ||
from .pdf_renderer import PdfRenderer | ||
|
||
|
||
class Converter: | ||
def __init__(self, outputFileName): | ||
self.parser = commonmark.Parser() | ||
self.renderer = PdfRenderer(outputFileName) | ||
|
||
def convert(self, inputFileNames): | ||
for inputFile in inputFileNames: | ||
log.info(inputFile) | ||
mdFile = open(inputFile, "r", encoding="utf-8") | ||
entireFile = mdFile.read() | ||
ast = self.parser.parse(entireFile) | ||
self.renderer.render(ast, inputFile) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import fitz | ||
|
||
# _BASE14 = fitz.Base14_fontdict | ||
|
||
# Font attribute names | ||
NAME = "fontname" | ||
SIZE = "fontsize" | ||
INDENT = "indent" | ||
STRONG = "bold" | ||
EMPHASIS = "italic" | ||
|
||
|
||
COURIER = "cour" | ||
TIMES = "tiro" | ||
HELVETICA = "helv" | ||
SYMBOL = "symb" | ||
ZAPFDINGBATS = "zadb" | ||
|
||
_BOLD = "bo" | ||
_ITALIC = "it" | ||
BOLD_ITALIC = "bi" | ||
|
||
|
||
class Base14: | ||
def __init__(self, name): | ||
if name not in [COURIER, TIMES, HELVETICA, SYMBOL, ZAPFDINGBATS]: | ||
raise Exception("not valid Base14") | ||
|
||
self._name = name | ||
self._bold = False | ||
self._italic = False | ||
|
||
# def setModifier(self): | ||
# if self._root not in [COURIER, TIMES, HELVETICA]: | ||
# return # TODO: raise? symbol and zapf don't have modifiers | ||
# if self._bold and self._italic: | ||
# self._name = self._name[:2] + BOLD_ITALIC | ||
# elif self._bold: | ||
# self._name = self._name[:2] + _BOLD | ||
# elif self._italic: | ||
# self._name = self._name[:2] + _ITALIC | ||
# else: | ||
# self._name = self._root | ||
|
||
def setItalic(self, state): | ||
self._italic = state | ||
# self.setModifier() | ||
|
||
def setBold(self, state): | ||
self._bold = state | ||
# self.setModifier() | ||
|
||
@property | ||
def name(self): | ||
if self._name in [ZAPFDINGBATS, SYMBOL]: | ||
return self._name | ||
if self._name not in [COURIER, TIMES, HELVETICA]: | ||
return # TODO: raise? symbol and zapf don't have modifiers | ||
if self._bold and self._italic: | ||
name = self._name[:2] + BOLD_ITALIC | ||
elif self._bold: | ||
name = self._name[:2] + _BOLD | ||
elif self._italic: | ||
name = self._name[:2] + _ITALIC | ||
else: | ||
name = self._name | ||
return name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# | ||
|
||
|
||
class Base: | ||
enabled = False | ||
|
||
@classmethod | ||
def setFmt(cls, fmt): | ||
cls._left, cls._mid, cls._right = fmt.split(",") | ||
cls.enabled = True | ||
|
||
@classmethod | ||
def left(cls, m): | ||
return cls._left.format(**m.__dict__) | ||
|
||
@classmethod | ||
def mid(cls, m): | ||
return cls._mid.format(**m.__dict__) | ||
|
||
@classmethod | ||
def right(cls, m): | ||
return cls._right.format(**m.__dict__) | ||
|
||
|
||
class Header(Base): | ||
pass | ||
|
||
|
||
class Footer(Base): | ||
pass | ||
|
||
|
||
if __name__ == "__main__": | ||
Header.setFmt("{date},blah,{page}") | ||
|
||
class MetaData(object): | ||
pass | ||
|
||
metaData = MetaData() | ||
metaData.date = "2020-02-15" | ||
metaData.page = 12 | ||
metaData.header = "chapter 1" | ||
|
||
# metaData = {"date": date, "page": page, "header": header} | ||
|
||
l = Header.left(metaData) | ||
m = Header.mid(metaData) | ||
r = Header.right(metaData) | ||
|
||
metaData.page += 1 | ||
r = Header.right(metaData) | ||
|
||
pass |
Oops, something went wrong.