Merge branch 'main' of ssh://git.wlankabel.at:1516/aqoaba/md2tex
This commit is contained in:
commit
f6f36ffa23
40
README.md
40
README.md
@ -1,4 +1,26 @@
|
||||
# README
|
||||
## INSTALL pdf2book
|
||||
```
|
||||
PREFIX="$HOME/.local"
|
||||
LIBDIR=$PREFIX/lib
|
||||
BINDIR=$PREFIX/bin
|
||||
SRCDIR=$LIBDIR/md2tex.git
|
||||
mkdir -p $LIBDIR
|
||||
git clone ssh://git@git.wlankabel.at:1516/aqoaba/md2tex.git $SRCDIR
|
||||
python3 -m venv $SRCDIR/.venv
|
||||
. $SRCDIR/.venv/bin/activate
|
||||
pip3 install pypdf
|
||||
echo -n '''#!/bin/bash
|
||||
SRCDIR='$SRCDIR'
|
||||
VENVDIR=$SRCDIR/.venv
|
||||
. $VENVDIR/bin/activate
|
||||
python3 $SRCDIR/pdf2book.py $@
|
||||
deactivate
|
||||
'''> $BINDIR/pdf2book
|
||||
chmod +x $BINDIR/pdf2book
|
||||
|
||||
|
||||
|
||||
|
||||
All names are temporary and happy about suggestions of improvement.
|
||||
Dependencies:
|
||||
@ -6,6 +28,8 @@ Dependencies:
|
||||
- python3
|
||||
- pypdf (e.g. `python3 -m venv .venv && . .venv/bin/activate && pip install pypdf`)
|
||||
- xelatex (e.g. `apt install texlive-xetex`)
|
||||
- yaml
|
||||
- pandoc
|
||||
|
||||
---
|
||||
|
||||
@ -104,3 +128,19 @@ s=4: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 -> 16,01.02,15 14,03.04,13 12,05.06,
|
||||
- [ ] check if md2parallel is available
|
||||
- [ ] ultimately include md2XXX.sh into md2tex.py
|
||||
- [ ] make sure that underscores are no problem
|
||||
|
||||
---
|
||||
- [ ] cover
|
||||
- [ ] no cm or inch lenghts
|
||||
- [ ] publisher small and and at very buttom
|
||||
- [ ] potential picture
|
||||
- [ ] small title?
|
||||
- [ ] right flush?
|
||||
- [ ] introduction
|
||||
- [ ] TOC
|
||||
- [ ] dictionary/glossary
|
||||
- [ ] bibliography
|
||||
- [ ] bug: & in md
|
||||
- [ ] make headings two lines
|
||||
- [ ] dont cp compilation artifacts to wd
|
||||
- [ ] cp tmp to wd upon failure ...
|
||||
|
22
conf.yaml
Normal file
22
conf.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
latex-options:
|
||||
latex-engine: "xelatex"
|
||||
compilation-runs: "1"
|
||||
|
||||
document-options:
|
||||
doc-class: "memoir"
|
||||
doc-class-options: "twoside"
|
||||
fontsize: "10"
|
||||
pagesize: "a5"
|
||||
|
||||
project-options:
|
||||
language: 'en' # see chapter 18.20 in https://texdoc.org/serve/memman.pdf/0
|
||||
project: "asem"
|
||||
title: "Nsɛm wɔ Twi ne Brɔfo"
|
||||
subtitle: "Texts in Twi and English"
|
||||
author: "Yɛn Ara"
|
||||
publisher: "TwiTeX"
|
||||
edition: "First Edition"
|
||||
infiles:
|
||||
- testfiles/parallel-ak.md
|
||||
- testfiles/parallel-en.md
|
||||
|
@ -37,10 +37,11 @@ $SED_CMD 's@<p>@\n\\pend\\pstart\n@' ${BASENAME}.html
|
||||
$SED_CMD 's@</p>@@' ${BASENAME}.html
|
||||
$SED_CMD 's@“@\\enquote{@g' ${BASENAME}.html
|
||||
$SED_CMD 's@”@}@g' ${BASENAME}.html
|
||||
$SED_CMD 's@<h1.*">@\\section[@' ${BASENAME}.html
|
||||
$SED_CMD 's@</h1>@]@' ${BASENAME}.html
|
||||
$SED_CMD 's@<h2.*">@{@' ${BASENAME}.html
|
||||
$SED_CMD 's@<h1.*">@\\section{@' ${BASENAME}.html
|
||||
$SED_CMD 's@</h1>@}@' ${BASENAME}.html
|
||||
$SED_CMD 's@<h2.*">@\\pend\\pstart\\subsection{@' ${BASENAME}.html
|
||||
$SED_CMD 's@</h2>@}@' ${BASENAME}.html
|
||||
$SED_CMD "s@’@'@g" ${BASENAME}.html
|
||||
mv ${BASENAME}.html ${BASENAME}.tex
|
||||
cat ${BASENAME}.tex && rm ${BASENAME}.tex
|
||||
if [[ -f ${BASENAME}.html\'\' ]] ; then rm ${BASENAME}.html\'\' ; fi
|
||||
|
@ -101,11 +101,10 @@ TITLE_PAGE="""
|
||||
\hrule width \hsize
|
||||
\kern 1mm
|
||||
\hrule width \hsize height 2pt
|
||||
%\vskip 8em
|
||||
\vspace*{\fill}
|
||||
\large
|
||||
\LARGE
|
||||
$PUBLISHER
|
||||
\vskip 2em
|
||||
% \vskip 2em
|
||||
\end{flushright}
|
||||
\end{titlingpage}
|
||||
"""
|
||||
@ -122,9 +121,6 @@ COLOPHON="""
|
||||
\begin{LARGE}
|
||||
\begin{tcolorbox}[width=.5\textwidth]
|
||||
\centering
|
||||
% \texttt{AQO}\\
|
||||
% \texttt{ABA}\\
|
||||
% \texttt{~\newline AQO\newline ABA\newline}%\\
|
||||
\texttt{$PUBLISHER}
|
||||
\end{tcolorbox}
|
||||
\end{LARGE}
|
||||
@ -179,6 +175,7 @@ echo $TMPDIR
|
||||
for i in $(seq 1 $COMPILATION_RUNS )
|
||||
do
|
||||
$LATEX_ENGINE $PROJECT.tex # 2&> /dev/null
|
||||
echo ${i}-th compilation finished
|
||||
done
|
||||
#$LATEX_ENGINE $PROJECT.tex # 2&> /dev/null
|
||||
# $LATEX_ENGINE $PROJECT.tex
|
||||
|
@ -7,11 +7,12 @@ PROJECT="asem"
|
||||
TITLE="Nsɛm wɔ Twi ne Brɔfo"
|
||||
SUBTITLE="Texts in Twi and English"
|
||||
AUTHOR="Yɛn Ara"
|
||||
PUBLISHER="AQO\\\\ABA"
|
||||
PUBLISHER="twi\TeX"
|
||||
EDITION="First Edition"
|
||||
COMPILATION_RUNS="3"
|
||||
INFILES="""
|
||||
Anansesem - Ghanaian Folk Tales
|
||||
testfiles/parallel-ak.md
|
||||
testfiles/parallel-en.md
|
||||
"""
|
||||
PUBLISHER="AQO\\\\ABA"
|
||||
EDITION="First Edition"
|
||||
COMPILATIONS_RUNS="1"
|
||||
|
117
pdf2book.py
117
pdf2book.py
@ -1,7 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from pypdf import PdfReader
|
||||
from pypdf import PdfWriter
|
||||
from pypdf import PaperSize, PdfReader, PdfWriter, Transformation
|
||||
from pypdf.generic import RectangleObject
|
||||
|
||||
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(
|
||||
prog='pdf2book',
|
||||
@ -12,6 +14,7 @@ parser.add_argument('pdf_file') # positional argument
|
||||
#parser.add_argument('pages', type=int) # positional argument
|
||||
#parser.add_argument('-s', '--signature') # option that takes a value
|
||||
parser.add_argument('-v', '--verbose', action='store_true') # on/off flag
|
||||
parser.add_argument('-z', '--zine', action='store_true', help='Input pdf needs to be 16 pages')
|
||||
parser.add_argument('-s', '--signature',
|
||||
dest='signature',
|
||||
type=int,
|
||||
@ -82,6 +85,7 @@ def get_reorder(number_of_pages: int, signature_size: int):
|
||||
#print(lst)
|
||||
#print(len(lst))
|
||||
return lst
|
||||
|
||||
def print_signatures(lst: list,signature_size: int):
|
||||
if signature_size==0: signature_size=1
|
||||
for i in range( len( lst ) ):
|
||||
@ -91,13 +95,9 @@ def print_signatures(lst: list,signature_size: int):
|
||||
print(lst[i], end=' ')
|
||||
else:
|
||||
print(lst[i],end='.')
|
||||
lst=get_reorder(number_of_pages, signature_size)
|
||||
print_signatures(lst,signature_size)
|
||||
|
||||
# REARRANGING OF PAGES
|
||||
|
||||
def rearrange_pages(reader, lst):
|
||||
|
||||
writer = PdfWriter()
|
||||
for page in lst:
|
||||
# print(page)
|
||||
@ -105,11 +105,112 @@ def rearrange_pages(reader, lst):
|
||||
writer.add_blank_page(width=reader.pages[0].mediabox.width,height=reader.pages[0].mediabox.height)
|
||||
else:
|
||||
writer.add_page(reader.pages[page-1])
|
||||
|
||||
return writer
|
||||
|
||||
# SAVE FILE TO DISK
|
||||
def make_zine(reader, lst):
|
||||
# _____________________
|
||||
# | 1r | 8r | 7r | 6r |
|
||||
# ---------------------
|
||||
# | 2 | 3 | 4 | 5 |
|
||||
# ---------------------
|
||||
#
|
||||
# _________________________
|
||||
# | 9r | 16r | 15r | 14r |
|
||||
# -------------------------
|
||||
# | 10 | 11 | 12 | 13 |
|
||||
# -------------------------
|
||||
#
|
||||
# todo
|
||||
# - [ ] alternative folding 1 for zine
|
||||
# _____________________
|
||||
# | 3r | 2r | 1r | 8r |
|
||||
# ---------------------
|
||||
# | 4 | 5 | 6 | 7 |
|
||||
# ---------------------
|
||||
# _________________________
|
||||
# | 11r | 10r | 9r | 16r |
|
||||
# -------------------------
|
||||
# | 12 | 13 | 14 | 15 |
|
||||
# -------------------------
|
||||
#
|
||||
page_order=[
|
||||
2, 3, 4, 5,
|
||||
1, 8, 7, 6,
|
||||
10,11,12,13,
|
||||
9,16,15,14
|
||||
]
|
||||
print("zine")
|
||||
# Create a destination file, and add a blank page to it
|
||||
writer = PdfWriter()
|
||||
# Copy source page to destination page, several times
|
||||
for i in range(2):
|
||||
destpage = writer.add_blank_page(
|
||||
width=PaperSize.A4.height,
|
||||
height=PaperSize.A4.width
|
||||
)
|
||||
for y in range(2):
|
||||
for x in range(4):
|
||||
pageposition=8*i+4*y+x
|
||||
sourcepage=reader.pages[page_order[pageposition]-1]
|
||||
mb=sourcepage.mediabox
|
||||
sourcepage.cropbox = RectangleObject((
|
||||
-2*mb.right,
|
||||
-4*mb.top,
|
||||
2*mb.right,
|
||||
2*mb.top
|
||||
))
|
||||
if y == 1:
|
||||
transformation = Transformation().rotate(180)
|
||||
r="r"
|
||||
sourcepage.add_transformation(transformation)
|
||||
tx_val=(1*x+1) * sourcepage.mediabox.width
|
||||
ty_val=2*y * sourcepage.mediabox.height
|
||||
else:
|
||||
tx_val=x * sourcepage.mediabox.width
|
||||
ty_val=2*y * sourcepage.mediabox.height
|
||||
r=" "
|
||||
if x==3:
|
||||
print(page_order[pageposition],r)
|
||||
else:
|
||||
print(page_order[pageposition],r,end=' ')
|
||||
destpage.merge_transformed_page(
|
||||
sourcepage,
|
||||
Transformation(
|
||||
).translate(
|
||||
tx=tx_val,
|
||||
ty=ty_val,
|
||||
).scale(
|
||||
sx=0.5,
|
||||
sy=0.5
|
||||
)
|
||||
, expand=True
|
||||
)
|
||||
# destpage.
|
||||
destpage.mediabox = RectangleObject((
|
||||
0,
|
||||
0,
|
||||
2*mb.right,
|
||||
1*mb.top
|
||||
))
|
||||
#writer.add_page(destpage)
|
||||
# destpage = writer.add_blank_page(
|
||||
# width=PaperSize.A4.height,
|
||||
# height=PaperSize.A4.width
|
||||
# )
|
||||
return writer
|
||||
|
||||
lst=get_reorder(number_of_pages, signature_size)
|
||||
if args.zine :
|
||||
if number_of_pages != 16:
|
||||
print("Error... when using '--zine' the input pdf must have 16 pages!")
|
||||
exit(1)
|
||||
writer=make_zine(reader, lst)
|
||||
# signature_size=zine
|
||||
outfile=args.pdf_file.split(".pdf")[0]+"_zine.pdf"
|
||||
else:
|
||||
print_signatures(lst,signature_size)
|
||||
writer=rearrange_pages(reader,lst)
|
||||
outfile=args.pdf_file.split(".pdf")[0]+"_book_s"+str(signature_size)+".pdf"
|
||||
# SAVE FILE TO DISK
|
||||
with open(outfile, "wb") as fp:
|
||||
writer.write(fp)
|
||||
|
199
sakara.py
Executable file
199
sakara.py
Executable file
@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
### USAGE
|
||||
|
||||
|
||||
|
||||
# from command line, yaml file or env vars
|
||||
def parse_options(filename="anansesem.yaml"):
|
||||
import yaml
|
||||
with open(filename) as stream:
|
||||
try:
|
||||
conf=yaml.safe_load(stream)
|
||||
except yaml.YAMLError as exec:
|
||||
print(exec)
|
||||
return conf
|
||||
|
||||
# create tex files from md files
|
||||
def md2tex(infile, outdir):
|
||||
intext=read(infile)
|
||||
outtext=exec("pandoc -i inifile -f md -t tex")
|
||||
|
||||
def convert_text_format(infiles, informat='md', outformat='tex'): # from md/adoc to html/tex # md2parallel
|
||||
for file in infiles:
|
||||
if path(file) is not absolute: # os.path.isabs(my_path)
|
||||
|
||||
path()+file
|
||||
md2tex(infile, outfile)
|
||||
|
||||
def create_project_dir(conf):
|
||||
project=conf['project-options']['project']
|
||||
cwd=os.getcwd()
|
||||
if os.path.exists(project):
|
||||
shutil.rmtree(project) # https://stackoverflow.com/a/814170
|
||||
# print(project, "already exist. Please delete or move the folder")
|
||||
# exit(1)
|
||||
os.makedirs(project)
|
||||
return os.path.realpath(project)
|
||||
|
||||
def create_skel(project_dir,conf):
|
||||
proj=conf['project-options']['project']
|
||||
os.makedirs(os.path.join(proj,'chapters'))
|
||||
# create makefile
|
||||
# r'' https://stackoverflow.com/a/46011113
|
||||
# '{{{}}}'.format() https://stackoverflow.com/a/10112665
|
||||
makefile_content=r'''
|
||||
basename := {project}
|
||||
LATEX := {latex_engine}
|
||||
|
||||
test: $(basename).tex
|
||||
$(LATEX) $(basename).tex
|
||||
|
||||
full: $(basename).tex
|
||||
$(LATEX) $(basename).tex
|
||||
$(LATEX) $(basename).tex
|
||||
|
||||
clear: clean
|
||||
rm -f $(basename).pdf
|
||||
clean:
|
||||
ls | egrep "$(basename).[0-9]+" | xargs rm -f
|
||||
rm -f $(basename).*R \
|
||||
$(basename).Aend \
|
||||
$(basename).Bend \
|
||||
$(basename).Cend \
|
||||
$(basename).Dend \
|
||||
$(basename).Eend \
|
||||
$(basename).aux \
|
||||
$(basename).eled* \
|
||||
$(basename).eled* \
|
||||
$(basename).log \
|
||||
$(basename).maf \
|
||||
$(basename).mtc* \
|
||||
$(basename).glg \
|
||||
$(basename).glo \
|
||||
$(basename).gls \
|
||||
$(basename).ist \
|
||||
$(basename).mw \
|
||||
$(basename).toc
|
||||
'''.format(project=conf['project-options']['project'], latex_engine=conf['latex-options']['latex-engine'])
|
||||
makefile_path=os.path.join(project_dir,'Makefile')
|
||||
with open(makefile_path, 'w') as makefile: # https://www.geeksforgeeks.org/writing-to-file-in-python/#with-statement
|
||||
makefile.write(makefile_content)
|
||||
|
||||
# create main latex file
|
||||
mainfile_content=r'''
|
||||
\documentclass[twoside,{pagesize}paper]{{memoir}}
|
||||
\usepackage[fontsize={fontsize}pt]{{fontsize}}
|
||||
\usepackage{{libertine}} % also loads fontspec which is needed for ɔ and ɛ
|
||||
%\usepackage{{minitoc}} % make mini table of content for each chapter
|
||||
\usepackage{{graphicx}} % include graphics
|
||||
\usepackage{{tcolorbox}} % https://en.wikipedia.org/wiki/Colophon_(publishing)
|
||||
\usepackage{{placeins}} % https://tex.stackexchange.com/a/88659/264579
|
||||
\usepackage{{csquotes}} % \enquote
|
||||
\usepackage{{hyperref}} % https://tex.stackexchange.com/a/643590/264579
|
||||
\usepackage{{reledmac}} % needed for repedpar
|
||||
\usepackage{{reledpar}} % parallel text
|
||||
\firstlinenum*{{1000}}
|
||||
\linenumincrement*{{1000}}
|
||||
\newcommand{{\pagesinclude}}[2]{{
|
||||
\begin{{pages}}
|
||||
\begin{{Leftside}}
|
||||
\beginnumbering
|
||||
\pstart\input{{#1}}\pend
|
||||
\endnumbering
|
||||
\end{{Leftside}}
|
||||
\begin{{Rightside}}
|
||||
\beginnumbering
|
||||
\pstart\input{{#2}}\pend
|
||||
\endnumbering
|
||||
\end{{Rightside}}
|
||||
\end{{pages}}
|
||||
\Pages
|
||||
}}
|
||||
\title{{{title}}}
|
||||
\author{{{author}}}
|
||||
%\usepackage[showframe]{{geometry}}
|
||||
\begin{{document}}
|
||||
'''.format(pagesize=conf['document-options']['pagesize'],
|
||||
fontsize=conf['document-options']['fontsize'],
|
||||
title=conf['project-options']['title'],
|
||||
author=conf['project-options']['author'])
|
||||
mainfile_path=os.path.join(project_dir,proj+'.tex')
|
||||
with open(mainfile_path, 'w') as maintex:
|
||||
maintex.write(mainfile_content)
|
||||
maintex.write('\n')
|
||||
# title page
|
||||
titlepage=gettitlepage(conf)
|
||||
maintex.write(titlepage)
|
||||
# include chapters
|
||||
for infile in conf['project-options']['infiles']:
|
||||
# maintex.write(infile)
|
||||
f=os.path.join("chapters", os.path.basename(infile).split('.')[0]+".tex")
|
||||
maintex.write(r'\input{{{f}}}'.format(f=f))
|
||||
maintex.write('\n')
|
||||
# end document
|
||||
maintex.write('\n')
|
||||
maintex.write(r'\end{document}')
|
||||
|
||||
def gettitlepage(conf):
|
||||
title_page=r'''
|
||||
\begin{titlingpage} %This starts the title page
|
||||
% center textblock on page % https://tex.stackexchange.com/a/378157/264579
|
||||
\setlrmarginsandblock{2.5cm}{*}{1} % this is manual and only works for a5
|
||||
\setulmarginsandblock{2.5cm}{*}{1}
|
||||
\checkandfixthelayout
|
||||
\begin{flushright}
|
||||
\hrule width \hsize height 2pt
|
||||
\kern 1mm
|
||||
\hrule width \hsize
|
||||
\vspace{ 1.5em}
|
||||
\Huge
|
||||
title\par
|
||||
% \vspace{ 0.5em}
|
||||
\huge
|
||||
subtitlep osttitle\par
|
||||
\vspace{ 2em}
|
||||
\Large
|
||||
author
|
||||
\vspace{ 1.5em}
|
||||
\hrule width \hsize
|
||||
\kern 1mm
|
||||
\hrule width \hsize height 2pt
|
||||
\vspace*{\fill}
|
||||
\LARGE
|
||||
SAKARA
|
||||
% \vspace{ 2em}
|
||||
\end{flushright}
|
||||
\end{titlingpage}
|
||||
'''
|
||||
return title_page
|
||||
|
||||
def make_pdf(conf):
|
||||
os.system("cd "+conf['project-options']['project']+" && make") # https://stackoverflow.com/a/92395
|
||||
# subprocess.call("make")
|
||||
|
||||
def convert_text_format(conf):
|
||||
proj=conf['project-options']['project']
|
||||
infiles=conf['project-options']['infiles']
|
||||
for infile in infiles:
|
||||
os.system("pandoc -f markdown -t latex -i {infile} -o {outfile}".format(
|
||||
infile=infile,
|
||||
outfile=os.path.join(
|
||||
proj,
|
||||
"chapters",
|
||||
os.path.basename(infile).split('.')[0]+'.tex'
|
||||
)
|
||||
)
|
||||
)
|
||||
print(infile)
|
||||
## MAIN
|
||||
conf=parse_options("anansesem.yaml")
|
||||
project_dir=create_project_dir(conf)
|
||||
create_skel(project_dir, conf)
|
||||
infiles=conf['project-options']['infiles']
|
||||
convert_text_format(conf)
|
||||
make_pdf(conf)
|
||||
exit(0)
|
BIN
testfiles/zine.pdf
Normal file
BIN
testfiles/zine.pdf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user