diff --git a/songbook_core/build.py b/songbook_core/build.py index e16703af..f81f00ab 100644 --- a/songbook_core/build.py +++ b/songbook_core/build.py @@ -5,7 +5,6 @@ import codecs import glob -import json import logging import os.path import re @@ -26,27 +25,6 @@ DEFAULT_AUTHWORDS = { } -def parse_template(template): - """Return the dict of default parameters defined in the template.""" - embedded_json_pattern = re.compile(r"^%%:") - with open(template) as template_file: - code = [ - line[3:-1] - for line - in template_file - if embedded_json_pattern.match(line) - ] - - data = json.loads(''.join(code)) - parameters = dict() - for param in data: - try: - parameters[param["name"]] = param["default"] - except KeyError: - parameters[param["name"]] = None - return parameters - - # pylint: disable=too-few-public-methods class Songbook(object): """Represent a songbook (.sb) file. @@ -85,12 +63,9 @@ class Songbook(object): Song.authwords['ignore'] = self.config['authwords']['ignore'] Song.authwords['sep'] = [ re.compile(r"^(.*)%s (.*)$" % sep) - for sep - in ([ - " %s" % sep - for sep - in self.config['authwords']["sep"] - ] + [',']) + for sep in ([ + " %s" % sep for sep in self.config['authwords']["sep"] + ] + [',']) ] def _parse(self, raw_songbook): @@ -134,7 +109,7 @@ class Songbook(object): self.config['datadir'], ) - context = parse_template(renderer.file_template()) + context = renderer.get_variables() context.update(self.config) context['titleprefixkeys'] = ["after", "sep", "ignore"] diff --git a/songbook_core/data/examples/songs/greensleeves.ly b/songbook_core/data/examples/songs/greensleeves.ly index 98b79433..1fd2bccb 100644 --- a/songbook_core/data/examples/songs/greensleeves.ly +++ b/songbook_core/data/examples/songs/greensleeves.ly @@ -1,21 +1,19 @@ \include "_lilypond/header" \paper{paper-height = 6.5\cm} -%\new \songbookstaff { \key a \minor - \time 6/8 - \partial 8 a'8 - \relative c''{ - c4 d8 e8. (f16) e8 d4 b8 g8. (a16) b8 - c4 a8 a8. (gis16) a8 b4 gis8 e4 a8 - c4 d8 e8. (f16 e8) d4 b8 g8. (a16) b8 - c8. (b16) a8 gis8. (fis16) gis8 a4 a8 a4. - - g'4. g8. (fis16) e8 d4 b8 g8. (a16) b8 - c4 (a8) a8. (gis16) a8 b4 gis8 e4. - g'4. g8. (fis16) e8 d4 b8 g8. (a16) b8 - c8. (b16) a8 gis8. (fis16) gis8 a4. a4. - } -} + \time 6/8 + \partial 8 a'8 + \relative c''{ + c4 d8 e8. (f16) e8 d4 b8 g8. (a16) b8 + c4 a8 a8. (gis16) a8 b4 gis8 e4 a8 + c4 d8 e8. (f16 e8) d4 b8 g8. (a16) b8 + c8. (b16) a8 gis8. (fis16) gis8 a4 a8 a4. + g'4. g8. (fis16) e8 d4 b8 g8. (a16) b8 + c4 (a8) a8. (gis16) a8 b4 gis8 e4. + g'4. g8. (fis16) e8 d4 b8 g8. (a16) b8 + c8. (b16) a8 gis8. (fis16) gis8 a4. a4. + } +} diff --git a/songbook_core/data/latex/chords.sty b/songbook_core/data/latex/chords.sty index 8fa01843..b4f5e10a 100644 --- a/songbook_core/data/latex/chords.sty +++ b/songbook_core/data/latex/chords.sty @@ -4,7 +4,50 @@ \newcommand*{\Sharp}{\nolinebreak\hspace{-.05em}\raisebox{.6ex}{\,\small\bf \#}} \newcommand*{\Flat}{\nolinebreak\hspace{-.05em}\raisebox{.6ex}{\,\small$\mathbf{\flat}$}} \newcommand*{\chordrule}{\mbox{\hspace{1cm}\rule[0.5cm]{15cm}{0.02cm}}\vspace{-.4cm}} -\newcommand*{\chordname}[2]{\makebox[3cm]{\raisebox{.5cm}{\large \textbf{\iflanguage{english}{#1}{#2}}}}} +\newcommand*{\chordname}[1]{\makebox[3cm]{\raisebox{.5cm}{\large \textbf{#1}}}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Multilanguage management + +\AtBeginDocument{ + % Default names (english) + \newcommand{\guitarchordsname}{Guitar chords} + \newcommand{\ukulelechordsname}{Ukulele chords} + \newcommand{\chordnameAsharp}{A\Sharp = B\Flat} + \newcommand{\chordnameA}{A} + \newcommand{\chordnameB}{B} + \newcommand{\chordnameCsharp}{C\Sharp = D\Flat} + \newcommand{\chordnameC}{C} + \newcommand{\chordnameDsharp}{D\Sharp = E\Flat} + \newcommand{\chordnameD}{D} + \newcommand{\chordnameE}{E} + \newcommand{\chordnameFsharp}{F\Sharp = G\Flat} + \newcommand{\chordnameF}{F} + \newcommand{\chordnameGsharp}{G\Sharp = A\Flat} + \newcommand{\chordnameG}{G} + + \IfStrEq{\mainlanguage}{french}{ + % French names + \renewcommand{\guitarchordsname}{Accords de guitare} + \renewcommand{\ukulelechordsname}{Accords de ukulélé} + \renewcommand{\chordnameAsharp}{La\Sharp = Si\Flat} + \renewcommand{\chordnameA}{La} + \renewcommand{\chordnameB}{Si} + \renewcommand{\chordnameCsharp}{Do\Sharp = Ré\Flat} + \renewcommand{\chordnameC}{Do} + \renewcommand{\chordnameDsharp}{Ré\Sharp = Mi\Flat} + \renewcommand{\chordnameD}{Ré} + \renewcommand{\chordnameE}{Mi} + \renewcommand{\chordnameFsharp}{Fa\Sharp = Sol\Flat} + \renewcommand{\chordnameF}{Fa} + \renewcommand{\chordnameGsharp}{Sol\Sharp = La\Flat} + \renewcommand{\chordnameG}{Sol} + }{} +} + +% End of multilanguage management +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \newcommand{\chords}{ \begin{songs}{} @@ -16,8 +59,8 @@ \songcolumns{1} \ifguitar - \iflanguage{english}{\beginsong{Guitar chords}}{\beginsong{Accords de guitare}} - \chordname{C}{Do} + \beginsong{\guitarchordsname} + \chordname{\chordnameC} \gtab{C}{~:X32010} \gtab{C7}{~:X32310} \gtab{Cm}{3:X02210} @@ -29,7 +72,7 @@ \gtab*{C6}{~:XX2213} \chordrule - \chordname{C\Sharp = D\Flat}{Do\Sharp = Ré\Flat} + \chordname{\chordnameCsharp} \gtab{C\#}{4:X02220} \gtab{C\#7}{4:X02020} \gtab{C\#m}{4:X02210} @@ -41,7 +84,7 @@ \gtab*{C\#6}{1:X02010} \chordrule - \chordname{D}{Ré} + \chordname{\chordnameD} \gtab{D}{~:XX0232} \gtab{D7}{~:XX0212} \gtab{Dm}{~:XX0231} @@ -53,7 +96,7 @@ \gtab*{D6}{~:X00202} \chordrule - \chordname{D\Sharp = E\Flat}{Ré\Sharp = Mi\Flat} + \chordname{\chordnameDsharp} \gtab{D\#}{6:X02220} \gtab{D\#7}{6:X02020} \gtab{D\#m}{6:X02210} @@ -65,7 +108,7 @@ \gtab*{D\#6}{1:X00202} \chordrule - \chordname{E}{Mi} + \chordname{\chordnameE} \gtab{E}{~:022100} \gtab{E7}{~:020100} \gtab{Em}{~:022000} @@ -77,7 +120,7 @@ \gtab*{E6}{~:022120} \chordrule - \chordname{F}{Fa} + \chordname{\chordnameF} \gtab{F}{1:022100} \gtab{F7}{1:020100} \gtab{Fm}{1:022000} @@ -89,7 +132,7 @@ \gtab*{F6}{~:XX0211} \chordrule - \chordname{F\Sharp = G\Flat}{Fa\Sharp = Sol\Flat} + \chordname{\chordnameFsharp} \gtab{F\#}{2:022100} \gtab{F\#7}{2:020100} \gtab{F\#m}{2:022000} @@ -101,7 +144,7 @@ \gtab*{F\#6}{~:XX1322} \chordrule - \chordname{G}{Sol} + \chordname{\chordnameG} \gtab{G}{~:320003} \gtab{G7}{~:320001} \gtab{Gm}{3:022000} @@ -113,7 +156,7 @@ \gtab*{G6}{~:320000} \chordrule - \chordname{G\Sharp = A\Flat}{Sol\Sharp = La\Flat} + \chordname{\chordnameGsharp} \gtab{G\#}{4:022100} \gtab{G\#7}{4:020100} \gtab{G\#m}{4:022000} @@ -125,7 +168,7 @@ \gtab*{G\#6}{~:XX1111} \chordrule - \chordname{A}{La} + \chordname{\chordnameA} \gtab{A}{~:X02220} \gtab{A7}{~:X02020} \gtab{Am}{~:X02210} @@ -137,7 +180,7 @@ \gtab*{A6}{~:XX2222} \chordrule - \chordname{A\Sharp = B\Flat}{La\Sharp = Si\Flat} + \chordname{\chordnameAsharp} \gtab{A\#}{1:X02220} \gtab{A\#7}{1:X02020} \gtab{A\#m}{1:X02210} @@ -149,7 +192,7 @@ \gtab*{A\#6}{~:XX3333} \chordrule - \chordname{B}{Si} + \chordname{\chordnameB} \gtab{B}{2:X02220} \gtab{B7}{X21202} \gtab{Bm}{2:X02210} @@ -169,9 +212,9 @@ \fi \ifukulele - \iflanguage{english}{\beginsong{Ukulele chords}}{\beginsong{Accords de ukulélé}} + \beginsong{\ukulelechordsname} - \chordname{C}{Do} + \chordname{\chordnameC} \utab{C}{~:0003} \utab{C7}{~:0001} \utab{Cm}{~:0333} @@ -183,7 +226,7 @@ \utab*{Cdim}{2:3101} \chordrule - \chordname{C\Sharp = D\Flat}{Do\Sharp = Ré\Flat} + \chordname{\chordnameCsharp} \utab{C\#}{1:0003} \utab{C\#7}{1:0001} \utab{C\#m}{~:1104} @@ -195,7 +238,7 @@ \utab*{C\#dim}{~:0104} \chordrule - \chordname{D}{Ré} + \chordname{\chordnameD} \utab{D}{~:2220} \utab{D7}{2:0001} \utab{Dm}{~:2210} @@ -207,7 +250,7 @@ \utab*{Ddim}{1:0104} \chordrule - \chordname{D\Sharp = E\Flat}{Ré\Sharp = Mi\Flat} + \chordname{\chordnameDsharp} \utab{D\#}{1:2220} \utab{D\#7}{3:0001} \utab{D\#m}{1:2210} @@ -219,7 +262,7 @@ \utab*{D\#dim}{~:2320} \chordrule - \chordname{E}{Mi} + \chordname{\chordnameE} \utab{E}{2:2220} \utab{E7}{~:1202} \utab{Em}{~:0432} @@ -231,7 +274,7 @@ \utab*{Edim}{1:2320} \chordrule - \chordname{F}{Fa} + \chordname{\chordnameF} \utab{F}{~:2010} \utab{F7}{~:2310} \utab{Fm}{~:1013} @@ -243,7 +286,7 @@ \utab*{Fdim}{2:2320} \chordrule - \chordname{F\Sharp = G\Flat}{Fa\Sharp = Sol\Flat} + \chordname{\chordnameFsharp} \utab{F\#}{1:2010} \utab{F\#7}{1:2310} \utab{F\#m}{~:2120} @@ -255,7 +298,7 @@ \utab*{F\#dim}{~:2020} \chordrule - \chordname{G}{Sol} + \chordname{\chordnameG} \utab{G}{~:0232} \utab{G7}{~:0212} \utab{Gm}{~:0231} @@ -267,7 +310,7 @@ \utab*{Gdim}{~:0131} \chordrule - \chordname{G\Sharp = A\Flat}{Sol\Sharp = La\Flat} + \chordname{\chordnameGsharp} \utab{G\#}{3:2010} \utab{G\#7}{1:0212} \utab{G\#m}{1:0231} @@ -279,7 +322,7 @@ \utab*{G\#dim}{1:0131} \chordrule - \chordname{A}{La} + \chordname{\chordnameA} \utab{A}{~:2100} \utab{A7}{~:0100} \utab{Am}{~:2000} @@ -291,7 +334,7 @@ \utab*{Adim}{2:0131} \chordrule - \chordname{A\Sharp = B\Flat}{La\Sharp = Si\Flat} + \chordname{\chordnameAsharp} \utab{A\#}{1:2100} \utab{A\#7}{1:0100} \utab{A\#m}{1:2000} @@ -303,7 +346,7 @@ \utab*{A\#dim}{~:3101} \chordrule - \chordname{B}{Si} + \chordname{\chordnameB} \utab{B}{2:2100} \utab{B7}{2:0100} \utab{Bm}{2:2000} diff --git a/songbook_core/data/latex/crepbook.cls b/songbook_core/data/latex/crepbook.cls index 249fb419..3a9b67f9 100644 --- a/songbook_core/data/latex/crepbook.cls +++ b/songbook_core/data/latex/crepbook.cls @@ -84,6 +84,60 @@ \fi % Start + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Multilanguage management + +\AtBeginDocument{ + % Default names (english) + \newcommand{\songlistname}{Songs list} + \newcommand{\labelversionname}{version:} + \newcommand{\labeldatename}{date:} + \newcommand{\labelauthorname}{authors:} + \newcommand{\labelwebname}{web:} + \newcommand{\labelmailname}{mail:} + \newcommand{\originalsongname}{Original song:} + \newcommand{\introname}{intro} + \newcommand{\outroname}{outro} + \newcommand{\bridgename}{bridge} + \newcommand{\chorusname}{chorus} + \newcommand{\versename}{verse} + \newcommand{\soloname}{solo} + \newcommand{\patternname}{pattern} + \newcommand{\rythmname}{rythm} + \newcommand{\transpositionname}{transposition:} + \newcommand{\songindexname}{Songs Index} + \newcommand{\authorindexname}{Authors Index} + \newcommand{\chordlistname}{Chords list} + + \IfStrEq{\mainlanguage}{french}{ + % French names + \renewcommand{\songlistname}{Liste des chansons}{} + \renewcommand{\labelversionname}{version :} + \renewcommand{\labeldatename}{date :} + \renewcommand{\labelauthorname}{auteurs :} + \renewcommand{\labelwebname}{web :} + \renewcommand{\labelmailname}{mail :} + \renewcommand{\originalsongname}{Chanson originale :} + \renewcommand{\introname}{intro} + \renewcommand{\outroname}{outro} + \renewcommand{\bridgename}{pont} + \renewcommand{\chorusname}{refrain} + \renewcommand{\versename}{couplet} + \renewcommand{\soloname}{solo} + \renewcommand{\patternname}{motif} + \renewcommand{\rythmname}{rythme} + \renewcommand{\transpositionname}{transposition :} + \renewcommand{\songindexname}{Index des chansons} + \renewcommand{\authorindexname}{Index des auteurs} + \renewcommand{\chordlistname}{Liste des accords} + }{} +} + +% End of multilanguage management +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \def\andname{and} \def\lastandname{\unskip, and} @@ -111,30 +165,9 @@ \def\picture#1{\gdef\@picture{#1}} \def\picturecopyright#1{\gdef\@picturecopyright{#1}} \def\footer#1{\gdef\@footer{#1}} -\def\lang#1{\gdef\@lang{#1}} +\def\lang#1{\gdef\mainlanguage{#1}} \clearheadinfo -\newcommand{\l@belVersion}{ - \IfStrEq{\@lang}{english}{\bf version:}{} - \IfStrEq{\@lang}{french}{\bf version :}{} -} -\newcommand{\l@belDate}{ - \IfStrEq{\@lang}{english}{\bf date:}{} - \IfStrEq{\@lang}{french}{\bf date :}{} -} -\newcommand{\l@belAuthor}{ - \IfStrEq{\@lang}{english}{\bf authors:}{} - \IfStrEq{\@lang}{french}{\bf auteurs :}{} -} -\newcommand{\l@belWeb}{ - \IfStrEq{\@lang}{english}{\bf web:}{} - \IfStrEq{\@lang}{french}{\bf web :}{} -} -\newcommand{\l@belMail}{ - \IfStrEq{\@lang}{english}{\bf mail:}{} - \IfStrEq{\@lang}{french}{\bf mail :}{} -} - \renewcommand\maketitle{ \@maketitle @@ -172,11 +205,11 @@ \begin{flushleft} \begin{tabular}{l l} - \if!\@version!\else{\l@belVersion} & \@version \\ \fi - \if!\@date!\else{\l@belDate} & \@date \\ \fi - \if!\@author!\else{\l@belAuthor} & \@author \\ \fi - \if!\@web!\else{\l@belWeb} & \url{\@web} \\ \fi - \if!\@mail!\else{\l@belMail} & \url{\@mail} \\ \fi + \if!\@version!\else{\textbf{\labelversionname}} & \@version \\ \fi + \if!\@date!\else{\textbf{\labeldatename}} & \@date \\ \fi + \if!\@author!\else{\textbf{\labelauthorname}} & \@author \\ \fi + \if!\@web!\else{\textbf{\labelwebname}} & \url{\@web} \\ \fi + \if!\@mail!\else{\textbf{\labelmailname}} & \url{\@mail} \\ \fi \end{tabular} \end{flushleft} @@ -194,8 +227,6 @@ \thispagestyle{empty} } -\makeatletter - \newlength{\coverheight} \setlength{\coverheight}{2cm} \newlength{\coverspace} @@ -229,7 +260,7 @@ \renewcommand{\extendpostlude}{ {\footnotesize% \IfStrEq{\songoriginal}{}{}{ - \IfStrEq{\@lang}{english}{Original song:}{Chanson originale :} + \originalsongname \songoriginal } } @@ -446,36 +477,28 @@ %% End of tabs.sty file \newcommand*{\Intro}{% - \IfStrEq{\@lang}{english}{intro}{}% - \IfStrEq{\@lang}{french}{intro}{}% + \introname% }% \newcommand*{\Outro}{% - \IfStrEq{\@lang}{english}{outro}{}% - \IfStrEq{\@lang}{french}{outro}{}% + \outroname% }% \newcommand*{\Bridge}{% - \IfStrEq{\@lang}{english}{bridge}{}% - \IfStrEq{\@lang}{french}{pont}{}% + \bridgename% }% \newcommand*{\Chorus}{% - \IfStrEq{\@lang}{english}{chorus}{}% - \IfStrEq{\@lang}{french}{refrain}{}% + \chorusname% }% \newcommand*{\Verse}{% - \IfStrEq{\@lang}{english}{verse}{}% - \IfStrEq{\@lang}{french}{couplet}{}% + \versename% }% \newcommand*{\Solo}{% - \IfStrEq{\@lang}{english}{solo}{}% - \IfStrEq{\@lang}{french}{solo}{}% + \soloname% }% \newcommand*{\Pattern}{% - \IfStrEq{\@lang}{english}{pattern}{}% - \IfStrEq{\@lang}{french}{motif}{}% + \patternname% }% \newcommand*{\Rythm}{% - \IfStrEq{\@lang}{english}{rythm}{}% - \IfStrEq{\@lang}{french}{rythme}{}% + \rythmname% }% \newcommand*{\Adlib}{% \emph{ad~lib.}% @@ -485,7 +508,7 @@ \renewcommand{\musicnote}[2][]{% \vspace{.1cm} \IfStrEq{}{#1}{\musicnoteORIG{#2}}{ - \IfStrEq{\@lang}{#1}{\musicnoteORIG{#2}}{} + \iflanguage{#1}{\musicnoteORIG{#2}}{} } } @@ -493,7 +516,7 @@ \renewcommand{\textnote}[2][]{% \vspace{.1cm} \IfStrEq{}{#1}{\textnoteORIG{#2}}{ - \IfStrEq{\@lang}{#1}{\textnoteORIG{#2}}{} + \iflanguage{#1}{\textnoteORIG{#2}}{} } } @@ -559,8 +582,7 @@ \newcommand{\transposition}[1]{% \ifnorepeatchords% \musicnote{% - \IfStrEq{\@lang}{english}{transposition:~}{}% - \IfStrEq{\@lang}{french}{transposition~:~}{}% + \transpositionname~ \ifthenelse{#1>0}{#1$\Uparrow$}{\removefirstch@r#1$\Downarrow$}% }% \else% diff --git a/songbook_core/data/templates/default.tex b/songbook_core/data/templates/default.tex index 73d9399e..5d19dda0 100644 --- a/songbook_core/data/templates/default.tex +++ b/songbook_core/data/templates/default.tex @@ -1,47 +1,36 @@ -(% comment %) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Template parameters -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%:[ -%%: {"name":"title", "description":"Title", "default":"Recueil de chansons pour guitare", "mandatory":true}, -%%: {"name":"author", "description":"Author", "default":"The Songbook Team", "mandatory":true}, -%%: {"name":"booktype", "description":"Type", "type":"enum", "values":["chorded","lyric"], "default":"chorded", "mandatory":true}, -%%: {"name":"lang", "description":"Language", "default":"english"}, -%%: {"name":"instruments", "description":"Instruments", "type":"flag", "values":["guitar","ukulele"], "join":",", "mandatory":true, "default":["guitar"]}, -%%: {"name":"bookoptions", "description":"Options", "type":"flag", "values":["diagram","importantdiagramonly","lilypond","pictures","tabs","repeatchords","onesongperpage"], "join":",", "mandatory":true, "default":["diagram","pictures"]}, -%%: {"name":"version", "description":"Version", "default":"unknown"}, -%%: {"name":"subtitle", "description":"Subtitle"}, -%%: {"name":"web", "description":"Web", "default":"http://www.patacrep.com"}, -%%: {"name":"mail", "description":"Email", "default":"crep@team-on-fire.com"}, -%%: {"name":"picture", "description":"Picture", "type":"file", "default":"treble_a"}, -%%: {"name":"picturecopyright", "description":"Copyright", "default":"Dbolton \\url{http://commons.wikimedia.org/wiki/User:Dbolton}"}, -%%: {"name":"footer", "description":"Footer", "default":"\\begin{flushright}Generated using Songbook (\\url{http://www.patacrep.com})\\end{flushright}"}, -%%: {"name":"mainfontsize", "description":"Font Size", "type":"font", "default":"10"}, -%%: {"name":"songnumberbgcolor", "description":"Number Shade", "type":"color", "default":"D1E4AE"}, -%%: {"name":"notebgcolor", "description":"Note Shade", "type":"color", "default":"D1E4AE"}, -%%: {"name":"indexbgcolor", "description":"Index Shade", "type":"color", "default":"D1E4AE"}, -%%: {"name":"titleprefixwords", "description":"Ignore some words in the beginning of song titles"}, -%%: {"name":"authwords", "descriptipn":"Set of options to process author string (LaTeX commands authsepword, authignoreword, authbyword)"}, -%%: {"name":"languages", "description":"List of languages used by songs", "default":"english"} -%%:] -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -(% endcomment %) +(% variables %) +[ +{"name":"title", "description":"Title", "default":"Recueil de chansons pour guitare", "mandatory":true}, +{"name":"author", "description":"Author", "default":"The Songbook Team", "mandatory":true}, +{"name":"booktype", "description":"Type", "type":"enum", "values":["chorded","lyric"], "default":"chorded", "mandatory":true}, +{"name":"lang", "description":"Language", "default":"english"}, +{"name":"instruments", "description":"Instruments", "type":"flag", "values":["guitar","ukulele"], "join":",", "mandatory":true, "default":["guitar"]}, +{"name":"bookoptions", "description":"Options", "type":"flag", "values":["diagram","importantdiagramonly","lilypond","pictures","tabs","repeatchords","onesongperpage"], "join":",", "mandatory":true, "default":["diagram","pictures"]}, +{"name":"version", "description":"Version", "default":"unknown"}, +{"name":"subtitle", "description":"Subtitle"}, +{"name":"web", "description":"Web", "default":"http://www.patacrep.com"}, +{"name":"mail", "description":"Email", "default":"crep@team-on-fire.com"}, +{"name":"picture", "description":"Picture", "type":"file", "default":"treble_a"}, +{"name":"picturecopyright", "description":"Copyright", "default":"Dbolton \\url{http://commons.wikimedia.org/wiki/User:Dbolton}"}, +{"name":"footer", "description":"Footer", "default":"\\begin{flushright}Generated using Songbook (\\url{http://www.patacrep.com})\\end{flushright}"}, +{"name":"mainfontsize", "description":"Font Size", "type":"font", "default":"10"}, +{"name":"songnumberbgcolor", "description":"Number Shade", "type":"color", "default":"D1E4AE"}, +{"name":"notebgcolor", "description":"Note Shade", "type":"color", "default":"D1E4AE"}, +{"name":"indexbgcolor", "description":"Index Shade", "type":"color", "default":"D1E4AE"}, +{"name":"titleprefixwords", "description":"Ignore some words in the beginning of song titles"}, +{"name":"authwords", "descriptipn":"Set of options to process author string (LaTeX commands authsepword, authignoreword, authbyword)"}, +{"name":"languages", "description":"List of languages used by songs", "default":"english"} +] +(% endvariables %) -(* extends "layout.tex" *) +(* extends "songs.tex" *) +(* set indexes = "titleidx,authidx" *) + +(* block songbookpreambule *) + (( super() )) -(* block extrapackages *) - \usepackage[ - a4paper % paper size - ,includeheadfoot % include header and footer into text size - ,hmarginratio=1:1 % ratio between inner and outer margin (default) - ,outer=1.8cm % outer margin (right) - ,vmarginratio=1:1 % ratio between top and bottom margin - ,bmargin=1.3cm % bottom margin - ]{geometry} \usepackage{chords} -(* endblock extrapackages *) -(* block songbookpreambule *) \title{((title))} \author{((author))} \subtitle{((subtitle))} @@ -53,7 +42,6 @@ \picture{((picture))} \picturecopyright{((picturecopyright))} \footer{((footer))} - \lang{((mainlang))} \newindex{titleidx}{((filename))_title} \newauthorindex{authidx}{((filename))_auth} @@ -70,28 +58,16 @@ (* endif *) (* endfor *) (* endfor*) +(* endblock *) - \graphicspath{{((datadir))/img/}} - \pagestyle{empty} - - \definecolor{SongNumberBgColor}{HTML}{((songnumberbgcolor))} - \definecolor{NoteBgColor}{HTML}{((notebgcolor))} - \definecolor{IndexBgColor}{HTML}{((indexbgcolor))} - - \renewcommand{\snumbgcolor}{SongNumberBgColor} - \renewcommand{\notebgcolor}{NoteBgColor} - \renewcommand{\idxbgcolor}{IndexBgColor} +(* block title *) +\maketitle (* endblock *) (* block index *) - (* if mainlang==english *) - \showindex{Songs Index}{titleidx} - \showindex{Authors Index}{authidx} - (* else *) - \showindex{Index des chansons}{titleidx} - \showindex{Index des auteurs}{authidx} - (* endif *) - (* if mainlang==french *) + \showindex{\songindexname}{titleidx} + \showindex{\authorindexname}{authidx} + (* if lang==french *) \notenamesin{A}{B}{C}{D}{E}{F}{G} \notenamesout{La}{Si}{Do}{Ré}{Mi}{Fa}{Sol} (* endif *) @@ -101,26 +77,8 @@ % list of chords \ifchorded \phantomsection - (* if mainlang==english *) - \addcontentsline{toc}{section}{Chords list} - (* else *) - \addcontentsline{toc}{section}{Liste des accords} - (* endif *) + \addcontentsline{toc}{section}{\chordlistname} \chords \fi (* endblock *) -(* block content *) - \phantomsection - (* if mainlang==english *) - \addcontentsline{toc}{section}{Songs list} - (* else *) - \addcontentsline{toc}{section}{Liste des chansons} - (* endif *) - - \begin{songs}{titleidx,authidx} - (* for song in songlist.songs *) - \input{((song.path))} - (* endfor *) - \end{songs} -(* endblock *) diff --git a/songbook_core/data/templates/layout.tex b/songbook_core/data/templates/layout.tex index 112fa233..5b0fd76a 100644 --- a/songbook_core/data/templates/layout.tex +++ b/songbook_core/data/templates/layout.tex @@ -23,27 +23,19 @@ % Copyright (C) 2014 The Songbook team (www.patacrep.com) +(* block documentclass *) \documentclass[((booktype)), (* for option in bookoptions *)((option)), (* endfor *) (* for instrument in instruments *)((instrument)), (* endfor *) ((mainfontsize))pt]{crepbook} +(* endblock *) -(* block packages *) +(* block songbookpreambule *) \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage{lmodern} - (* for lang in songlist.languages() *) - \PassOptionsToPackage{((lang))}{babel} - (* endfor *) - \usepackage{babel} - - (* block extrapackages *) - (* endblock extrapackages *) -(* endblock packages *) - -(* block songbookpreambule *) (* endblock songbookpreambule *) (* block preambule *) @@ -52,7 +44,6 @@ \begin{document} (* block title *) -\maketitle (* endblock *) (* block preface *) @@ -64,7 +55,7 @@ (* block chords *) (* endblock *) -(* block content *) +(* block songs *) (* endblock *) (* block postface *) diff --git a/songbook_core/data/templates/patacrep.tex b/songbook_core/data/templates/patacrep.tex new file mode 100644 index 00000000..33723475 --- /dev/null +++ b/songbook_core/data/templates/patacrep.tex @@ -0,0 +1,53 @@ +(% comment %) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Template parameters +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%:[ +%%: {"name":"title", "description":"Title", "default":"Recueil de chansons pour guitare", "mandatory":true}, +%%: {"name":"author", "description":"Author", "default":"The Songbook Team", "mandatory":true}, +%%: {"name":"booktype", "description":"Type", "type":"enum", "values":["chorded","lyric"], "default":"chorded", "mandatory":true}, +%%: {"name":"lang", "description":"Language", "default":"english"}, +%%: {"name":"instruments", "description":"Instruments", "type":"flag", "values":["guitar","ukulele"], "join":",", "mandatory":true, "default":["guitar"]}, +%%: {"name":"bookoptions", "description":"Options", "type":"flag", "values":["diagram","importantdiagramonly","lilypond","pictures","tabs","repeatchords","onesongperpage"], "join":",", "mandatory":true, "default":["diagram","pictures"]}, +%%: {"name":"version", "description":"Version", "default":"unknown"}, +%%: {"name":"subtitle", "description":"Subtitle"}, +%%: {"name":"web", "description":"Web", "default":"http://www.patacrep.com"}, +%%: {"name":"mail", "description":"Email", "default":"crep@team-on-fire.com"}, +%%: {"name":"picture", "description":"Picture", "type":"file", "default":"treble_a"}, +%%: {"name":"picturecopyright", "description":"Copyright", "default":"Dbolton \\url{http://commons.wikimedia.org/wiki/User:Dbolton}"}, +%%: {"name":"footer", "description":"Footer", "default":"\\begin{flushright}Generated using Songbook (\\url{http://www.patacrep.com})\\end{flushright}"}, +%%: {"name":"mainfontsize", "description":"Font Size", "type":"font", "default":"10"}, +%%: {"name":"songnumberbgcolor", "description":"Number Shade", "type":"color", "default":"D1E4AE"}, +%%: {"name":"notebgcolor", "description":"Note Shade", "type":"color", "default":"D1E4AE"}, +%%: {"name":"indexbgcolor", "description":"Index Shade", "type":"color", "default":"D1E4AE"}, +%%: {"name":"titleprefixwords", "description":"Ignore some words in the beginning of song titles"}, +%%: {"name":"authwords", "descriptipn":"Set of options to process author string (LaTeX commands authsepword, authignoreword, authbyword)"}, +%%: {"name":"languages", "description":"List of languages used by songs", "default":"english"} +%%:] +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +(% endcomment %) + +(* extends "default.tex" *) + +(* block songbookpreambule *) + \usepackage[ + a4paper % paper size + ,includeheadfoot % include header and footer into text size + ,hmarginratio=1:1 % ratio between inner and outer margin (default) + ,outer=1.8cm % outer margin (right) + ,vmarginratio=1:1 % ratio between top and bottom margin + ,bmargin=1.3cm % bottom margin + ]{geometry} + + (( super() )) + + \pagestyle{empty} + + \definecolor{SongNumberBgColor}{HTML}{((songnumberbgcolor))} + \definecolor{NoteBgColor}{HTML}{((notebgcolor))} + \definecolor{IndexBgColor}{HTML}{((indexbgcolor))} + + \renewcommand{\snumbgcolor}{SongNumberBgColor} + \renewcommand{\notebgcolor}{NoteBgColor} + \renewcommand{\idxbgcolor}{IndexBgColor} +(* endblock *) diff --git a/songbook_core/data/templates/songs.tex b/songbook_core/data/templates/songs.tex new file mode 100644 index 00000000..0095ad5d --- /dev/null +++ b/songbook_core/data/templates/songs.tex @@ -0,0 +1,25 @@ +(* extends "layout.tex" *) + +(* block songbookpreambule *) + (( super() )) + + + (* for lang in songlist.languages() *) + \PassOptionsToPackage{((lang))}{babel} + (* endfor *) + \usepackage[((lang))]{babel} + \lang{((lang))} + + \graphicspath{{((datadir))/img/}} +(* endblock *) + +(* block songs *) + \phantomsection + \addcontentsline{toc}{section}{\songlistname} + + \begin{songs}{((indexes|default('')))} + (* for song in songlist.songs *) + \input{((song.path))} + (* endfor *) + \end{songs} +(* endblock *) diff --git a/songbook_core/plastex.py b/songbook_core/plastex.py index 6b921d0b..3affc7bd 100644 --- a/songbook_core/plastex.py +++ b/songbook_core/plastex.py @@ -17,6 +17,13 @@ def process_unbr_spaces(node): will be rendered as unbreakable space. Return node object for convenience. + + This function is a workaround to a bug that has been solved since: + - https://github.com/tiarno/plastex/commit/76bb78d5fbaac48e68025a3545286cc63cb4e7ad + - https://github.com/tiarno/plastex/commit/682a0d223b99d6b949bacf1c974d24dc9bb1d18e + + It can be deleted once this bug has been merged in production version of + PlasTeX. """ if (type(node) == Sentences.InterWordSpace or (type(node) == Sentences.NoLineBreak and node.source == '~ ')): @@ -74,7 +81,8 @@ def parsetex(filename): """ # /* BEGIN plasTeX patch # The following lines, and another line a few lines later, are used to - # circumvent a plasTeX bug. It has been reported, with a patch. + # circumvent a plasTeX bug. It has been reported and corrected : + # https://github.com/tiarno/plastex/commit/8f4e5a385f3cb6a04d5863f731ce24a7e856f2a4 # To see if you can delete those lines, set your LC_TIME locale to French, # during a month containing diacritics (e.g. Février), and run songbook. If # no plasTeX bug appears, it is safe to remove those lines. diff --git a/songbook_core/plastex_patchedbabel.py b/songbook_core/plastex_patchedbabel.py index 2f3b159a..39aa2e8f 100644 --- a/songbook_core/plastex_patchedbabel.py +++ b/songbook_core/plastex_patchedbabel.py @@ -11,8 +11,9 @@ en production. En attendant, nous utilisons cette version modifiée. Dés que la correction sera entrée en production, il faudra supprimer ce fichier, et remplater l'occurence à "patchedbabel" par "babel" dans le fichier "plastex.py". -La correction à suveiller est la révision 1.3 du fichier babel.py : -http://plastex.cvs.sourceforge.net/viewvc/plastex/plastex/plasTeX/Packages/babel.py?view=log +La correction à suveiller est la révision +41a48c0c229dd46b69fb0e3720595000a71b17d8 du fichier babel.py : +https://github.com/tiarno/plastex/commit/41a48c0c229dd46b69fb0e3720595000a71b17d8 # Comment vérifier si on peut supprimer ce fichier ? diff --git a/songbook_core/templates.py b/songbook_core/templates.py index 94107cb1..9cc10280 100644 --- a/songbook_core/templates.py +++ b/songbook_core/templates.py @@ -3,8 +3,10 @@ """Template for .tex generation settings and utilities""" from jinja2 import Environment, FileSystemLoader, ChoiceLoader, PackageLoader +from jinja2.meta import find_referenced_templates as find_templates import os import re +import json _LATEX_SUBS = ( (re.compile(r'\\'), r'\\textbackslash'), @@ -23,6 +25,7 @@ def _escape_tex(value): newval = pattern.sub(replacement, newval) return newval + class TexRenderer(object): """Render a template to a LaTeX file.""" @@ -32,8 +35,6 @@ class TexRenderer(object): Arguments: - datadir: location of the user-defined templates ''' - self.template = template - self.texenv = Environment( loader=ChoiceLoader([ FileSystemLoader( @@ -42,31 +43,69 @@ class TexRenderer(object): PackageLoader( 'songbook_core', os.path.join('data', 'templates') ), - ]) + ]), ) self.texenv.block_start_string = '(*' self.texenv.block_end_string = '*)' self.texenv.variable_start_string = '((' self.texenv.variable_end_string = '))' - self.texenv.comment_start_string = '(% comment %)' - self.texenv.comment_end_string = '(% endcomment %)' + self.texenv.comment_start_string = '(% variables %)' + self.texenv.comment_end_string = '(% endvariables %)' + self.texenv.line_comment_prefix = '(%%)' self.texenv.filters['escape_tex'] = _escape_tex self.texenv.trim_blocks = True self.texenv.lstrip_blocks = True - def file_template(self): - """Return the filename of the selected template.""" - return self.texenv.get_template(self.template).filename + # TODO: catch the TemplateNotFound + self.template = self.texenv.get_template(template) + + def get_variables(self): + data = self.parse_templates() + variables = dict() + for param in data: + try: + variables[param["name"]] = param["default"] + except KeyError: + variables[param["name"]] = None + return variables + + def parse_templates(self): + templates = self.get_templates(self.template) + templates |= set([self.template.name]) + variables = [] + regex = re.compile(r'\(% variables %\)(?P.*)' + '\(% endvariables %\)', re.DOTALL) + for template_name in templates: + filename = self.texenv.get_template(template_name).filename + with open(filename, 'r') as template_file: + content = template_file.read() + match = re.search(regex, content) + if match: + content = match.group('variables') + variables += json.loads(content) + return variables + + def get_templates(self, template): + '''Recursively get a set of all the templates used + by a particular template. + ''' + with open(template.filename, 'r') as template_file: + content = template_file.readlines() + new_templates = list(find_templates(self.texenv.parse(content))) + all_templates = set(new_templates) + if len(new_templates) > 0: + for new_template_name in new_templates: + new_template = self.texenv.get_template(new_template_name) + # union of the sets + all_templates |= self.get_templates(new_template) + return all_templates def render_tex(self, output, context): '''Render a template into a .tex file Arguments: - output: a file object to write the result - - context: all the data to populate the template + - context: a dict of all the data to populate the template ''' - #pylint: disable=star-args - output.write( - self.texenv.get_template(self.template).render(**context) - ) + output.write(self.template.render(context))