Browse Source

Merge branch 'master' of github.com:patacrep/patacrep

pull/211/head
Louis 9 years ago
parent
commit
4cea64f214
  1. 2
      patacrep/content/__init__.py
  2. 22
      patacrep/content/addsongdir.py
  3. 36
      patacrep/content/cd.py
  4. 19
      patacrep/content/include.py
  5. 48
      patacrep/content/setcounter.py
  6. 1
      patacrep/content/tex.py
  7. 17
      patacrep/data/latex/patacrep.sty
  8. 2
      patacrep/templates.py
  9. 2
      test/test_content/cwd.source
  10. 2
      test/test_content/cwd_list.source
  11. 4
      test/test_content/setcounter.control
  12. 7
      test/test_content/setcounter.source
  13. 2
      test/test_content/sort.source
  14. 17
      test/test_content/test_content.py
  15. 3
      test/test_songbook/content.tex.control
  16. 7
      test/test_songbook/content.yaml
  17. 4
      test/test_songbook/onthefly/content.onthefly.yaml

2
patacrep/content/__init__.py

@ -21,7 +21,7 @@ met, the corresponding parser is called.
- sort - sort
- section* - section*
- cwd - cd
# Parsers # Parsers

22
patacrep/content/cwd.py → patacrep/content/addsongdir.py

@ -1,4 +1,4 @@
"""Change base directory before importing songs.""" """Add a path directory to the 'songdir' list."""
from patacrep.content import process_content, validate_parser_argument from patacrep.content import process_content, validate_parser_argument
from patacrep.songs import DataSubpath from patacrep.songs import DataSubpath
@ -6,39 +6,35 @@ from patacrep.songs import DataSubpath
#pylint: disable=unused-argument #pylint: disable=unused-argument
@validate_parser_argument(""" @validate_parser_argument("""
type: //rec type: //rec
required:
path: //str
optional: optional:
content: //any content: //any
required:
path: //str
""") """)
def parse(keyword, config, argument): def parse(keyword, config, argument):
"""Return a list songs, whith a different base path. """Return a list of songs, whith an another base path.
Arguments: Arguments:
- keyword: unused; - keyword: unused;
- config: the current songbook configuration dictionary; - config: the current songbook configuration dictionary;
- argument: a dict containing: - argument: a dict containing:
path: string specifying the path to use as root; path: string specifying the path to add to the songdirs list;
content: songbook content, that is parsed by content: songbook content, that is parsed by
patacrep.content.process_content(). patacrep.content.process_content().
This function adds 'path' to the directories where songs are searched This function adds 'path' to the directories where songs are searched
for, and then processes the content. for, and then processes the content.
The 'path' is added: The 'path' is added as a relative path to the dir of the songbook file.
- first as a relative path to the *.yaml file directory;
- then as a relative path to every path already present in
config['songdir'] (which are 'song' dir inside the datadirs).
""" """
subpath = argument['path'] subpath = argument['path']
old_songdir = config['_songdir'] old_songdir = config['_songdir']
config['_songdir'] = [path.clone().join(subpath) for path in config['_songdir']] config['_songdir'] = [DataSubpath(config['_songbookfile_dir'], subpath)]
if '_songbookfile_dir' in config: config['_songdir'].extend(old_songdir)
config['_songdir'].insert(0, DataSubpath(config['_songbookfile_dir'], subpath))
processed_content = process_content(argument.get('content'), config) processed_content = process_content(argument.get('content'), config)
config['_songdir'] = old_songdir config['_songdir'] = old_songdir
return processed_content return processed_content
CONTENT_PLUGINS = {'cwd': parse} CONTENT_PLUGINS = {'addsongdir': parse}

36
patacrep/content/cd.py

@ -0,0 +1,36 @@
"""Change base directory before importing songs."""
from patacrep.content import process_content, validate_parser_argument
#pylint: disable=unused-argument
@validate_parser_argument("""
type: //rec
required:
path: //str
optional:
content: //any
""")
def parse(keyword, config, argument):
"""Return a list of songs, whith a different base path.
Arguments:
- keyword: unused;
- config: the current songbook configuration dictionary;
- argument: a dict containing:
path: string specifying the path to append to current songdirs;
content: songbook content, that is parsed by
patacrep.content.process_content().
The 'path' is added as a relative path to every path already present
in config['songdir'] (which are 'songs' dir inside the datadirs).
"""
subpath = argument['path']
old_songdir = config['_songdir']
config['_songdir'] = [path.clone().join(subpath) for path in config['_songdir']]
processed_content = process_content(argument.get('content'), config)
config['_songdir'] = old_songdir
return processed_content
CONTENT_PLUGINS = {'cd': parse}

19
patacrep/content/include.py

@ -10,22 +10,23 @@ import logging
import yaml import yaml
from patacrep.content import process_content, ContentError, ContentList, validate_parser_argument from patacrep.content import process_content, ContentError, ContentList, validate_parser_argument
from patacrep import encoding, errors, files from patacrep import encoding, errors
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
def load_from_datadirs(path, datadirs): def load_from_datadirs(filename, songdirs):
"""Load 'path' from one of the datadirs. """Load 'filename' from one of the songdirs.
Raise an exception if it was found if none of the datadirs of 'config'. Raise an exception if it was not found in any songdir.
""" """
for filepath in files.iter_datadirs(datadirs, "songs", path): for path in songdirs:
if os.path.exists(filepath): fullpath = os.path.join(path.fullpath, filename)
return filepath if os.path.exists(fullpath):
return fullpath
# File not found # File not found
raise ContentError( raise ContentError(
"include", "include",
errors.notfound(path, list(files.iter_datadirs(datadirs))) errors.notfound(filename, list(songdirs))
) )
#pylint: disable=unused-argument #pylint: disable=unused-argument
@ -53,7 +54,7 @@ def parse(keyword, config, argument):
for path in argument: for path in argument:
try: try:
filepath = load_from_datadirs(path, config['_datadir']) filepath = load_from_datadirs(path, config['_songdir'])
except ContentError as error: except ContentError as error:
new_contentlist.append_error(error) new_contentlist.append_error(error)
continue continue

48
patacrep/content/setcounter.py

@ -0,0 +1,48 @@
"""Allows to set an arbitrary value to any LaTeX counter (like `songnum`)."""
from patacrep.content import ContentItem, ContentList, validate_parser_argument
class CounterSetter(ContentItem):
"""Set a counter."""
# pylint: disable=too-few-public-methods
def __init__(self, name, value):
self.name = name
self.value = value
def render(self, __context):
"""Set the value of the counter."""
return r'\setcounter{{{}}}{{{}}}'.format(self.name, self.value)
#pylint: disable=unused-argument
@validate_parser_argument("""
type: //any
of:
- //nil
- //int
- type: //rec
optional:
name: //str
value: //int
""")
def parse(keyword, argument, config):
"""Parse the counter setter.
Arguments:
- nothing
reset the "songnum" counter to 1
- an int
reset the "songnum" counter to this value
- a dict:
- name ("songnum"): the counter to set;
- value: value to set the counter to;
"""
if argument is None:
argument = {}
if isinstance(argument, int):
argument = {'value': argument}
name = argument.get('name', 'songnum')
value = argument.get('value', 1)
return ContentList([CounterSetter(name, value)])
CONTENT_PLUGINS = {'setcounter': parse}

1
patacrep/content/tex.py

@ -45,7 +45,6 @@ def parse(keyword, argument, config):
filelist = ContentList() filelist = ContentList()
basefolders = itertools.chain( basefolders = itertools.chain(
(path.fullpath for path in config['_songdir']), (path.fullpath for path in config['_songdir']),
files.iter_datadirs(config['_datadir']),
files.iter_datadirs(config['_datadir'], 'latex'), files.iter_datadirs(config['_datadir'], 'latex'),
) )
for filename in argument: for filename in argument:

17
patacrep/data/latex/patacrep.sty

