Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat: display a graph in the PDF output for the ephemerides
Show a graph instead of a table for the ephemerides in the PDF output
  • Loading branch information
Jérôme Deuchnord committed May 12, 2020
1 parent ef2e9e4 commit 4ea148e
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 92 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Expand Up @@ -6,8 +6,10 @@ kosmorro.egg-info
coverage.xml
node_modules/
package-lock.json

/kosmorrolib/assets/pdf/*
!/assets/pdf/*.tex
!/kosmorrolib/assets/pdf/*.tex
!/kosmorrolib/assets/pdf/*.sty

/manpage/*
!/manpage/*.md
Expand Down
1 change: 1 addition & 0 deletions .scripts/tests-e2e.sh
Expand Up @@ -104,6 +104,7 @@ assertSuccess "$PIP_BIN install latex" "CI"

# Dependencies installed, should not fail
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf"
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf --no-graph"

# man page
assertSuccess "man --pager=cat kosmorro"
Expand Down
115 changes: 115 additions & 0 deletions kosmorrolib/assets/pdf/kosmorro.sty
@@ -0,0 +1,115 @@
%! Package = kosmorro
%! Author = Jérôme Deuchnord
%! Date = 2020-04-26

\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{kosmorro}[2020/04/26 Kosmorro Package]

\RequirePackage{xcolor}
\RequirePackage{fp}

\newcommand{\moonphase}[2]{
\begin{center}
\begin{minipage}{2cm}
\includegraphics[width=\linewidth]{#1}
\end{minipage}
\hspace{5mm}
\begin{minipage}{7cm}
\textbf{\currentmoonphasetitle}\\#2
\end{minipage}
\end{center}
}

\newenvironment{ephemerides}{
\begin{table}[h]
\centering
\begin{tabular}{lccc}
\textbf{\ephemeridesobjecttitle} &
\textbf{\ephemeridesrisetimetitle} &
\textbf{\ephemeridesculminationtimetitle} &
\textbf{\ephemeridessettimetitle}\\
\hline
}{
\end{tabular}
\end{table}
}

\newcommand{\object}[4]{
\hline
\textbf{#1} & {#2} & {#3} & {#4}\\
}

\newenvironment{graphephemerides}{\setlength{\unitlength}{0.02\linewidth}
\begin{picture}(20,20)
% Axes
\put(0,-2){\vector(1,0){50}}
\multiput(0,-2)(2,0){24}{
\line(0,-1){0.25}
}
\newcounter{hour}
\multiput(-0.25,-3.5)(4,0){12}{
\sffamily\footnotesize
\arabic{hour}\stepcounter{hour}\stepcounter{hour}
}
\put(49,-3.5){\sffamily\footnotesize hours}

% Graduation

\put(50,-0.5){\sffamily\footnotesize Pluto}
\put(50,1.5){\sffamily\footnotesize Neptune}
\put(50,3.5){\sffamily\footnotesize Uranus}
\put(50,5.5){\sffamily\footnotesize Saturn}
\put(50,7.5){\sffamily\footnotesize Jupiter}
\put(50,9.5){\sffamily\footnotesize Mars}
\put(50,11.5){\sffamily\footnotesize Venus}
\put(50,13.5){\sffamily\footnotesize Mercury}
\put(50,15.5){\sffamily\footnotesize Moon}
\put(50,17.5){\sffamily\footnotesize Sun}

\multiput(0,0)(0,2){10}{
\color{gray}\line(1,0){48}
}

\linethickness{1.5mm}
}{
\end{picture}
\vspace{1cm}
}

\newcommand{\graphobject}[8]{%
% #1: Y coordinate component
% #2: Color
% #3: Hour rise time
% #4: Minute rise time
% #5: Hour set time
% #6: Minute set time
% #7: Human-readable rise time
% #8: Human-readable set time

\FPeval{\start}{#3*2+(#4/60)*2}%
\FPeval{\length}{#5*2+(#6/60)*2 - \start}%
\FPeval{\starttext}{\start+0.7}%
\FPeval{\endtext}{\start+\length-3.25}%

{\color{#2}%
\put(\start,#1){%
\line(1, 0){\length}%
}}%

\put(\starttext,#1.5){\sffamily\footnotesize #7}%
\put(\endtext,#1.5){\sffamily\footnotesize #8}%
}

\newcommand{\event}[2]{
\textbf{#1} & {#2}\\
}

\newenvironment{events}{
\begin{table}[h]
\begin{tabular}{ll}
}{
\end{tabular}
\end{table}
}

\endinput
54 changes: 9 additions & 45 deletions kosmorrolib/assets/pdf/template.tex
Expand Up @@ -5,12 +5,19 @@
\usepackage[margin=25mm]{geometry}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{kosmorro}

\newcommand{\currentmoonphasetitle}{+++CURRENT-MOON-PHASE-TITLE+++}
\newcommand{\ephemeridesobjecttitle}{+++EPHEMERIDES-OBJECT+++}
\newcommand{\ephemeridesrisetimetitle}{+++EPHEMERIDES-RISE-TIME+++}
\newcommand{\ephemeridesculminationtimetitle}{+++EPHEMERIDES-CULMINATION-TIME+++}
\newcommand{\ephemeridessettimetitle}{+++EPHEMERIDES-SET-TIME+++}

% Fix Unicode issues
\DeclareUnicodeCharacter{202F}{~}
\DeclareUnicodeCharacter{00B0}{$^\circ$}

\hypersetup{pdfinfo={
\hypersetup{pdfinfo={%
Title={+++DOCUMENT-TITLE+++},
Creator={Kosmorro v+++KOSMORRO-VERSION+++}
}}
Expand All @@ -23,49 +30,6 @@

\begin{document}

\newcommand{\object}[4]{
\hline
\textbf{#1} & {#2} & {#3} & {#4}\\
}

\newcommand{\moonphase}[2]{
\begin{center}
\begin{minipage}{2cm}
\includegraphics[width=\linewidth]{#1}
\end{minipage}
\hspace{5mm}
\begin{minipage}{7cm}
\textbf{+++CURRENT-MOON-PHASE-TITLE+++}\\#2
\end{minipage}
\end{center}
}

\newenvironment{ephemerides}{
\begin{table}[h]
\centering
\begin{tabular}{lccc}
\textbf{+++EPHEMERIDES-OBJECT+++} &
\textbf{+++EPHEMERIDES-RISE-TIME+++} &
\textbf{+++EPHEMERIDES-CULMINATION-TIME+++} &
\textbf{+++EPHEMERIDES-SET-TIME+++}\\
\hline
}{
\end{tabular}
\end{table}
}

\newcommand{\event}[2]{
\textbf{#1} & {#2}\\
}

\newenvironment{events}{
\begin{table}[h]
\begin{tabular}{ll}
}{
\end{tabular}
\end{table}
}

\maketitle

+++INTRODUCTION+++
Expand All @@ -76,7 +40,7 @@
\section{\sffamily +++SECTION-EPHEMERIDES+++}

\begin{ephemerides}
+++EPHEMERIDES+++
+++EPHEMERIDES+++
\end{ephemerides}
%%% END-EPHEMERIDES-SECTION

Expand Down
67 changes: 60 additions & 7 deletions kosmorrolib/dumper.py
Expand Up @@ -20,6 +20,7 @@
import datetime
import json
import os
from pathlib import Path
from tabulate import tabulate
from numpy import int64
from termcolor import colored
Expand All @@ -41,13 +42,15 @@

class Dumper(ABC):
def __init__(self, ephemerides: [AsterEphemerides] = None, moon_phase: MoonPhase = None, events: [Event] = None,
date: datetime.date = datetime.date.today(), timezone: int = 0, with_colors: bool = True):
date: datetime.date = datetime.date.today(), timezone: int = 0, with_colors: bool = True,
show_graph: bool = False):
self.ephemerides = ephemerides
self.moon_phase = moon_phase
self.events = events
self.date = date
self.timezone = timezone
self.with_colors = with_colors
self.show_graph = show_graph

if self.timezone != 0:
self._convert_dates_to_timezones()
Expand Down Expand Up @@ -282,10 +285,17 @@ def _make_document(self, template: str) -> str:
.replace('+++SECTION-EVENTS+++', _('Expected events')) \
.replace('+++EVENTS+++', self._make_events())

if self.show_graph:
# The graphephemerides environment beginning tag must end with a percent symbol to ensure
# that no extra space will interfere with the graph.
document = document.replace(r'\begin{ephemerides}', r'\begin{graphephemerides}%')\
.replace(r'\end{ephemerides}', r'\end{graphephemerides}')

return document

def _make_ephemerides(self) -> str:
latex = []
graph_y_component = 18

if self.ephemerides is not None:
for ephemeris in self.ephemerides:
Expand All @@ -308,10 +318,46 @@ def _make_ephemerides(self) -> str:
else:
aster_set = '-'

latex.append(r'\object{%s}{%s}{%s}{%s}' % (ephemeris.object.name,
aster_rise,
aster_culmination,
aster_set))
if not self.show_graph:
latex.append(r'\object{%s}{%s}{%s}{%s}' % (ephemeris.object.name,
aster_rise,
aster_culmination,
aster_set))
else:
if ephemeris.rise_time is not None:
raise_hour = ephemeris.rise_time.hour
raise_minute = ephemeris.rise_time.minute
else:
raise_hour = raise_minute = 0
aster_rise = ''

if ephemeris.set_time is not None:
set_hour = ephemeris.set_time.hour
set_minute = ephemeris.set_time.minute
else:
set_hour = 24
set_minute = 0
aster_set = ''
sets_after_end = set_hour > raise_hour

if not sets_after_end:
latex.append(r'\graphobject{%d}{gray}{0}{0}{%d}{%d}{}{%s}' % (graph_y_component,
set_hour,
set_minute,
aster_set))
set_hour = 24
set_minute = 0

latex.append(r'\graphobject{%d}{gray}{%d}{%d}{%d}{%d}{%s}{%s}' % (
graph_y_component,
raise_hour,
raise_minute,
set_hour,
set_minute,
aster_rise,
aster_set if sets_after_end else ''
))
graph_y_component -= 2

return ''.join(latex)

Expand Down Expand Up @@ -345,10 +391,15 @@ def _remove_section(document: str, section: str):


class PdfDumper(Dumper):
def _convert_dates_to_timezones(self):
"""This method is disabled in this dumper, because the timezone is already converted
in :class:`_LatexDumper`."""

def to_string(self):
try:
latex_dumper = _LatexDumper(self.ephemerides, self.moon_phase, self.events,
date=self.date, timezone=self.timezone, with_colors=self.with_colors)
date=self.date, timezone=self.timezone, with_colors=self.with_colors,
show_graph=self.show_graph)
return self._compile(latex_dumper.to_string())
except RuntimeError:
raise UnavailableFeatureError(_("Building PDFs was not possible, because some dependencies are not"
Expand All @@ -364,4 +415,6 @@ def _compile(latex_input) -> bytes:
if build_pdf is None:
raise RuntimeError('Python latex module not found')

return bytes(build_pdf(latex_input))
package = str(Path(__file__).parent.absolute()) + '/assets/pdf/'

return bytes(build_pdf(latex_input, [package]))

0 comments on commit 4ea148e

Please sign in to comment.