Ein Open Source Kochrezept
Ottmar Gobrecht
DOAG Konferenz 2016, Nürnberg
Appetithäppchen
Einwohnerentwicklung New York, Rio, Tokio
1940 - 2010
Population Development,New York,Rio,Tokio
1940,7454995,1759277,6778804
1950,7891957,2375280,5385071
1960,7781984,3300431,8310027
1970,7895563,4251918,8840942
1980,7071639,5090723,8351893
1990,7322564,5480768,8163573
2000,8008278,5857904,8134688
2010,8175133,6320446,8980768
Selber Kochen
# Eine Überschrift
Ein kurzer Absatz.
* Ein Aufzählungspunkt
* Noch einer mit *kursivem* und **fettem** Text
HTML = Publikations-Format
Markdown = Schreib-Format
Komplette ursprüngliche Syntax, Weiterentwicklungen, das APEX Plugin
pandoc demo.md --from=markdown --to=html --output=demo.html
Anmerkung:
Node.js führt die gleichen Shellscripte aus, die man auch zur Entwicklung lokal ausführt. Es ist wirklich nur eine Fernsteuerung übers Web, weil in der Regel in einer Produktivumgebung die Möglichkeit fehlt, solche Dienste lokal auf dem Datenbankserver zu hosten. Das ist auch der Grund, warum jegliches Logging in der Node-App fehlt. Es darf ausschließlich von der Datenbank zugegriffen werden und etwaige Fehler können auf der Datenbank in eine Tabelle geschrieben werden.
Da die PDF-Erstellung in LaTeX recht aufwendig ist, sollte man überlegen, seitens der Datenbank die Anzahl der gleichzeitigen PDF-Erstellungen zu limitieren. Dies kann durch eine Jobsteuerung geschehen, was im Reporting-Umfeld ja sowieso oft der Fall ist.
Natürlich steht es jedem frei, alles nach seinen Wünschen anzupassen. Dies ist ja nur eine Beispielimplementierung, welche die Einstiegshürde in das Thema senken soll.
Muss dazu noch etwas gesagt werden?
pip3 install -U pip
python -m pip install -U pip
pip3 install matplotlib
pip3 install pandas
pip3 install seaborn
pip3 install jupyter
Anmerkung:
Bei der Installation von seaborn unter Windows kann es zu folgendem Fehler kommen, wenn scipy installiert wird: No Lapack/Blas Resources Found
. Dazu gibt es einen Stackoverflow Beitrag - hier (eine) mögliche Lösung in Kurzform:
pip install localDownloadedFileName
pip install seaborn
klappenSpäter habe ich dann bei der Anwendung von dem Pandoc Python Filter wieder einen Fehler bekommen, diesmal ging es um numpy+mkl - die Lösung ist fast die gleiche:
pip install localDownloadedFileName
npm install
(dort, wo package.json liegt)node app.js
oracle_plsql
SELECT markdown_reporter.convert_document(
p_format => 'pdf' -- html, pdf, docx (with png's only)
, p_markdown => markdown_reporter.preprocess_data(p_markdown => q'[
``` { .sql .chart .line caption="Demo Chart"}
SELECT 1940 "Population Development", 7454995 "New York", 1759277 "Rio"
, 6778804 "Tokio" FROM dual UNION ALL
SELECT 1950,7891957,2375280,5385071 FROM dual UNION ALL
SELECT 1960,7781984,3300431,8310027 FROM dual UNION ALL
SELECT 1970,7895563,4251918,8840942 FROM dual UNION ALL
SELECT 1980,7071639,5090723,8351893 FROM dual UNION ALL
SELECT 1990,7322564,5480768,8163573 FROM dual UNION ALL
SELECT 2000,8008278,5857904,8134688 FROM dual UNION ALL
SELECT 2010,8175133,6320446,8980768 FROM dual;
```
]'))
FROM dual;
SELECT markdown_reporter.preprocess_data(p_markdown => '...')
FROM dual;
``` { .sql .chart .line caption="Demo Chart"}
"Population Development","New York","Rio","Tokio"
"1940","7454995","1759277","6778804"
"1950","7891957","2375280","5385071"
"1960","7781984","3300431","8310027"
"1970","7895563","4251918","8840942"
"1980","7071639","5090723","8351893"
"1990","7322564","5480768","8163573"
"2000","8008278","5857904","8134688"
"2010","8175133","6320446","8980768"
```
Die ganze Magie findet in einem Pandoc Filter statt
# read csv data from code block
df = pd.read_csv(StringIO( code ), index_col=0, parse_dates=True)
# create chart
if charttype == 'line':
ax = df.plot.line(subplots=False, figsize=(width/96, height/96), \
legend=legend) # size must be given in inches, default is 96 dpi
#---<snip>-----------------------------------------------------------
# set title and axis labels
if title != '':
ax.set_title(title)
#---<snip>-----------------------------------------------------------
# clean up chart with seaborn despine method
sns.despine()
# save chart
plt.savefig(filename)
Jupyter Start mit Shellaufruf:
jupyter notebook
Jupyter-Docs, Das Notizbuch aus dem Markdown Reporter Projekt
Notebook Schritt für Schritt ausführen
Für einen unverbindlichen Test oder eine temporäre Entwicklungsumgebung ohne Adminrechte:
msiexec /a pathToMsiFile /qb TARGETDIR=pathToTargetDir
Anmerkung:
Natürlich muß man sich selbst um die Pfadangaben kümmern, wenn man alles portabel installiert - aber man kann sich ja mit Batchdateien aushelfen - hier ein Beispiel:
echo off
cls
if [%1]==[] echo Please provide the desired target format as a parameter - example: convert html & goto end
set format=%1
set filterformat=%1
set filter=..\..\pandoc_filter\pandocFilterMarkdownReporter.py
set datadir=..
set pandoc=c:\og\PortableApps\pandoc\pandoc.exe
set python=c:\og\PortableApps\python\python-3.5.2.amd64\python.exe
set latex=c:\og\PortableApps\miktex\miktex\bin\lualatex.exe
rem remove the first parameter (the format)
shift
rem fill var params with remaining parameters
set params=%1
:loop
shift
if [%1]==[] goto afterloop
set params=%params% %1
goto loop
:afterloop
rem ensure the same format names like pandoc - for PDF files the output format is latex!
if %format%==pdf set filterformat=latex
echo generate JSON source...
%pandoc% document.md --from=markdown --to=json --output=document.json %params%
echo apply filter (generate charts from relevant code blocks)...
%python% %filter% %filterformat%
echo generate target document...
if %format%==html %pandoc% document.filtered.json --from=json --to=html --output=document.html --data-dir=%datadir% --self-contained --standalone %params%
if %format%==docx %pandoc% document.filtered.json --from=json --to=docx --output=document.docx --data-dir=%datadir% %params%
if %format%==pdf %pandoc% document.filtered.json --from=json --to=latex --output=document.pdf --data-dir=%datadir% --latex-engine=%latex% %params%
:end