@ -443,4 +443,21 @@
\def\@void[#1]{} \def\@void[#1]{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Prevent numbering reset on new 'songs' environment
\newcounter{tempsongnum}
\let\oldsongs\songs
\let\endoldsongs\endsongs
\renewenvironment{songs}[1]{%
\setcounter{tempsongnum}{\thesongnum}%
\oldsongs{#1}%
\setcounter{songnum}{\thetempsongnum}%
}{%
\endoldsongs\ignorespacesafterend%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\endinput \endinput

2
patacrep/templates.py

@ -275,7 +275,7 @@ def iter_bookoptions(config):
if config['chords']['show']: if config['chords']['show']:
yield 'chorded' yield 'chorded'
else: else:
yield 'lyrics' yield 'lyric'
book_equivalents = { book_equivalents = {
'pictures': 'pictures', 'pictures': 'pictures',

2
test/test_content/cwd.source

@ -1,3 +1,3 @@
- cwd: - cd:
path: subdir path: subdir
content: content:

2
test/test_content/cwd_list.source

@ -1,4 +1,4 @@
- cwd: - cd:
path: subdir path: subdir
content: content:
- "exsong.sg" - "exsong.sg"

4
test/test_content/setcounter.control

@ -0,0 +1,4 @@
- setcounter{songnum}{101}
- setcounter{songnum}{1}
- setcounter{songnum}{5}
- setcounter{counter_name}{-1}

7
test/test_content/setcounter.source

@ -0,0 +1,7 @@
- setcounter:
value: 101
- setcounter:
- setcounter: 5
- setcounter:
name: counter_name
value: -1

2
test/test_content/sort.source

@ -1,4 +1,4 @@
- cwd: - addsongdir:
path: "datadir_sort" path: "datadir_sort"
content: content:
- section: - section:

17
test/test_content/test_content.py

@ -10,7 +10,7 @@ import yaml
from pkg_resources import resource_filename from pkg_resources import resource_filename
from patacrep import content, files from patacrep import content, files
from patacrep.content import song, section, songsection, tex from patacrep.content import song, section, setcounter, songsection, tex
from patacrep.songbook import prepare_songbook from patacrep.songbook import prepare_songbook
from .. import logging_reduced from .. import logging_reduced
@ -76,15 +76,18 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest):
@classmethod @classmethod
def _clean_path(cls, elem): def _clean_path(cls, elem):
"""Shorten the path relative to the `songs` directory""" """Shorten the path relative to the `songs` directory"""
if isinstance(elem, song.SongRenderer):
songpath = os.path.join(os.path.dirname(__file__), 'datadir', 'songs')
return files.path2posix(files.relpath(elem.song.fullpath, songpath))
elif isinstance(elem, section.Section): latex_command_classes = (
section.Section,
songsection.SongSection,
setcounter.CounterSetter,
)
if isinstance(elem, latex_command_classes):
return elem.render(None)[1:] return elem.render(None)[1:]
elif isinstance(elem, songsection.SongSection): elif isinstance(elem, song.SongRenderer):
return elem.render(None)[1:] songpath = os.path.join(os.path.dirname(__file__), 'datadir', 'songs')
return files.path2posix(files.relpath(elem.song.fullpath, songpath))
elif isinstance(elem, tex.LaTeX): elif isinstance(elem, tex.LaTeX):
return files.path2posix(elem.filename) return files.path2posix(elem.filename)

3
test/test_songbook/content.tex.control

@ -122,6 +122,9 @@ guitar,
\songsection{Test of song section} \songsection{Test of song section}
\setcounter{songnum}{101}
\begin{songs}{titleidx,authidx} \begin{songs}{titleidx,authidx}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% content_datadir/content/song.csg %% content_datadir/content/song.csg

7
test/test_songbook/content.yaml

@ -11,14 +11,15 @@ content:
- section: Test of section - section: Test of section
- sort: - sort:
- songsection: Test of song section - songsection: Test of song section
- cwd: - setcounter: 101
- addsongdir:
# relative to yaml songfile # relative to yaml songfile
path: content_datadir/content path: content_datadir/content
content: content:
- "song.csg" - "song.csg"
- "song.tsg" - "song.tsg"
- cwd: - cd:
# relative to datadir # relative to datadir 'songs' dir
path: ../content path: ../content
content: content:
- tex: foo.tex - tex: foo.tex

4
test/test_songbook/onthefly/content.onthefly.yaml

@ -11,8 +11,8 @@ content:
- section: Test of section - section: Test of section
- sort: - sort:
- songsection: Test of song section - songsection: Test of song section
- cwd: - cd:
# relative to datadir 'song' dir # relative to datadir 'songs' dir
path: ../content path: ../content
content: content:
- tex: foo.tex - tex: foo.tex

Loading…
Cancel
Save