mirror of https://github.com/patacrep/patacrep.git
Louis
9 years ago
106 changed files with 2699 additions and 807 deletions
@ -1,3 +1,3 @@ |
|||||
Run the following command to build an example song book. |
Run the following command to build an example song book. |
||||
|
|
||||
$ songbook example.sb |
$ songbook example.yaml |
||||
|
@ -1,19 +0,0 @@ |
|||||
{ |
|
||||
"bookoptions" : [ |
|
||||
"diagram", |
|
||||
"repeatchords", |
|
||||
"lilypond", |
|
||||
"pictures" |
|
||||
], |
|
||||
"booktype" : "chorded", |
|
||||
"datadir": ["datadir2"], |
|
||||
"template" : "patacrep.tex", |
|
||||
"lang" : "fr", |
|
||||
"encoding": "utf8", |
|
||||
"authwords" : { |
|
||||
"sep" : ["and", "et"] |
|
||||
}, |
|
||||
"datadir" : ".", |
|
||||
"content": [["sorted"]] |
|
||||
|
|
||||
} |
|
@ -0,0 +1,27 @@ |
|||||
|
book: |
||||
|
lang: fr |
||||
|
encoding: utf8 |
||||
|
template: patacrep.tex |
||||
|
datadir: "." |
||||
|
pictures: yes |
||||
|
chords: |
||||
|
show: yes |
||||
|
diagramreminder: all |
||||
|
repeatchords: yes |
||||
|
|
||||
|
authors: |
||||
|
separators: |
||||
|
- "and" |
||||
|
- "et" |
||||
|
content: |
||||
|
- sort: |
||||
|
|
||||
|
template: |
||||
|
patacrep.tex: |
||||
|
color: |
||||
|
songlink: FF0000 |
||||
|
hyperlink: 0000FF |
||||
|
bgcolor: |
||||
|
note: D1E4AE |
||||
|
songnumber: AED1E4 |
||||
|
index: E4AED1 #not enough songs to see it |
@ -1,17 +0,0 @@ |
|||||
bookoptions: |
|
||||
- "diagram" |
|
||||
- "repeatchords" |
|
||||
- "lilypond" |
|
||||
- "pictures" |
|
||||
booktype: "chorded" |
|
||||
datadir: "." |
|
||||
template: "patacrep.tex" |
|
||||
lang: "fr" |
|
||||
encoding: "utf8" |
|
||||
authwords: |
|
||||
sep: |
|
||||
- "and" |
|
||||
- "et" |
|
||||
content: |
|
||||
- |
|
||||
- "sorted" |
|
@ -1,22 +0,0 @@ |
|||||
{ |
|
||||
"template" : "patacrep.tex", |
|
||||
"bookoptions" : [ |
|
||||
"importantdiagramonly", |
|
||||
"repeatchords", |
|
||||
"lilypond", |
|
||||
"pictures" |
|
||||
], |
|
||||
"booktype" : "chorded", |
|
||||
"lang" : "fr", |
|
||||
"authwords" : { |
|
||||
"sep" : ["and", "et"] |
|
||||
}, |
|
||||
"datadir" : ".", |
|
||||
"content" : [["section", "Traditional"], |
|
||||
"chevaliers_de_la_table_ronde.sg", |
|
||||
"greensleeves.sg", |
|
||||
"vent_frais.sg", |
|
||||
["section", "Example"], |
|
||||
"example-fr.sg", |
|
||||
"example-en.sg"] |
|
||||
} |
|
@ -0,0 +1,24 @@ |
|||||
|
book: |
||||
|
lang: fr |
||||
|
encoding: utf8 |
||||
|
template: patacrep.tex |
||||
|
datadir: "." |
||||
|
pictures: yes |
||||
|
chords: |
||||
|
show: yes |
||||
|
diagramreminder: important |
||||
|
repeatchords: yes |
||||
|
lilypond: yes |
||||
|
|
||||
|
authors: |
||||
|
separators: |
||||
|
- "and" |
||||
|
- "et" |
||||
|
content: |
||||
|
- section: "Traditional" |
||||
|
- "chevaliers_de_la_table_ronde.tsg" |
||||
|
- "greensleeves.csg" |
||||
|
- "vent_frais.tsg" |
||||
|
- section: Example |
||||
|
- "example-fr.tsg" |
||||
|
- "example-en.tsg" |
@ -1,22 +0,0 @@ |
|||||
{ |
|
||||
"template" : "layout.tex", |
|
||||
"bookoptions" : [ |
|
||||
"importantdiagramonly", |
|
||||
"repeatchords", |
|
||||
"lilypond", |
|
||||
"pictures" |
|
||||
], |
|
||||
"booktype" : "chorded", |
|
||||
"lang" : "fr", |
|
||||
"authwords" : { |
|
||||
"sep" : ["and", "et"] |
|
||||
}, |
|
||||
"datadir" : ".", |
|
||||
"content" : [["section", "Traditional"], |
|
||||
"chevaliers_de_la_table_ronde.sg", |
|
||||
"greensleeves.sg", |
|
||||
"vent_frais.sg", |
|
||||
["section", "Example"], |
|
||||
"example-fr.sg", |
|
||||
"example-en.sg"] |
|
||||
} |
|
@ -1,22 +0,0 @@ |
|||||
{ |
|
||||
"template" : "songs.tex", |
|
||||
"bookoptions" : [ |
|
||||
"importantdiagramonly", |
|
||||
"repeatchords", |
|
||||
"lilypond", |
|
||||
"pictures" |
|
||||
], |
|
||||
"booktype" : "chorded", |
|
||||
"lang" : "fr", |
|
||||
"authwords" : { |
|
||||
"sep" : ["and", "et"] |
|
||||
}, |
|
||||
"datadir" : ".", |
|
||||
"content" : [["section", "Traditional"], |
|
||||
"chevaliers_de_la_table_ronde.sg", |
|
||||
"greensleeves.sg", |
|
||||
"vent_frais.sg", |
|
||||
["section", "Example"], |
|
||||
"example-fr.sg", |
|
||||
"example-en.sg"] |
|
||||
} |
|
@ -0,0 +1,24 @@ |
|||||
|
book: |
||||
|
lang: fr |
||||
|
encoding: utf8 |
||||
|
template: songs.tex |
||||
|
datadir: "." |
||||
|
pictures: yes |
||||
|
chords: |
||||
|
show: yes |
||||
|
diagramreminder: important |
||||
|
repeatchords: yes |
||||
|
lilypond: yes |
||||
|
|
||||
|
authors: |
||||
|
separators: |
||||
|
- "and" |
||||
|
- "et" |
||||
|
content: |
||||
|
- section: "Traditional" |
||||
|
- "chevaliers_de_la_table_ronde.tsg" |
||||
|
- "greensleeves.csg" |
||||
|
- "vent_frais.tsg" |
||||
|
- section: Example |
||||
|
- "example-fr.tsg" |
||||
|
- "example-en.tsg" |
@ -1,14 +0,0 @@ |
|||||
{ |
|
||||
"bookoptions" : [ |
|
||||
"diagram", |
|
||||
"repeatchords", |
|
||||
"lilypond", |
|
||||
"pictures" |
|
||||
], |
|
||||
"lang": "ERROR", |
|
||||
"booktype" : "chorded", |
|
||||
"template" : "patacrep.tex", |
|
||||
"encoding": "utf8", |
|
||||
"content": ["tests/*.csg", "tests/*.tsg"] |
|
||||
|
|
||||
} |
|
@ -0,0 +1,14 @@ |
|||||
|
book: |
||||
|
lang: ERROR |
||||
|
encoding: utf8 |
||||
|
template: patacrep.tex |
||||
|
datadir: "." |
||||
|
pictures: yes |
||||
|
chords: |
||||
|
show: yes |
||||
|
diagramreminder: all |
||||
|
repeatchords: yes |
||||
|
|
||||
|
content: |
||||
|
- "tests/*.csg" |
||||
|
- "tests/*.tsg" |
@ -1,21 +0,0 @@ |
|||||
{ |
|
||||
"bookoptions" : [ |
|
||||
"importantdiagramonly", |
|
||||
"repeatchords", |
|
||||
"lilypond", |
|
||||
"pictures" |
|
||||
], |
|
||||
"booktype" : "chorded", |
|
||||
"lang" : "fr", |
|
||||
"authwords" : { |
|
||||
"sep" : ["and", "et"] |
|
||||
}, |
|
||||
"datadir" : ".", |
|
||||
"content" : [["section", "Traditional"], |
|
||||
"chevaliers_de_la_table_ronde.sg", |
|
||||
"greensleeves.sg", |
|
||||
"vent_frais.sg", |
|
||||
["section", "Example"], |
|
||||
"example-fr.sg", |
|
||||
"example-en.sg"] |
|
||||
} |
|
@ -0,0 +1,23 @@ |
|||||
|
book: |
||||
|
lang: fr |
||||
|
encoding: utf8 |
||||
|
datadir: "." |
||||
|
pictures: yes |
||||
|
chords: |
||||
|
show: yes |
||||
|
diagramreminder: important |
||||
|
repeatchords: yes |
||||
|
lilypond: yes |
||||
|
|
||||
|
authors: |
||||
|
separators: |
||||
|
- "and" |
||||
|
- "et" |
||||
|
content: |
||||
|
- section: "Traditional" |
||||
|
- "chevaliers_de_la_table_ronde.tsg" |
||||
|
- "greensleeves.csg" |
||||
|
- "vent_frais.tsg" |
||||
|
- section: Example |
||||
|
- "example-fr.tsg" |
||||
|
- "example-en.tsg" |
@ -1,24 +0,0 @@ |
|||||
{ |
|
||||
"bookoptions" : [ |
|
||||
"importantdiagramonly", |
|
||||
"repeatchords", |
|
||||
"lilypond", |
|
||||
"pictures" |
|
||||
], |
|
||||
"booktype" : "chorded", |
|
||||
"lang" : "fr", |
|
||||
"authwords" : { |
|
||||
"sep" : ["and", "et", "À"], |
|
||||
"ignore" : ["À"], |
|
||||
"after" : ["À"] |
|
||||
}, |
|
||||
"titleprefixwords": ["À"], |
|
||||
"datadir" : ".", |
|
||||
"content" : [["section", "Traditional"], |
|
||||
"chevaliers_de_la_table_ronde.sg", |
|
||||
"greensleeves.sg", |
|
||||
"vent_frais.sg", |
|
||||
["section", "Example"], |
|
||||
"example-fr.sg", |
|
||||
"example-en.sg"] |
|
||||
} |
|
@ -0,0 +1,32 @@ |
|||||
|
book: |
||||
|
lang: fr |
||||
|
encoding: utf8 |
||||
|
datadir: "." |
||||
|
pictures: yes |
||||
|
chords: |
||||
|
show: yes |
||||
|
diagramreminder: important |
||||
|
repeatchords: yes |
||||
|
lilypond: yes |
||||
|
|
||||
|
authors: |
||||
|
separators: |
||||
|
- "and" |
||||
|
- "et" |
||||
|
- "À" |
||||
|
ignore: |
||||
|
- "À" |
||||
|
after: |
||||
|
- "À" |
||||
|
|
||||
|
titles: # Comment sont analysés les titres |
||||
|
prefix: |
||||
|
- "À" |
||||
|
content: |
||||
|
- section: "Traditionàl" |
||||
|
- "chevaliers_de_la_table_ronde.tsg" |
||||
|
- "greensleeves.csg" |
||||
|
- "vent_frais.tsg" |
||||
|
- section: Exâmple |
||||
|
- "example-fr.tsg" |
||||
|
- "example-en.tsg" |
@ -0,0 +1,748 @@ |
|||||
|
# Downloaded from https://github.com/rjbs/rx |
||||
|
# The contents of the Rx repository are copyright (C) 2008, Ricardo SIGNES. |
||||
|
# They may be distributed under the terms of the |
||||
|
# GNU Public License (GPL) Version 2, June 1991 |
||||
|
|
||||
|
#pylint: skip-file |
||||
|
|
||||
|
import re |
||||
|
import types |
||||
|
from numbers import Number |
||||
|
|
||||
|
### Exception Classes -------------------------------------------------------- |
||||
|
|
||||
|
class SchemaError(Exception): |
||||
|
pass |
||||
|
|
||||
|
class SchemaMismatch(Exception): |
||||
|
|
||||
|
def __init__(self, message, schema, error=None): |
||||
|
Exception.__init__(self, message) |
||||
|
self.type = schema.subname() |
||||
|
self.error = error |
||||
|
|
||||
|
class TypeMismatch(SchemaMismatch): |
||||
|
|
||||
|
def __init__(self, schema, data): |
||||
|
message = 'must be of type {} (was {})'.format( |
||||
|
schema.subname(), |
||||
|
type(data).__name__ |
||||
|
) |
||||
|
|
||||
|
SchemaMismatch.__init__(self, message, schema, 'type') |
||||
|
self.expected_type = schema.subname() |
||||
|
self.value = type(data).__name__ |
||||
|
|
||||
|
|
||||
|
class ValueMismatch(SchemaMismatch): |
||||
|
|
||||
|
def __init__(self, schema, data): |
||||
|
|
||||
|
message = 'must equal {} (was {})'.format( |
||||
|
repr(schema.value), |
||||
|
repr(data) |
||||
|
) |
||||
|
|
||||
|
SchemaMismatch.__init__(self, message, schema, 'value') |
||||
|
self.expected_value = schema.value |
||||
|
self.value = data |
||||
|
|
||||
|
|
||||
|
|
||||
|
class RangeMismatch(SchemaMismatch): |
||||
|
|
||||
|
def __init__(self, schema, data): |
||||
|
|
||||
|
message = 'must be in range {} (was {})'.format( |
||||
|
schema.range, |
||||
|
data |
||||
|
) |
||||
|
|
||||
|
SchemaMismatch.__init__(self, message, schema, 'range') |
||||
|
self.range = schema.range |
||||
|
self.value = data |
||||
|
|
||||
|
|
||||
|
class LengthRangeMismatch(SchemaMismatch): |
||||
|
|
||||
|
def __init__(self, schema, data): |
||||
|
length_range = Range(schema.length) |
||||
|
|
||||
|
if not hasattr(length_range, 'min') and \ |
||||
|
not hasattr(length_range, 'min_ex'): |
||||
|
length_range.min = 0 |
||||
|
|
||||
|
message = 'length must be in range {} (was {})'.format( |
||||
|
length_range, |
||||
|
len(data) |
||||
|
) |
||||
|
|
||||
|
SchemaMismatch.__init__(self, message, schema, 'range') |
||||
|
self.range = schema.length |
||||
|
self.value = len(data) |
||||
|
|
||||
|
|
||||
|
class MissingFieldMismatch(SchemaMismatch): |
||||
|
|
||||
|
def __init__(self, schema, fields): |
||||
|
|
||||
|
if len(fields) == 1: |
||||
|
message = 'missing required field: {}'.format( |
||||
|
repr(fields[0]) |
||||
|
) |
||||
|
else: |
||||
|
message = 'missing required fields: {}'.format( |
||||
|
', '.join(fields) |
||||
|
) |
||||
|
if len(message) >= 80: # if the line is too long |
||||
|
message = 'missing required fields:\n{}'.format( |
||||
|
_indent('\n'.join(fields)) |
||||
|
) |
||||
|
|
||||
|
SchemaMismatch.__init__(self, message, schema, 'missing') |
||||
|
self.fields = fields |
||||
|
|
||||
|
|
||||
|
class UnknownFieldMismatch(SchemaMismatch): |
||||
|
|
||||
|
def __init__(self, schema, fields): |
||||
|
|
||||
|
if len(fields) == 1: |
||||
|
message = 'unknown field: {}'.format( |
||||
|
repr(fields[0]) |
||||
|
) |
||||
|
else: |
||||
|
message = 'unknown fields: {}'.format( |
||||
|
', '.join(fields) |
||||
|
) |
||||
|
if len(message) >= 80: # if the line is too long |
||||
|
message = 'unknown fields:\n{}'.format( |
||||
|
_indent('\n'.join(fields)) |
||||
|
) |
||||
|
|
||||
|
SchemaMismatch.__init__(self, message, schema, 'unexpected') |
||||
|
self.fields = fields |
||||
|
|
||||
|
|
||||
|
class SeqLengthMismatch(SchemaMismatch): |
||||
|
def __init__(self, schema, data): |
||||
|
|
||||
|
expected_length = len(schema.content_schema) |
||||
|
message = 'sequence must have {} element{} (had {})'.format( |
||||
|
expected_length, |
||||
|
's'*(expected_length != 1), # plural |
||||
|
len(data) |
||||
|
) |
||||
|
|
||||
|
SchemaMismatch.__init__(self, message, schema, 'size') |
||||
|
self.expected_length = expected_length |
||||
|
self.value = len(data) |
||||
|
|
||||
|
|
||||
|
class TreeMismatch(SchemaMismatch): |
||||
|
|
||||
|
def __init__(self, schema, errors=[], child_errors={}, message=None): |
||||
|
|
||||
|
## Create error message |
||||
|
|
||||
|
error_messages = [] |
||||
|
|
||||
|
for err in errors: |
||||
|
error_messages.append(str(err)) |
||||
|
|
||||
|
for key, err in child_errors.items(): |
||||
|
|
||||
|
if isinstance(key, int): |
||||
|
index = '[item {}]'.format(key) |
||||
|
else: |
||||
|
index = '{}'.format(repr(key)) |
||||
|
|
||||
|
if isinstance(err, TreeMismatch) and \ |
||||
|
not err.errors and len(err.child_errors) == 1: |
||||
|
|
||||
|
template = '{} > {}' |
||||
|
|
||||
|
else: |
||||
|
template = '{} {}' |
||||
|
|
||||
|
msg = template.format(index, err) |
||||
|
error_messages.append(msg) |
||||
|
|
||||
|
if message is None: |
||||
|
message = 'does not match schema' |
||||
|
|
||||
|
if len(error_messages) == 1: |
||||
|
msg = error_messages[0] |
||||
|
|
||||
|
else: |
||||
|
msg = '{}:\n{}'.format( |
||||
|
message, |
||||
|
_indent('\n'.join(error_messages)) |
||||
|
) |
||||
|
|
||||
|
SchemaMismatch.__init__(self, msg, schema, 'multiple') |
||||
|
self.errors = errors |
||||
|
self.child_errors = child_errors |
||||
|
|
||||
|
def _createTreeMismatch(schema, errors=[], child_errors={}, message=None): |
||||
|
if len(errors) == 1 and not child_errors: |
||||
|
return errors[0] |
||||
|
else: |
||||
|
return TreeMismatch(schema, errors, child_errors, message) |
||||
|
|
||||
|
### Utilities ---------------------------------------------------------------- |
||||
|
|
||||
|
class Range(object): |
||||
|
|
||||
|
def __init__(self, opt): |
||||
|
if isinstance(opt, Range): |
||||
|
for attr in ('min', 'max', 'min_ex', 'max_ex'): |
||||
|
if hasattr(opt, attr): |
||||
|
setattr(self, attr, getattr(opt, attr)) |
||||
|
else: |
||||
|
if not {'min', 'max', 'min-ex', 'max-ex'}.issuperset(opt): |
||||
|
raise ValueError("illegal argument to make_range_check") |
||||
|
if {'min', 'min-ex'}.issubset(opt): |
||||
|
raise ValueError("Cannot define both exclusive and inclusive min") |
||||
|
if {'max', 'max-ex'}.issubset(opt): |
||||
|
raise ValueError("Cannot define both exclusive and inclusive max") |
||||
|
|
||||
|
for boundary in ('min', 'max', 'min-ex', 'max-ex'): |
||||
|
if boundary in opt: |
||||
|
attr = boundary.replace('-', '_') |
||||
|
setattr(self, attr, opt[boundary]) |
||||
|
|
||||
|
def __call__(self, value): |
||||
|
INF = float('inf') |
||||
|
|
||||
|
get = lambda attr, default: getattr(self, attr, default) |
||||
|
|
||||
|
return( |
||||
|
get('min', -INF) <= value and \ |
||||
|
get('max', INF) >= value and \ |
||||
|
get('min_ex', -INF) < value and \ |
||||
|
get('max_ex', INF) > value |
||||
|
) |
||||
|
|
||||
|
def __str__(self): |
||||
|
if hasattr(self, 'min'): |
||||
|
s = '[{}, '.format(self.min) |
||||
|
elif hasattr(self, 'min_ex'): |
||||
|
s = '({}, '.format(self.min_ex) |
||||
|
else: |
||||
|
s = '(-Inf, ' |
||||
|
|
||||
|
if hasattr(self, 'max'): |
||||
|
s += '{}]'.format(self.max) |
||||
|
elif hasattr(self, 'max_ex'): |
||||
|
s += '{})'.format(self.max_ex) |
||||
|
else: |
||||
|
s += 'Inf)' |
||||
|
|
||||
|
return s |
||||
|
|
||||
|
def _indent(text, level=1, whitespace=' '): |
||||
|
return '\n'.join(whitespace*level+line for line in text.split('\n')) |
||||
|
|
||||
|
### Schema Factory Class ----------------------------------------------------- |
||||
|
|
||||
|
class Factory(object): |
||||
|
def __init__(self, register_core_types=True): |
||||
|
self.prefix_registry = { |
||||
|
'': 'tag:codesimply.com,2008:rx/core/', |
||||
|
'.meta': 'tag:codesimply.com,2008:rx/meta/', |
||||
|
} |
||||
|
|
||||
|
self.type_registry = {} |
||||
|
if register_core_types: |
||||
|
for t in core_types: self.register_type(t) |
||||
|
|
||||
|
@staticmethod |
||||
|
def _default_prefixes(): pass |
||||
|
|
||||
|
def expand_uri(self, type_name): |
||||
|
if re.match('^\w+:', type_name): return type_name |
||||
|
|
||||
|
m = re.match('^/([-._a-z0-9]*)/([-._a-z0-9]+)$', type_name) |
||||
|
|
||||
|
if not m: |
||||
|
raise ValueError("couldn't understand type name '{}'".format(type_name)) |
||||
|
|
||||
|
prefix, suffix = m.groups() |
||||
|
|
||||
|
if prefix not in self.prefix_registry: |
||||
|
raise KeyError( |
||||
|
"unknown prefix '{0}' in type name '{}'".format(prefix, type_name) |
||||
|
) |
||||
|
|
||||
|
return self.prefix_registry[ prefix ] + suffix |
||||
|
|
||||
|
def add_prefix(self, name, base): |
||||
|
if self.prefix_registry.get(name): |
||||
|
raise SchemaError("the prefix '{}' is already registered".format(name)) |
||||
|
|
||||
|
self.prefix_registry[name] = base; |
||||
|
|
||||
|
def register_type(self, t): |
||||
|
t_uri = t.uri() |
||||
|
|
||||
|
if t_uri in self.type_registry: |
||||
|
raise ValueError("type already registered for {}".format(t_uri)) |
||||
|
|
||||
|
self.type_registry[t_uri] = t |
||||
|
|
||||
|
def learn_type(self, uri, schema): |
||||
|
if self.type_registry.get(uri): |
||||
|
raise SchemaError( |
||||
|
"tried to learn type for already-registered uri {}".format(uri) |
||||
|
) |
||||
|
|
||||
|
# make sure schema is valid |
||||
|
# should this be in a try/except? |
||||
|
self.make_schema(schema) |
||||
|
|
||||
|
self.type_registry[uri] = { 'schema': schema } |
||||
|
|
||||
|
def make_schema(self, schema): |
||||
|
if isinstance(schema, str): |
||||
|
schema = { 'type': schema } |
||||
|
|
||||
|
if not isinstance(schema, dict): |
||||
|
raise SchemaError('invalid schema argument to make_schema') |
||||
|
|
||||
|
uri = self.expand_uri(schema['type']) |
||||
|
|
||||
|
if not self.type_registry.get(uri): |
||||
|
raise SchemaError("unknown type {}".format(uri)) |
||||
|
|
||||
|
type_class = self.type_registry[uri] |
||||
|
|
||||
|
if isinstance(type_class, dict): |
||||
|
if not {'type'}.issuperset(schema): |
||||
|
raise SchemaError('composed type does not take check arguments') |
||||
|
return self.make_schema(type_class['schema']) |
||||
|
else: |
||||
|
return type_class(schema, self) |
||||
|
|
||||
|
std_factory = None |
||||
|
def make_schema(schema): |
||||
|
global std_factory |
||||
|
if std_factory is None: |
||||
|
std_factory = Factory() |
||||
|
return std_factory.make_schema(schema) |
||||
|
|
||||
|
### Core Type Base Class ------------------------------------------------- |
||||
|
|
||||
|
class _CoreType(object): |
||||
|
@classmethod |
||||
|
def uri(self): |
||||
|
return 'tag:codesimply.com,2008:rx/core/' + self.subname() |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
if not {'type'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //{}'.format(self.subname())) |
||||
|
|
||||
|
def check(self, value): |
||||
|
try: |
||||
|
self.validate(value) |
||||
|
except SchemaMismatch: |
||||
|
return False |
||||
|
return True |
||||
|
|
||||
|
def validate(self, value): |
||||
|
raise SchemaMismatch('Tried to validate abstract base schema class', self) |
||||
|
|
||||
|
### Core Schema Types -------------------------------------------------------- |
||||
|
|
||||
|
class AllType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'all' |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
if not {'type', 'of'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //all') |
||||
|
|
||||
|
if not schema.get('of'): |
||||
|
raise SchemaError('no alternatives given in //all of') |
||||
|
|
||||
|
self.alts = [rx.make_schema(s) for s in schema['of']] |
||||
|
|
||||
|
def validate(self, value): |
||||
|
errors = [] |
||||
|
for schema in self.alts: |
||||
|
try: |
||||
|
schema.validate(value) |
||||
|
except SchemaMismatch as e: |
||||
|
errors.append(e) |
||||
|
|
||||
|
if errors: |
||||
|
raise _createTreeMismatch(self, errors) |
||||
|
|
||||
|
|
||||
|
class AnyType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'any' |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
self.alts = None |
||||
|
|
||||
|
if not {'type', 'of'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //any') |
||||
|
|
||||
|
if 'of' in schema: |
||||
|
if not schema['of']: |
||||
|
raise SchemaError('no alternatives given in //any of') |
||||
|
|
||||
|
self.alts = [ rx.make_schema(alt) for alt in schema['of'] ] |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if self.alts is None: |
||||
|
return |
||||
|
|
||||
|
errors = [] |
||||
|
|
||||
|
for schema in self.alts: |
||||
|
try: |
||||
|
schema.validate(value) |
||||
|
break |
||||
|
except SchemaMismatch as e: |
||||
|
errors.append(e) |
||||
|
|
||||
|
if len(errors) == len(self.alts): |
||||
|
message = 'must satisfy at least one of the following' |
||||
|
raise _createTreeMismatch(self, errors, message=message) |
||||
|
|
||||
|
|
||||
|
class ArrType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'arr' |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
self.length = None |
||||
|
|
||||
|
if not {'type', 'contents', 'length'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //arr') |
||||
|
|
||||
|
if not schema.get('contents'): |
||||
|
raise SchemaError('no contents provided for //arr') |
||||
|
|
||||
|
self.content_schema = rx.make_schema(schema['contents']) |
||||
|
|
||||
|
if schema.get('length'): |
||||
|
self.length = Range(schema['length']) |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if not isinstance(value, (list, tuple)): |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
errors = [] |
||||
|
if self.length and not self.length(len(value)): |
||||
|
err = LengthRangeMismatch(self, value) |
||||
|
errors.append(err) |
||||
|
|
||||
|
child_errors = {} |
||||
|
|
||||
|
for key, item in enumerate(value): |
||||
|
try: |
||||
|
self.content_schema.validate(item) |
||||
|
except SchemaMismatch as e: |
||||
|
child_errors[key] = e |
||||
|
if errors or child_errors: |
||||
|
raise _createTreeMismatch(self, errors, child_errors) |
||||
|
|
||||
|
|
||||
|
class BoolType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'bool' |
||||
|
|
||||
|
def validate(self, value,): |
||||
|
if not isinstance(value, bool): |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
|
||||
|
class DefType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'def' |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if value is None: |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
|
||||
|
class FailType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'fail' |
||||
|
|
||||
|
def check(self, value): return False |
||||
|
|
||||
|
def validate(self, value): |
||||
|
raise SchemaMismatch( |
||||
|
'is of fail type, automatically invalid.', |
||||
|
self, |
||||
|
'fail' |
||||
|
) |
||||
|
|
||||
|
|
||||
|
class IntType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'int' |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
if not {'type', 'range', 'value'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //int') |
||||
|
|
||||
|
self.value = None |
||||
|
if 'value' in schema: |
||||
|
if not isinstance(schema['value'], Number) or schema['value'] % 1 != 0: |
||||
|
raise SchemaError('invalid value parameter for //int') |
||||
|
self.value = schema['value'] |
||||
|
|
||||
|
self.range = None |
||||
|
if 'range' in schema: |
||||
|
self.range = Range(schema['range']) |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if not isinstance(value, Number) or isinstance(value, bool) or value%1: |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
if self.range and not self.range(value): |
||||
|
raise RangeMismatch(self, value) |
||||
|
|
||||
|
if self.value is not None and value != self.value: |
||||
|
raise ValueMismatch(self, value) |
||||
|
|
||||
|
|
||||
|
class MapType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'map' |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
self.allowed = set() |
||||
|
|
||||
|
if not {'type', 'values'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //map') |
||||
|
|
||||
|
if not schema.get('values'): |
||||
|
raise SchemaError('no values given for //map') |
||||
|
|
||||
|
self.value_schema = rx.make_schema(schema['values']) |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if not isinstance(value, dict): |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
child_errors = {} |
||||
|
|
||||
|
for key, val in value.items(): |
||||
|
try: |
||||
|
self.value_schema.validate(val) |
||||
|
except SchemaMismatch as e: |
||||
|
child_errors[key] = e |
||||
|
|
||||
|
if child_errors: |
||||
|
raise _createTreeMismatch(self, child_errors=child_errors) |
||||
|
|
||||
|
|
||||
|
class NilType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'nil' |
||||
|
|
||||
|
def check(self, value): return value is None |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if value is not None: |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
|
||||
|
class NumType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'num' |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
if not {'type', 'range', 'value'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //num') |
||||
|
|
||||
|
self.value = None |
||||
|
if 'value' in schema: |
||||
|
if not isinstance(schema['value'], Number): |
||||
|
raise SchemaError('invalid value parameter for //num') |
||||
|
self.value = schema['value'] |
||||
|
|
||||
|
self.range = None |
||||
|
|
||||
|
if schema.get('range'): |
||||
|
self.range = Range(schema['range']) |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if not isinstance(value, Number) or isinstance(value, bool): |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
if self.range and not self.range(value): |
||||
|
raise RangeMismatch(self, value) |
||||
|
|
||||
|
if self.value is not None and value != self.value: |
||||
|
raise ValueMismatch(self, value) |
||||
|
|
||||
|
|
||||
|
class OneType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'one' |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if not isinstance(value, (Number, str)): |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
|
||||
|
class RecType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'rec' |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
if not {'type', 'rest', 'required', 'optional'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //rec') |
||||
|
|
||||
|
self.known = set() |
||||
|
self.rest_schema = None |
||||
|
if schema.get('rest'): self.rest_schema = rx.make_schema(schema['rest']) |
||||
|
|
||||
|
for which in ('required', 'optional'): |
||||
|
setattr(self, which, {}) |
||||
|
for field in schema.get(which, {}).keys(): |
||||
|
if field in self.known: |
||||
|
raise SchemaError( |
||||
|
'%s appears in both required and optional' % field |
||||
|
) |
||||
|
|
||||
|
self.known.add(field) |
||||
|
|
||||
|
self.__getattribute__(which)[field] = rx.make_schema( |
||||
|
schema[which][field] |
||||
|
) |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if not isinstance(value, dict): |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
errors = [] |
||||
|
child_errors = {} |
||||
|
|
||||
|
missing_fields = [] |
||||
|
|
||||
|
for field in self.required: |
||||
|
|
||||
|
if field not in value: |
||||
|
missing_fields.append(field) |
||||
|
else: |
||||
|
try: |
||||
|
self.required[field].validate(value[field]) |
||||
|
except SchemaMismatch as e: |
||||
|
child_errors[field] = e |
||||
|
|
||||
|
if missing_fields: |
||||
|
err = MissingFieldMismatch(self, missing_fields) |
||||
|
errors.append(err) |
||||
|
|
||||
|
for field in self.optional: |
||||
|
if field not in value: continue |
||||
|
|
||||
|
try: |
||||
|
self.optional[field].validate(value[field]) |
||||
|
except SchemaMismatch as e: |
||||
|
child_errors[field] = e |
||||
|
|
||||
|
unknown = [k for k in value.keys() if k not in self.known] |
||||
|
|
||||
|
if unknown: |
||||
|
if self.rest_schema: |
||||
|
rest = {key: value[key] for key in unknown} |
||||
|
try: |
||||
|
self.rest_schema.validate(rest) |
||||
|
except SchemaMismatch as e: |
||||
|
errors.append(e) |
||||
|
else: |
||||
|
fields = _indent('\n'.join(unknown)) |
||||
|
err = UnknownFieldMismatch(self, unknown) |
||||
|
errors.append(err) |
||||
|
|
||||
|
if errors or child_errors: |
||||
|
raise _createTreeMismatch(self, errors, child_errors) |
||||
|
|
||||
|
|
||||
|
class SeqType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'seq' |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
if not {'type', 'contents', 'tail'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //seq') |
||||
|
|
||||
|
if not schema.get('contents'): |
||||
|
raise SchemaError('no contents provided for //seq') |
||||
|
|
||||
|
self.content_schema = [ rx.make_schema(s) for s in schema['contents'] ] |
||||
|
|
||||
|
self.tail_schema = None |
||||
|
if (schema.get('tail')): |
||||
|
self.tail_schema = rx.make_schema(schema['tail']) |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if not isinstance(value, (list, tuple)): |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
errors = [] |
||||
|
|
||||
|
if len(value) != len(self.content_schema): |
||||
|
if len(value) > len(self.content_schema) and self.tail_schema: |
||||
|
try: |
||||
|
self.tail_schema.validate(value[len(self.content_schema):]) |
||||
|
except SchemaMismatch as e: |
||||
|
errors.append(e) |
||||
|
else: |
||||
|
err = SeqLengthMismatch(self, value) |
||||
|
errors.append(err) |
||||
|
|
||||
|
child_errors = {} |
||||
|
|
||||
|
for index, (schema, item) in enumerate(zip(self.content_schema, value)): |
||||
|
try: |
||||
|
schema.validate(item) |
||||
|
except SchemaMismatch as e: |
||||
|
child_errors[index] = e |
||||
|
|
||||
|
if errors or child_errors: |
||||
|
raise _createTreeMismatch(self, errors, child_errors) |
||||
|
|
||||
|
|
||||
|
class StrType(_CoreType): |
||||
|
@staticmethod |
||||
|
def subname(): return 'str' |
||||
|
|
||||
|
def __init__(self, schema, rx): |
||||
|
if not {'type', 'value', 'length'}.issuperset(schema): |
||||
|
raise SchemaError('unknown parameter for //str') |
||||
|
|
||||
|
self.value = None |
||||
|
if 'value' in schema: |
||||
|
if not isinstance(schema['value'], str): |
||||
|
raise SchemaError('invalid value parameter for //str') |
||||
|
self.value = schema['value'] |
||||
|
|
||||
|
self.length = None |
||||
|
if 'length' in schema: |
||||
|
self.length = Range(schema['length']) |
||||
|
|
||||
|
def validate(self, value): |
||||
|
if not isinstance(value, str): |
||||
|
raise TypeMismatch(self, value) |
||||
|
|
||||
|
if self.value is not None and value != self.value: |
||||
|
raise ValueMismatch(self, self) |
||||
|
|
||||
|
if self.length and not self.length(len(value)): |
||||
|
raise LengthRangeMismatch(self, value) |
||||
|
|
||||
|
core_types = [ |
||||
|
AllType, AnyType, ArrType, BoolType, DefType, |
||||
|
FailType, IntType, MapType, NilType, NumType, |
||||
|
OneType, RecType, SeqType, StrType |
||||
|
] |
@ -0,0 +1,186 @@ |
|||||
|
schema: |
||||
|
type: //rec |
||||
|
optional: |
||||
|
content: //any |
||||
|
template: //any |
||||
|
_songbookfile_dir: //str |
||||
|
required: |
||||
|
_cache: //bool |
||||
|
_outputdir: //str |
||||
|
_outputname: //str |
||||
|
_error: //str |
||||
|
_datadir: |
||||
|
type: //arr |
||||
|
contents: //str |
||||
|
_songdir: |
||||
|
type: //arr |
||||
|
contents: //any |
||||
|
book: |
||||
|
type: //rec |
||||
|
required: |
||||
|
encoding: //str |
||||
|
lang: //str |
||||
|
pictures: //bool |
||||
|
template: //str |
||||
|
onesongperpage: //bool |
||||
|
chords: |
||||
|
type: //rec |
||||
|
required: |
||||
|
show: //bool |
||||
|
diagrampage: //bool |
||||
|
repeatchords: //bool |
||||
|
lilypond: //bool |
||||
|
tablatures: //bool |
||||
|
diagramreminder: |
||||
|
type: //any |
||||
|
of: |
||||
|
- type: //str |
||||
|
value: "none" |
||||
|
- type: //str |
||||
|
value: "important" |
||||
|
- type: //str |
||||
|
value: "all" |
||||
|
instrument: |
||||
|
type: //any |
||||
|
of: |
||||
|
- type: //str |
||||
|
value: "guitar" |
||||
|
- type: //str |
||||
|
value: "ukulele" |
||||
|
notation: |
||||
|
type: //any |
||||
|
of: |
||||
|
- type: //str |
||||
|
value: "alphascale" |
||||
|
- type: //str |
||||
|
value: "solfedge" |
||||
|
authors: |
||||
|
type: //rec |
||||
|
required: |
||||
|
separators: |
||||
|
type: //any |
||||
|
of: |
||||
|
- type: //arr |
||||
|
contents: //str |
||||
|
- type: //nil |
||||
|
ignore: |
||||
|
type: //any |
||||
|
of: |
||||
|
- type: //arr |
||||
|
contents: //str |
||||
|
- type: //nil |
||||
|
after: |
||||
|
type: //any |
||||
|
of: |
||||
|
- type: //arr |
||||
|
contents: //str |
||||
|
- type: //nil |
||||
|
titles: |
||||
|
type: //rec |
||||
|
required: |
||||
|
prefix: |
||||
|
type: //any |
||||
|
of: |
||||
|
- type: //arr |
||||
|
contents: //str |
||||
|
- type: //nil |
||||
|
default: |
||||
|
en: |
||||
|
_datadir: [] # For test reasons |
||||
|
book: |
||||
|
lang: en |
||||
|
encoding: utf-8 |
||||
|
pictures: yes |
||||
|
template: patacrep.tex |
||||
|
onesongperpage: no |
||||
|
|
||||
|
chords: |
||||
|
show: yes |
||||
|
diagramreminder: important |
||||
|
diagrampage: yes |
||||
|
repeatchords: yes |
||||
|
lilypond: no |
||||
|
tablatures: no |
||||
|
instrument: guitar |
||||
|
notation: alphascale |
||||
|
|
||||
|
authors: |
||||
|
separators: |
||||
|
- and |
||||
|
ignore: |
||||
|
- unknown |
||||
|
after: |
||||
|
- by |
||||
|
|
||||
|
titles: |
||||
|
prefix: |
||||
|
- The |
||||
|
- Le |
||||
|
- La |
||||
|
- "L'" |
||||
|
- A |
||||
|
- Au |
||||
|
- Ces |
||||
|
- De |
||||
|
- Des |
||||
|
- El |
||||
|
- Les |
||||
|
- Ma |
||||
|
- Mon |
||||
|
- Un |
||||
|
|
||||
|
fr: |
||||
|
chords: |
||||
|
notation: solfedge |
||||
|
description: |
||||
|
en: |
||||
|
book: |
||||
|
lang: "Main language of the songbook" |
||||
|
encoding: "Encoding of the files" |
||||
|
pictures: "Display the album pictures" |
||||
|
template: "Main template to use" |
||||
|
onesongperpage: "Start every song on a new page" |
||||
|
|
||||
|
chords: |
||||
|
show: "Display chords" |
||||
|
diagramreminder: "Display some diagram reminders before the songs" |
||||
|
diagrampage: "Add a diagram page" |
||||
|
repeatchords: "Repeat the chords inside the songs" |
||||
|
lilypond: "Display lilypond scores" |
||||
|
tablatures: "Display tablatures" |
||||
|
instrument: "Instrument for the diagrams" |
||||
|
notation: "Chord notation" |
||||
|
|
||||
|
authors: |
||||
|
separators: "Separator words between artists" |
||||
|
ignore: "Artist names to ignore" |
||||
|
after: "Word preceding artist names" |
||||
|
|
||||
|
titles: |
||||
|
prefix: "Words to ignore at the beginning of song titles for the index" |
||||
|
|
||||
|
fr: |
||||
|
book: |
||||
|
lang: "Langue principale" |
||||
|
encoding: "Encodage des fichiers" |
||||
|
pictures: "Afficher les illustrations d'albums" |
||||
|
template: "Template de base" |
||||
|
onesongperpage: "Commencer chaque chant sur une nouvelle page" |
||||
|
|
||||
|
chords: |
||||
|
show: "Afficher les accords" |
||||
|
diagramreminder: "Afficher quelques diagrammes d'accords au début des chants" |
||||
|
diagrampage: "Inclure une page de rappel des accords" |
||||
|
repeatchords: "Répéter l'affichage des accords au sein des chants" |
||||
|
lilypond: "Inclure les partitions lilypond" |
||||
|
tablatures: "Inclure les tablatures" |
||||
|
instrument: "Instrument pour les diagrammes d'accords" |
||||
|
notation: "Notation des accords" |
||||
|
|
||||
|
authors: |
||||
|
separators: "Mots de séparation entre les artistes" |
||||
|
ignore: "Noms d'artistes à ignorer" |
||||
|
after: "Mots précédents les noms d'artistes" |
||||
|
|
||||
|
titles: |
||||
|
prefix: "Préfixes de chants à ignorer dans le classement" |
@ -1 +1 @@ |
|||||
["subdir/chordpro.csg"] |
- subdir/chordpro.csg |
@ -1 +1,3 @@ |
|||||
[["cwd(subdir)"]] |
- cwd: |
||||
|
path: subdir |
||||
|
content: |
@ -1 +1,2 @@ |
|||||
["subdir/chordpro.csg", "exsong.sg"] |
- subdir/chordpro.csg |
||||
|
- exsong.sg |
@ -1 +1,11 @@ |
|||||
[["cwd(subdir)", "exsong.sg", "intersong.is", "jsonlist.json", "texfile.tex", "texsong.tsg", "chordpro.csg", "subdir/chordpro.csg"], "exsong.sg"] |
- cwd: |
||||
|
path: subdir |
||||
|
content: |
||||
|
- "exsong.sg" |
||||
|
- "intersong.is" |
||||
|
- "jsonlist.json" |
||||
|
- "texfile.tex" |
||||
|
- "texsong.tsg" |
||||
|
- "chordpro.csg" |
||||
|
- "subdir/chordpro.csg" |
||||
|
- "exsong.sg" |
@ -0,0 +1,6 @@ |
|||||
|
- sort: |
||||
|
key: "title" |
||||
|
content: |
||||
|
- exsong.sg |
||||
|
- chordpro.csg |
||||
|
- subdir/chordpro.csg |
@ -0,0 +1,5 @@ |
|||||
|
{title: Title1} |
||||
|
{artist: Author1} |
||||
|
|
||||
|
Foo bar |
||||
|
|
@ -0,0 +1,5 @@ |
|||||
|
{title: Title1} |
||||
|
{artist: Author2} |
||||
|
|
||||
|
Foo bar |
||||
|
|
@ -0,0 +1,5 @@ |
|||||
|
{title: Title2} |
||||
|
{artist: Author1} |
||||
|
|
||||
|
Foo bar |
||||
|
|
@ -0,0 +1,5 @@ |
|||||
|
{title: Title2} |
||||
|
{artist: Author2} |
||||
|
|
||||
|
Foo bar |
||||
|
|
@ -0,0 +1,5 @@ |
|||||
|
{title: Title1} |
||||
|
{artist: Author1} |
||||
|
|
||||
|
Foo bar |
||||
|
|
@ -0,0 +1,5 @@ |
|||||
|
{title: Title1} |
||||
|
{artist: Author2} |
||||
|
|
||||
|
Foo bar |
||||
|
|
@ -0,0 +1,5 @@ |
|||||
|
{title: Title2} |
||||
|
{artist: Author1} |
||||
|
|
||||
|
Foo bar |
||||
|
|
@ -0,0 +1,5 @@ |
|||||
|
{title: Title2} |
||||
|
{artist: Author2} |
||||
|
|
||||
|
Foo bar |
||||
|
|
@ -1 +1 @@ |
|||||
["chordpro.csg"] |
- chordpro.csg |
@ -1 +1 @@ |
|||||
["*.csg"] |
- "*.csg" |
@ -1 +1,6 @@ |
|||||
["exsong.sg", "chordpro.csg", "subdir/chordpro.csg"] |
- exsong.sg |
||||
|
- chordpro.csg |
||||
|
- subdir/chordpro.csg |
||||
|
- chordpro.csg |
||||
|
- subdir/chordpro.csg |
||||
|
- exsong.sg |
@ -1 +1,3 @@ |
|||||
[["include" , "custom_list.json"]] |
- include: |
||||
|
- custom_list.json |
||||
|
- include: custom_list.yaml |
@ -0,0 +1 @@ |
|||||
|
[] |
@ -0,0 +1,4 @@ |
|||||
|
- ["directly", "a", "list"] |
||||
|
- invalid_keyword: Test |
||||
|
- section: |
||||
|
short: Missing name |
@ -1 +1,11 @@ |
|||||
["section:Traditional", "exsong.sg", "section:Example", "texsong.tsg", "chordpro.csg", "exsong.sg"] |
- section{First Section!} |
||||
|
- section{Named section} |
||||
|
- section[section_short_name]{Section with short name} |
||||
|
- section*{Section* with short name} |
||||
|
- part{part section test} |
||||
|
- chapter{chapter section test} |
||||
|
- section{section section test} |
||||
|
- subsection{subsection section test} |
||||
|
- subsubsection{subsubsection section test} |
||||
|
- paragraph{paragraph section test} |
||||
|
- subparagraph{subparagraph section test} |
@ -1,6 +1,16 @@ |
|||||
[["section", "Traditional"], |
- section: First Section! |
||||
"exsong.sg", |
- section: |
||||
["section", "Example"], |
name: Named section |
||||
"texsong.tsg", |
- section: |
||||
"chordpro.csg", |
name: Section with short name |
||||
"exsong.sg"] |
short: section_short_name |
||||
|
- section*: |
||||
|
name: Section* with short name |
||||
|
short: section_star_short_name |
||||
|
- part: part section test |
||||
|
- chapter: chapter section test |
||||
|
- section: section section test |
||||
|
- subsection: subsection section test |
||||
|
- subsubsection: subsubsection section test |
||||
|
- paragraph: paragraph section test |
||||
|
- subparagraph: subparagraph section test |
@ -1 +0,0 @@ |
|||||
["section:(tradi)Traditional", "exsong.sg", "section*:Example", "texsong.tsg", "chordpro.csg", "exsong.sg"] |
|
@ -1,6 +0,0 @@ |
|||||
[["section", "Traditional", "tradi"], |
|
||||
"exsong.sg", |
|
||||
["section*", "Example"], |
|
||||
"texsong.tsg", |
|
||||
"chordpro.csg", |
|
||||
"exsong.sg"] |
|
@ -1 +1,4 @@ |
|||||
["exsong.sg", "texsong.tsg", "chordpro.csg", "subdir/chordpro.csg"] |
- exsong.sg |
||||
|
- texsong.tsg |
||||
|
- chordpro.csg |
||||
|
- subdir/chordpro.csg |
@ -1 +1,8 @@ |
|||||
["exsong.sg", "intersong.is", "jsonlist.json", "texfile.tex", "texsong.tsg", "chordpro.csg", "subdir/chordpro.csg"] |
- exsong.sg |
||||
|
- intersong.is |
||||
|
- jsonlist.json |
||||
|
- song: |
||||
|
- texfile.tex |
||||
|
- texsong.tsg |
||||
|
- song: chordpro.csg |
||||
|
- subdir/chordpro.csg |
@ -1 +1,6 @@ |
|||||
["songsection:Traditional", "exsong.sg", "songchapter:English", "texsong.tsg", "chordpro.csg", "exsong.sg"] |
- songsection{Traditional} |
||||
|
- exsong.sg |
||||
|
- songchapter{English} |
||||
|
- texsong.tsg |
||||
|
- chordpro.csg |
||||
|
- exsong.sg |
@ -1,6 +1,6 @@ |
|||||
[["songsection", "Traditional"], |
- songsection: Traditional |
||||
"exsong.sg", |
- "exsong.sg" |
||||
["songchapter", "English"], |
- songchapter: English |
||||
"texsong.tsg", |
- "texsong.tsg" |
||||
"chordpro.csg", |
- "chordpro.csg" |
||||
"exsong.sg"] |
- "exsong.sg" |
@ -0,0 +1,27 @@ |
|||||
|
- section{Title} |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title1_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title1_author2.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title1_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title1_author2.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title2_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title2_author2.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title2_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title2_author2.csg" |
||||
|
- section{Author, Title} |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title1_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title1_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title2_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title2_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title1_author2.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title1_author2.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title2_author2.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title2_author2.csg" |
||||
|
- section{Path, Title} |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title1_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title1_author2.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title2_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path1_title2_author2.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title1_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title1_author2.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title2_author1.csg" |
||||
|
- "@TEST_FOLDER@/datadir_sort/path2_title2_author2.csg" |
@ -0,0 +1,15 @@ |
|||||
|
- cwd: |
||||
|
path: "datadir_sort" |
||||
|
content: |
||||
|
- section: |
||||
|
name: "Title" |
||||
|
- sort: |
||||
|
key: title |
||||
|
- section: |
||||
|
name: "Author, Title" |
||||
|
- sort: |
||||
|
key: [by, title] |
||||
|
- section: |
||||
|
name: "Path, Title" |
||||
|
- sort: |
||||
|
key: [path, title] |
@ -1 +0,0 @@ |
|||||
["chordpro.csg", "exsong.sg", "subdir/chordpro.csg", "texsong.tsg"] |
|
@ -1 +0,0 @@ |
|||||
[["sorted(fullpath)"]] |
|
@ -1 +1,2 @@ |
|||||
["test/test_content/datadir/songs/texfile.tex"] |
- test/test_content/datadir/songs/texfile.tex |
||||
|
- test/test_content/datadir/songs/texfile.tex |
@ -1 +1,4 @@ |
|||||
[["tex", "texfile.tex", "chordpro.csg"]] |
- tex: |
||||
|
- texfile.tex |
||||
|
- chordpro.csg |
||||
|
- tex: texfile.tex |
@ -1,3 +0,0 @@ |
|||||
{ |
|
||||
"datadir": ["test_cache_datadir"], |
|
||||
} |
|
@ -0,0 +1,2 @@ |
|||||
|
book: |
||||
|
datadir: test_cache_datadir |
@ -1,2 +1,2 @@ |
|||||
/*tex |
**.tex |
||||
.cache |
.cache |
||||
|
@ -1,13 +0,0 @@ |
|||||
{ |
|
||||
"datadir": ["content_datadir"], |
|
||||
"content": [ |
|
||||
["section", "Test of section"], |
|
||||
["sorted"], |
|
||||
["songsection", "Test of song section"], |
|
||||
["cwd(content_datadir/content)", |
|
||||
"song.csg", "song.tsg", |
|
||||
["tex", "foo.tex"] |
|
||||
], |
|
||||
["include", "include.sbc"] |
|
||||
] |
|
||||
} |
|
@ -0,0 +1,25 @@ |
|||||
|
book: |
||||
|
pictures: yes |
||||
|
datadir: content_datadir |
||||
|
lang: en |
||||
|
template: default.tex |
||||
|
chords: |
||||
|
repeatchords: no |
||||
|
diagramreminder: all |
||||
|
|
||||
|
content: |
||||
|
- section: Test of section |
||||
|
- sort: |
||||
|
- songsection: Test of song section |
||||
|
- cwd: |
||||
|
# relative to yaml songfile |
||||
|
path: content_datadir/content |
||||
|
content: |
||||
|
- "song.csg" |
||||
|
- "song.tsg" |
||||
|
- cwd: |
||||
|
# relative to datadir |
||||
|
path: ../content |
||||
|
content: |
||||
|
- tex: foo.tex |
||||
|
- include: include.sbc |
@ -1 +1 @@ |
|||||
[["section", "This is an included section"]] |
[{"section": "This is an included section"}] |
||||
|
@ -1,6 +0,0 @@ |
|||||
bookoptions: |
|
||||
- pictures |
|
||||
datadir: |
|
||||
- datadir_datadir |
|
||||
- datadir_datadir2 |
|
||||
lang: en |
|
@ -0,0 +1,7 @@ |
|||||
|
book: |
||||
|
pictures: yes |
||||
|
datadir: |
||||
|
- datadir_datadir |
||||
|
- datadir_datadir2 |
||||
|
lang: en |
||||
|
template: default.tex |
@ -0,0 +1,131 @@ |
|||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
%% Automatically generated document. |
||||
|
%% You may edit this file but all changes will be overwritten. |
||||
|
%% If you want to change this document, have a look at |
||||
|
%% the templating system. |
||||
|
%% |
||||
|
%% Generated using Songbook <http://www.patacrep.com> |
||||
|
|
||||
|
\makeatletter |
||||
|
\def\input@path{ % |
||||
|
{@TEST_FOLDER@/latex/} % |
||||
|
{@DATA_FOLDER@/latex/} % |
||||
|
} |
||||
|
\makeatother |
||||
|
|
||||
|
\documentclass[ |
||||
|
]{article} |
||||
|
|
||||
|
\usepackage[ |
||||
|
chorded, |
||||
|
pictures, |
||||
|
repeatchords, |
||||
|
importantdiagramonly, |
||||
|
guitar, |
||||
|
]{crepbook} |
||||
|
|
||||
|
\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{lmodern} |
||||
|
|
||||
|
|
||||
|
\usepackage[english]{babel} |
||||
|
\lang{english} |
||||
|
|
||||
|
\usepackage{graphicx} |
||||
|
\graphicspath{ % |
||||
|
{@TEST_FOLDER@/} % |
||||
|
{@DATA_FOLDER@/} % |
||||
|
} |
||||
|
|
||||
|
|
||||
|
\makeatletter |
||||
|
\@ifpackageloaded{hyperref}{}{ |
||||
|
\usepackage{url} |
||||
|
\newcommand{\phantomsection}{} |
||||
|
\newcommand{\hyperlink}[2]{#2} |
||||
|
\newcommand{\href}[2]{\expandafter\url\expandafter{#1}} |
||||
|
} |
||||
|
\makeatother |
||||
|
|
||||
|
|
||||
|
\usepackage{chords} |
||||
|
|
||||
|
\title{Guitar songbook} |
||||
|
\author{The Patacrep Team} |
||||
|
|
||||
|
\newindex{titleidx}{lang_default_title} |
||||
|
\newauthorindex{authidx}{lang_default_auth} |
||||
|
|
||||
|
\authignoreword{unknown} |
||||
|
\authbyword{by} |
||||
|
\authsepword{and} |
||||
|
|
||||
|
\notenamesout{A}{B}{C}{D}{E}{F}{G} |
||||
|
|
||||
|
|
||||
|
\pagestyle{empty}\definecolor{SongNumberBgColor}{HTML}{D1E4AE} |
||||
|
\definecolor{NoteBgColor}{HTML}{D1E4AE} |
||||
|
\definecolor{IndexBgColor}{HTML}{D1E4AE} |
||||
|
|
||||
|
\renewcommand{\snumbgcolor}{SongNumberBgColor} |
||||
|
\renewcommand{\notebgcolor}{NoteBgColor} |
||||
|
\renewcommand{\idxbgcolor}{IndexBgColor} |
||||
|
|
||||
|
\definecolor{tango-green-3}{HTML}{4e9a06} |
||||
|
\definecolor{tango-blue-3}{HTML}{204a87} |
||||
|
\usepackage[ |
||||
|
bookmarks, |
||||
|
bookmarksopen, |
||||
|
hyperfigures=true, |
||||
|
colorlinks=true, |
||||
|
linkcolor=tango-green-3, |
||||
|
urlcolor=tango-blue-3 |
||||
|
]{hyperref} |
||||
|
|
||||
|
|
||||
|
\subtitle{} |
||||
|
\mail{crep@team-on-fire.com} |
||||
|
\web{http://www.patacrep.com} |
||||
|
\picture{img/treble_a} |
||||
|
\picturecopyright{Dbolton \url{http://commons.wikimedia.org/wiki/User:Dbolton}} |
||||
|
\footer{Generated using Songbook (\url{http://www.patacrep.com})} |
||||
|
|
||||
|
|
||||
|
\begin{document} |
||||
|
|
||||
|
\maketitle |
||||
|
|
||||
|
|
||||
|
\showindex{\songindexname}{titleidx} |
||||
|
\showindex{\authorindexname}{authidx} |
||||
|
|
||||
|
% list of chords |
||||
|
\ifchorded |
||||
|
\ifdiagram |
||||
|
\phantomsection |
||||
|
\addcontentsline{toc}{section}{\chordlistname} |
||||
|
\chords |
||||
|
\fi |
||||
|
\fi |
||||
|
|
||||
|
\phantomsection |
||||
|
\addcontentsline{toc}{section}{\songlistname} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
\end{document} |
@ -0,0 +1,2 @@ |
|||||
|
content: |
||||
|
- sort: |
@ -0,0 +1,131 @@ |
|||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
%% Automatically generated document. |
||||
|
%% You may edit this file but all changes will be overwritten. |
||||
|
%% If you want to change this document, have a look at |
||||
|
%% the templating system. |
||||
|
%% |
||||
|
%% Generated using Songbook <http://www.patacrep.com> |
||||
|
|
||||
|
\makeatletter |
||||
|
\def\input@path{ % |
||||
|
{@TEST_FOLDER@/latex/} % |
||||
|
{@DATA_FOLDER@/latex/} % |
||||
|
} |
||||
|
\makeatother |
||||
|
|
||||
|
\documentclass[ |
||||
|
]{article} |
||||
|
|
||||
|
\usepackage[ |
||||
|
chorded, |
||||
|
pictures, |
||||
|
repeatchords, |
||||
|
importantdiagramonly, |
||||
|
guitar, |
||||
|
]{crepbook} |
||||
|
|
||||
|
\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{lmodern} |
||||
|
|
||||
|
|
||||
|
\usepackage[english]{babel} |
||||
|
\lang{english} |
||||
|
|
||||
|
\usepackage{graphicx} |
||||
|
\graphicspath{ % |
||||
|
{@TEST_FOLDER@/} % |
||||
|
{@DATA_FOLDER@/} % |
||||
|
} |
||||
|
|
||||
|
|
||||
|
\makeatletter |
||||
|
\@ifpackageloaded{hyperref}{}{ |
||||
|
\usepackage{url} |
||||
|
\newcommand{\phantomsection}{} |
||||
|
\newcommand{\hyperlink}[2]{#2} |
||||
|
\newcommand{\href}[2]{\expandafter\url\expandafter{#1}} |
||||
|
} |
||||
|
\makeatother |
||||
|
|
||||
|
|
||||
|
\usepackage{chords} |
||||
|
|
||||
|
\title{Guitar songbook} |
||||
|
\author{The Patacrep Team} |
||||
|
|
||||
|
\newindex{titleidx}{lang_en_title} |
||||
|
\newauthorindex{authidx}{lang_en_auth} |
||||
|
|
||||
|
\authignoreword{unknown} |
||||
|
\authbyword{by} |
||||
|
\authsepword{and} |
||||
|
|
||||
|
\notenamesout{A}{B}{C}{D}{E}{F}{G} |
||||
|
|
||||
|
|
||||
|
\pagestyle{empty}\definecolor{SongNumberBgColor}{HTML}{D1E4AE} |
||||
|
\definecolor{NoteBgColor}{HTML}{D1E4AE} |
||||
|
\definecolor{IndexBgColor}{HTML}{D1E4AE} |
||||
|
|
||||
|
\renewcommand{\snumbgcolor}{SongNumberBgColor} |
||||
|
\renewcommand{\notebgcolor}{NoteBgColor} |
||||
|
\renewcommand{\idxbgcolor}{IndexBgColor} |
||||
|
|
||||
|
\definecolor{tango-green-3}{HTML}{4e9a06} |
||||
|
\definecolor{tango-blue-3}{HTML}{204a87} |
||||
|
\usepackage[ |
||||
|
bookmarks, |
||||
|
bookmarksopen, |
||||
|
hyperfigures=true, |
||||
|
colorlinks=true, |
||||
|
linkcolor=tango-green-3, |
||||
|
urlcolor=tango-blue-3 |
||||
|
]{hyperref} |
||||
|
|
||||
|
|
||||
|
\subtitle{} |
||||
|
\mail{crep@team-on-fire.com} |
||||
|
\web{http://www.patacrep.com} |
||||
|
\picture{img/treble_a} |
||||
|
\picturecopyright{Dbolton \url{http://commons.wikimedia.org/wiki/User:Dbolton}} |
||||
|
\footer{Generated using Songbook (\url{http://www.patacrep.com})} |
||||
|
|
||||
|
|
||||
|
\begin{document} |
||||
|
|
||||
|
\maketitle |
||||
|
|
||||
|
|
||||
|
\showindex{\songindexname}{titleidx} |
||||
|
\showindex{\authorindexname}{authidx} |
||||
|
|
||||
|
% list of chords |
||||
|
\ifchorded |
||||
|
\ifdiagram |
||||
|
\phantomsection |
||||
|
\addcontentsline{toc}{section}{\chordlistname} |
||||
|
\chords |
||||
|
\fi |
||||
|
\fi |
||||
|
|
||||
|
\phantomsection |
||||
|
\addcontentsline{toc}{section}{\songlistname} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
\end{document} |
@ -0,0 +1,5 @@ |
|||||
|
book: |
||||
|
lang: en |
||||
|
|
||||
|
content: |
||||
|
- sort: |
@ -0,0 +1,131 @@ |
|||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
%% Automatically generated document. |
||||
|
%% You may edit this file but all changes will be overwritten. |
||||
|
%% If you want to change this document, have a look at |
||||
|
%% the templating system. |
||||
|
%% |
||||
|
%% Generated using Songbook <http://www.patacrep.com> |
||||
|
|
||||
|
\makeatletter |
||||
|
\def\input@path{ % |
||||
|
{@TEST_FOLDER@/latex/} % |
||||
|
{@DATA_FOLDER@/latex/} % |
||||
|
} |
||||
|
\makeatother |
||||
|
|
||||
|
\documentclass[ |
||||
|
]{article} |
||||
|
|
||||
|
\usepackage[ |
||||
|
chorded, |
||||
|
pictures, |
||||
|
repeatchords, |
||||
|
importantdiagramonly, |
||||
|
guitar, |
||||
|
]{crepbook} |
||||
|
|
||||
|
\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{lmodern} |
||||
|
|
||||
|
|
||||
|
\usepackage[french]{babel} |
||||
|
\lang{french} |
||||
|
|
||||
|
\usepackage{graphicx} |
||||
|
\graphicspath{ % |
||||
|
{@TEST_FOLDER@/} % |
||||
|
{@DATA_FOLDER@/} % |
||||
|
} |
||||
|
|
||||
|
|
||||
|
\makeatletter |
||||
|
\@ifpackageloaded{hyperref}{}{ |
||||
|
\usepackage{url} |
||||
|
\newcommand{\phantomsection}{} |
||||
|
\newcommand{\hyperlink}[2]{#2} |
||||
|
\newcommand{\href}[2]{\expandafter\url\expandafter{#1}} |
||||
|
} |
||||
|
\makeatother |
||||
|
|
||||
|
|
||||
|
\usepackage{chords} |
||||
|
|
||||
|
\title{Recueil de chansons pour guitare} |
||||
|
\author{L'équipe Patacrep} |
||||
|
|
||||
|
\newindex{titleidx}{lang_fr_title} |
||||
|
\newauthorindex{authidx}{lang_fr_auth} |
||||
|
|
||||
|
\authignoreword{unknown} |
||||
|
\authbyword{by} |
||||
|
\authsepword{and} |
||||
|
|
||||
|
\notenamesout{La}{Si}{Do}{R\'e}{Mi}{Fa}{Sol} |
||||
|
|
||||
|
|
||||
|
\pagestyle{empty}\definecolor{SongNumberBgColor}{HTML}{D1E4AE} |
||||
|
\definecolor{NoteBgColor}{HTML}{D1E4AE} |
||||
|
\definecolor{IndexBgColor}{HTML}{D1E4AE} |
||||
|
|
||||
|
\renewcommand{\snumbgcolor}{SongNumberBgColor} |
||||
|
\renewcommand{\notebgcolor}{NoteBgColor} |
||||
|
\renewcommand{\idxbgcolor}{IndexBgColor} |
||||
|
|
||||
|
\definecolor{tango-green-3}{HTML}{4e9a06} |
||||
|
\definecolor{tango-blue-3}{HTML}{204a87} |
||||
|
\usepackage[ |
||||
|
bookmarks, |
||||
|
bookmarksopen, |
||||
|
hyperfigures=true, |
||||
|
colorlinks=true, |
||||
|
linkcolor=tango-green-3, |
||||
|
urlcolor=tango-blue-3 |
||||
|
]{hyperref} |
||||
|
|
||||
|
|
||||
|
\subtitle{} |
||||
|
\mail{crep@team-on-fire.com} |
||||
|
\web{http://www.patacrep.com} |
||||
|
\picture{img/treble_a} |
||||
|
\picturecopyright{Dbolton \url{http://commons.wikimedia.org/wiki/User:Dbolton}} |
||||
|
\footer{Créé avec le programme Songbook (\url{http://www.patacrep.com})} |
||||
|
|
||||
|
|
||||
|
\begin{document} |
||||
|
|
||||
|
\maketitle |
||||
|
|
||||
|
|
||||
|
\showindex{\songindexname}{titleidx} |
||||
|
\showindex{\authorindexname}{authidx} |
||||
|
|
||||
|
% list of chords |
||||
|
\ifchorded |
||||
|
\ifdiagram |
||||
|
\phantomsection |
||||
|
\addcontentsline{toc}{section}{\chordlistname} |
||||
|
\chords |
||||
|
\fi |
||||
|
\fi |
||||
|
|
||||
|
\phantomsection |
||||
|
\addcontentsline{toc}{section}{\songlistname} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
\end{document} |
@ -0,0 +1,5 @@ |
|||||
|
book: |
||||
|
lang: fr |
||||
|
|
||||
|
content: |
||||
|
- sort: |
@ -1,2 +0,0 @@ |
|||||
datadir: |
|
||||
- languages_datadir |
|
@ -0,0 +1,4 @@ |
|||||
|
book: |
||||
|
template: default.tex |
||||
|
datadir: |
||||
|
- languages_datadir |
@ -0,0 +1,133 @@ |
|||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
%% Automatically generated document. |
||||
|
%% You may edit this file but all changes will be overwritten. |
||||
|
%% If you want to change this document, have a look at |
||||
|
%% the templating system. |
||||
|
%% |
||||
|
%% Generated using Songbook <http://www.patacrep.com> |
||||
|
|
||||
|
\makeatletter |
||||
|
\def\input@path{ % |
||||
|
{@TEST_FOLDER@/onthefly/../content_datadir/latex/} % |
||||
|
{@LOCAL_DATA_FOLDER@/latex/} % |
||||
|
} |
||||
|
\makeatother |
||||
|
|
||||
|
\documentclass[ |
||||
|
]{article} |
||||
|
|
||||
|
\usepackage[ |
||||
|
chorded, |
||||
|
pictures, |
||||
|
diagram, |
||||
|
guitar, |
||||
|
]{patacrep} |
||||
|
|
||||
|
\usepackage{lmodern} |
||||
|
|
||||
|
|
||||
|
\PassOptionsToPackage{english}{babel} |
||||
|
\PassOptionsToPackage{english}{babel} |
||||
|
\usepackage[english]{babel} |
||||
|
\lang{english} |
||||
|
|
||||
|
\usepackage{graphicx} |
||||
|
\graphicspath{ % |
||||
|
{@TEST_FOLDER@/onthefly/../content_datadir/} % |
||||
|
{@LOCAL_DATA_FOLDER@/} % |
||||
|
} |
||||
|
|
||||
|
|
||||
|
\makeatletter |
||||
|
\@ifpackageloaded{hyperref}{}{ |
||||
|
\usepackage{url} |
||||
|
\newcommand{\phantomsection}{} |
||||
|
\newcommand{\hyperlink}[2]{#2} |
||||
|
\newcommand{\href}[2]{\expandafter\url\expandafter{#1}} |
||||
|
} |
||||
|
\makeatother |
||||
|
|
||||
|
|
||||
|
\usepackage{chords} |
||||
|
|
||||
|
\title{Guitar songbook} |
||||
|
\author{The Patacrep Team} |
||||
|
|
||||
|
\newindex{titleidx}{content.onthefly_title} |
||||
|
\newauthorindex{authidx}{content.onthefly_auth} |
||||
|
|
||||
|
\authignoreword{unknown} |
||||
|
\authbyword{by} |
||||
|
\authsepword{and} |
||||
|
|
||||
|
\notenamesout{A}{B}{C}{D}{E}{F}{G} |
||||
|
|
||||
|
|
||||
|
\begin{document} |
||||
|
|
||||
|
\maketitle |
||||
|
|
||||
|
|
||||
|
\showindex{\songindexname}{titleidx} |
||||
|
\showindex{\authorindexname}{authidx} |
||||
|
|
||||
|
% list of chords |
||||
|
\ifchorded |
||||
|
\ifdiagram |
||||
|
\phantomsection |
||||
|
\addcontentsline{toc}{section}{\chordlistname} |
||||
|
\chords |
||||
|
\fi |
||||
|
\fi |
||||
|
|
||||
|
\phantomsection |
||||
|
\addcontentsline{toc}{section}{\songlistname} |
||||
|
|
||||
|
|
||||
|
\section{Test of section} |
||||
|
|
||||
|
\begin{songs}{titleidx,authidx} |
||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
||||
|
%% songs/./song.csg |
||||
|
|
||||
|
\selectlanguage{english} |
||||
|
|
||||
|
\beginsong{This is a song}[ |
||||
|
by={ |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
\begin{verse} |
||||
|
Foo |
||||
|
\end{verse} |
||||
|
|
||||
|
\endsong |
||||
|
|
||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
||||
|
%% songs/./song.tsg |
||||
|
|
||||
|
\import{@TEST_FOLDER@/content_datadir/songs/}{song.tsg} |
||||
|
|
||||
|
\end{songs} |
||||
|
|
||||
|
\songsection{Test of song section} |
||||
|
|
||||
|
|
||||
|
\input{@TEST_FOLDER@/content_datadir/content/foo.tex} |
||||
|
|
||||
|
|
||||
|
\section{This is an included section} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
\end{document} |
@ -0,0 +1,19 @@ |
|||||
|
book: |
||||
|
pictures: yes |
||||
|
datadir: content_datadir |
||||
|
lang: en |
||||
|
template: default.tex |
||||
|
chords: |
||||
|
repeatchords: no |
||||
|
diagramreminder: all |
||||
|
|
||||
|
content: |
||||
|
- section: Test of section |
||||
|
- sort: |
||||
|
- songsection: Test of song section |
||||
|
- cwd: |
||||
|
# relative to datadir 'song' dir |
||||
|
path: ../content |
||||
|
content: |
||||
|
- tex: foo.tex |
||||
|
- include: include.sbc |
@ -1,3 +0,0 @@ |
|||||
datadir: |
|
||||
- syntax_datadir |
|
||||
lang: en |
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue