Merge branch 'main' of ssh://git.wlankabel.at:1516/aqoaba/md2tex

This commit is contained in:
jowodo 2025-06-09 15:08:12 +02:00
commit f6f36ffa23
8 changed files with 382 additions and 21 deletions

View File

@ -1,4 +1,26 @@
# README # 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. All names are temporary and happy about suggestions of improvement.
Dependencies: Dependencies:
@ -6,6 +28,8 @@ Dependencies:
- python3 - python3
- pypdf (e.g. `python3 -m venv .venv && . .venv/bin/activate && pip install pypdf`) - pypdf (e.g. `python3 -m venv .venv && . .venv/bin/activate && pip install pypdf`)
- xelatex (e.g. `apt install texlive-xetex`) - 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 - [ ] check if md2parallel is available
- [ ] ultimately include md2XXX.sh into md2tex.py - [ ] ultimately include md2XXX.sh into md2tex.py
- [ ] make sure that underscores are no problem - [ ] 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
View 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

View File

@ -37,10 +37,11 @@ $SED_CMD 's@<p>@\n\\pend\\pstart\n@' ${BASENAME}.html
$SED_CMD 's@</p>@@' ${BASENAME}.html $SED_CMD 's@</p>@@' ${BASENAME}.html
$SED_CMD 's@“@\\enquote{@g' ${BASENAME}.html $SED_CMD 's@“@\\enquote{@g' ${BASENAME}.html
$SED_CMD 's@”@}@g' ${BASENAME}.html $SED_CMD 's@”@}@g' ${BASENAME}.html
$SED_CMD 's@<h1.*">@\\section[@' ${BASENAME}.html $SED_CMD 's@<h1.*">@\\section{@' ${BASENAME}.html
$SED_CMD 's@</h1>@]@' ${BASENAME}.html $SED_CMD 's@</h1>@}@' ${BASENAME}.html
$SED_CMD 's@<h2.*">@{@' ${BASENAME}.html $SED_CMD 's@<h2.*">@\\pend\\pstart\\subsection{@' ${BASENAME}.html
$SED_CMD 's@</h2>@}@' ${BASENAME}.html $SED_CMD 's@</h2>@}@' ${BASENAME}.html
$SED_CMD "s@@'@g" ${BASENAME}.html $SED_CMD "s@@'@g" ${BASENAME}.html
mv ${BASENAME}.html ${BASENAME}.tex mv ${BASENAME}.html ${BASENAME}.tex
cat ${BASENAME}.tex && rm ${BASENAME}.tex cat ${BASENAME}.tex && rm ${BASENAME}.tex
if [[ -f ${BASENAME}.html\'\' ]] ; then rm ${BASENAME}.html\'\' ; fi

View File

@ -101,11 +101,10 @@ TITLE_PAGE="""
\hrule width \hsize \hrule width \hsize
\kern 1mm \kern 1mm
\hrule width \hsize height 2pt \hrule width \hsize height 2pt
%\vskip 8em
\vspace*{\fill} \vspace*{\fill}
\large \LARGE
$PUBLISHER $PUBLISHER
\vskip 2em % \vskip 2em
\end{flushright} \end{flushright}
\end{titlingpage} \end{titlingpage}
""" """
@ -122,9 +121,6 @@ COLOPHON="""
\begin{LARGE} \begin{LARGE}
\begin{tcolorbox}[width=.5\textwidth] \begin{tcolorbox}[width=.5\textwidth]
\centering \centering
% \texttt{AQO}\\
% \texttt{ABA}\\
% \texttt{~\newline AQO\newline ABA\newline}%\\
\texttt{$PUBLISHER} \texttt{$PUBLISHER}
\end{tcolorbox} \end{tcolorbox}
\end{LARGE} \end{LARGE}
@ -179,6 +175,7 @@ echo $TMPDIR
for i in $(seq 1 $COMPILATION_RUNS ) for i in $(seq 1 $COMPILATION_RUNS )
do do
$LATEX_ENGINE $PROJECT.tex # 2&> /dev/null $LATEX_ENGINE $PROJECT.tex # 2&> /dev/null
echo ${i}-th compilation finished
done done
#$LATEX_ENGINE $PROJECT.tex # 2&> /dev/null #$LATEX_ENGINE $PROJECT.tex # 2&> /dev/null
# $LATEX_ENGINE $PROJECT.tex # $LATEX_ENGINE $PROJECT.tex

View File

@ -7,11 +7,12 @@ PROJECT="asem"
TITLE="Nsɛm wɔ Twi ne Brɔfo" TITLE="Nsɛm wɔ Twi ne Brɔfo"
SUBTITLE="Texts in Twi and English" SUBTITLE="Texts in Twi and English"
AUTHOR="Yɛn Ara" AUTHOR="Yɛn Ara"
PUBLISHER="AQO\\\\ABA"
PUBLISHER="twi\TeX"
EDITION="First Edition"
COMPILATION_RUNS="3"
INFILES=""" INFILES="""
Anansesem - Ghanaian Folk Tales Anansesem - Ghanaian Folk Tales
testfiles/parallel-ak.md testfiles/parallel-ak.md
testfiles/parallel-en.md testfiles/parallel-en.md
""" """
PUBLISHER="AQO\\\\ABA"
EDITION="First Edition"
COMPILATIONS_RUNS="1"

View File

@ -1,7 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from pypdf import PdfReader from pypdf import PaperSize, PdfReader, PdfWriter, Transformation
from pypdf import PdfWriter from pypdf.generic import RectangleObject
import argparse import argparse
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
prog='pdf2book', prog='pdf2book',
@ -12,6 +14,7 @@ parser.add_argument('pdf_file') # positional argument
#parser.add_argument('pages', type=int) # positional argument #parser.add_argument('pages', type=int) # positional argument
#parser.add_argument('-s', '--signature') # option that takes a value #parser.add_argument('-s', '--signature') # option that takes a value
parser.add_argument('-v', '--verbose', action='store_true') # on/off flag 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', parser.add_argument('-s', '--signature',
dest='signature', dest='signature',
type=int, type=int,
@ -82,6 +85,7 @@ def get_reorder(number_of_pages: int, signature_size: int):
#print(lst) #print(lst)
#print(len(lst)) #print(len(lst))
return lst return lst
def print_signatures(lst: list,signature_size: int): def print_signatures(lst: list,signature_size: int):
if signature_size==0: signature_size=1 if signature_size==0: signature_size=1
for i in range( len( lst ) ): for i in range( len( lst ) ):
@ -91,13 +95,9 @@ def print_signatures(lst: list,signature_size: int):
print(lst[i], end=' ') print(lst[i], end=' ')
else: else:
print(lst[i],end='.') print(lst[i],end='.')
lst=get_reorder(number_of_pages, signature_size)
print_signatures(lst,signature_size)
# REARRANGING OF PAGES # REARRANGING OF PAGES
def rearrange_pages(reader, lst): def rearrange_pages(reader, lst):
writer = PdfWriter() writer = PdfWriter()
for page in lst: for page in lst:
# print(page) # 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) writer.add_blank_page(width=reader.pages[0].mediabox.width,height=reader.pages[0].mediabox.height)
else: else:
writer.add_page(reader.pages[page-1]) writer.add_page(reader.pages[page-1])
return writer return writer
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 # SAVE FILE TO DISK
writer=rearrange_pages(reader,lst)
outfile=args.pdf_file.split(".pdf")[0]+"_book_s"+str(signature_size)+".pdf"
with open(outfile, "wb") as fp: with open(outfile, "wb") as fp:
writer.write(fp) writer.write(fp)

199
sakara.py Executable file
View 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

Binary file not shown.