mirror of
https://github.com/Threnklyn/dungeon-sheets.git
synced 2026-05-18 20:23:27 +02:00
All examples now build, plus added examples to travis build.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Generated output PDFs (and intermediate files)
|
||||
examples/*.pdf
|
||||
examples/*.aux
|
||||
examples/*.tex
|
||||
|
||||
# Emacs temp files
|
||||
*~
|
||||
|
||||
@@ -3,6 +3,10 @@ python:
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
before_install:
|
||||
- sudo add-apt-repository -y ppa:malteworld/ppa
|
||||
- sudo apt -q update
|
||||
- sudo apt-get -y install pdftk
|
||||
# command to install dependencies
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
|
||||
@@ -24,10 +24,11 @@ character sheet."""
|
||||
|
||||
bold_re = re.compile(r'\*\*([^*]+)\*\*')
|
||||
it_re = re.compile(r'\*([^*]+)\*')
|
||||
tt_re = re.compile(r'``([^`]+)``')
|
||||
verb_re = re.compile(r'``([^`]+)``')
|
||||
# A dice string, with optinal backticks: ``1d6 + 3``
|
||||
dice_re = re.compile(r'`*(\d+d\d+(?:\s*\+\s*\d+)?)`*')
|
||||
|
||||
|
||||
def rst_to_latex(rst):
|
||||
"""Basic markup of RST to LaTeX code."""
|
||||
if rst is None:
|
||||
@@ -38,10 +39,11 @@ def rst_to_latex(rst):
|
||||
tex = tex.replace(c, '\\' + c)
|
||||
tex = bold_re.sub(r'\\textbf{\1}', tex)
|
||||
tex = it_re.sub(r'\\textit{\1}', tex)
|
||||
tex = verb_re.sub(r'\\begin{verbatim}{\1}\\end{verbatim}', tex)
|
||||
tex = dice_re.sub(r'\\texttt{\1}', tex)
|
||||
tex = tt_re.sub(r'\\texttt{\1}', tex)
|
||||
for c in ['#', '$', '%', '&', '~', '_', '^']:
|
||||
tex = tex.replace(c, '\\' + c)
|
||||
|
||||
return tex
|
||||
|
||||
|
||||
@@ -70,22 +72,22 @@ def text_box(string):
|
||||
return new_string
|
||||
|
||||
|
||||
def create_druid_shapes_pdf(character, basename):
|
||||
def create_druid_shapes_pdf(character, basename, keep_temp_files=False):
|
||||
template = jinja_env.get_template('druid_shapes_template.tex')
|
||||
return create_latex_pdf(character, basename, template)
|
||||
return create_latex_pdf(character, basename, template, keep_temp_files=keep_temp_files)
|
||||
|
||||
|
||||
def create_spellbook_pdf(character, basename):
|
||||
def create_spellbook_pdf(character, basename, keep_temp_files=False):
|
||||
template = jinja_env.get_template('spellbook_template.tex')
|
||||
return create_latex_pdf(character, basename, template)
|
||||
return create_latex_pdf(character, basename, template, keep_temp_files=keep_temp_files)
|
||||
|
||||
|
||||
def create_features_pdf(character, basename):
|
||||
def create_features_pdf(character, basename, keep_temp_files=False):
|
||||
template = jinja_env.get_template('features_template.tex')
|
||||
return create_latex_pdf(character, basename, template)
|
||||
return create_latex_pdf(character, basename, template, keep_temp_files=keep_temp_files)
|
||||
|
||||
|
||||
def create_latex_pdf(character, basename, template):
|
||||
def create_latex_pdf(character, basename, template, keep_temp_files=False):
|
||||
tex = template.render(character=character)
|
||||
# Create tex document
|
||||
tex_file = f'{basename}.tex'
|
||||
@@ -109,19 +111,22 @@ def create_latex_pdf(character, basename, template):
|
||||
# Compile the PDF
|
||||
pdf_file = f'{basename}.pdf'
|
||||
output_dir = os.path.abspath(os.path.dirname(pdf_file))
|
||||
tex_command_line = ['pdflatex', '--output-directory', output_dir,
|
||||
'-halt-on-error', '-interaction=nonstopmode',
|
||||
tex_file]
|
||||
try:
|
||||
result = subprocess.run(['pdflatex', '--output-directory',
|
||||
output_dir, tex_file, '-halt-on-error'],
|
||||
result = subprocess.run(tex_command_line,
|
||||
stdout=subprocess.DEVNULL, timeout=30)
|
||||
except FileNotFoundError:
|
||||
# Remove temporary files
|
||||
remove_temp_files(basename)
|
||||
raise exceptions.LatexNotFoundError()
|
||||
else:
|
||||
if result.returncode == 0:
|
||||
if result.returncode == 0 and not keep_temp_files:
|
||||
remove_temp_files(basename)
|
||||
else:
|
||||
raise exceptions.LatexError(f'Processing of {basename}.tex failed.')
|
||||
if result.returncode != 0:
|
||||
raise exceptions.LatexError(f'Processing of {basename}.tex failed.'
|
||||
f' See {basename}.log for details.')
|
||||
|
||||
|
||||
def create_spells_pdf(character, basename, flatten=False):
|
||||
@@ -431,7 +436,7 @@ def _make_pdf_pdftk(fields, src_pdf, basename, flatten=False):
|
||||
os.remove(fdfname)
|
||||
|
||||
|
||||
def make_sheet(character_file, character=None, flatten=False):
|
||||
def make_sheet(character_file, character=None, flatten=False, debug=False):
|
||||
"""Prepare a PDF character sheet from the given character file.
|
||||
|
||||
Parameters
|
||||
@@ -463,7 +468,7 @@ def make_sheet(character_file, character=None, flatten=False):
|
||||
feat_base = '{:s}_feats'.format(
|
||||
os.path.splitext(character_file)[0])
|
||||
try:
|
||||
create_features_pdf(character=character, basename=feat_base)
|
||||
create_features_pdf(character=character, basename=feat_base, keep_temp_files=debug)
|
||||
except exceptions.LatexNotFoundError as e:
|
||||
log.warning('``pdflatex`` not available. Skipping features book '
|
||||
f'for {character.name}')
|
||||
@@ -473,7 +478,7 @@ def make_sheet(character_file, character=None, flatten=False):
|
||||
# Create spell book
|
||||
spellbook_base = os.path.splitext(character_file)[0] + '_spellbook'
|
||||
try:
|
||||
create_spellbook_pdf(character=character, basename=spellbook_base)
|
||||
create_spellbook_pdf(character=character, basename=spellbook_base, keep_temp_files=debug)
|
||||
except exceptions.LatexNotFoundError as e:
|
||||
log.warning('``pdflatex`` not available. Skipping spellbook '
|
||||
f'for {character.name}')
|
||||
@@ -484,7 +489,7 @@ def make_sheet(character_file, character=None, flatten=False):
|
||||
if len(wild_shapes) > 0:
|
||||
shapes_base = os.path.splitext(character_file)[0] + '_wild_shapes'
|
||||
try:
|
||||
create_druid_shapes_pdf(character=character, basename=shapes_base)
|
||||
create_druid_shapes_pdf(character=character, basename=shapes_base, keep_temp_files=debug)
|
||||
except exceptions.LatexNotFoundError as e:
|
||||
log.warning('``pdflatex`` not available. Skipping wild shapes list '
|
||||
f'for {character.name}')
|
||||
@@ -546,7 +551,7 @@ def main():
|
||||
for filename in filenames:
|
||||
print(f"Processing {os.path.splitext(filename)[0]}...", end='')
|
||||
try:
|
||||
make_sheet(character_file=filename, flatten=(not args.editable))
|
||||
make_sheet(character_file=filename, flatten=(not args.editable), debug=args.debug)
|
||||
except exceptions.CharacterFileFormatError as e:
|
||||
# Only raise the failed exception if this file is explicitly given
|
||||
print('invalid')
|
||||
|
||||
@@ -87,39 +87,39 @@ class ScorchingRay(Spell):
|
||||
|
||||
|
||||
class Scrying(Spell):
|
||||
"""You can see and hear a particular creature you choose that is on the same plane
|
||||
of existence as you. The target must make a W isdom saving throw, which is
|
||||
modified by how well you know the target and the sort of physical connection you
|
||||
have to it. If a target knows you're casting this spell, it can fail the saving
|
||||
throw voluntarily if it wants to be observed.
|
||||
"""You can see and hear a particular creature you choose that is on
|
||||
the same plane of existence as you. The target must make a W isdom
|
||||
saving throw, which is modified by how well you know the target
|
||||
and the sort of physical connection you have to it. If a target
|
||||
knows you're casting this spell, it can fail the saving throw
|
||||
voluntarily if it wants to be observed.
|
||||
|
||||
Knowledge - Save Modifier
|
||||
=========================
|
||||
Secondhand (you have heard of the target) - +5
|
||||
Firsthand (you have met the target) - +0
|
||||
Familiar (you know the target well) - -5
|
||||
|
||||
Connection - Save Modifier
|
||||
==========================
|
||||
Likeness or picture - -2
|
||||
Possession or garment - -4
|
||||
Body part, lock of hair, bit of nail, or the like - -10
|
||||
|
||||
On a successful save, the target isn't affected, and you can't use
|
||||
this spell against it again for 24 hours.
|
||||
|
||||
On a failed save, the spell creates an invisible sensor within 10
|
||||
feet of the target. You can see and hear through the sensor as if
|
||||
you w ere there. The sensor moves with the target, remaining
|
||||
within 10 feet of it for the duration. A creature that can see
|
||||
invisible objects sees the sensor as a luminous orb about the size
|
||||
of your fist.
|
||||
|
||||
Instead of targeting a creature, you can choose a location you
|
||||
have seen before as the target of this spell. When you do, the
|
||||
sensor appears at that location and doesn't move.
|
||||
|
||||
Knowledge Save
|
||||
Modifier
|
||||
Secondhand (you have heard of the target) +5
|
||||
Firsthand (you have met
|
||||
the target) +0
|
||||
Familiar (you know the target well) -5
|
||||
|
||||
Connection
|
||||
Save Modifier
|
||||
Likeness or picture -2
|
||||
Posession or
|
||||
garment -4
|
||||
Body part, lock of hair, bit of nail, or the like -10
|
||||
|
||||
On
|
||||
a successful save, the target isn't affected, and you can't use this spell
|
||||
against it again for 24 hours.
|
||||
|
||||
On a failed save, the spell creates an invisible
|
||||
sensor within 10 feet of the target. You can see and hear through the sensor as
|
||||
if you w ere there. The sensor moves with the target, remaining within 10 feet
|
||||
of it for the duration. A creature that can see invisible objects sees the
|
||||
sensor as a luminous orb about the size of your fist.
|
||||
|
||||
Instead of targeting a
|
||||
creature, you can choose a location you have seen before as the target of this
|
||||
spell. When you do, the sensor appears at that location and doesn't move.
|
||||
"""
|
||||
name = "Scrying"
|
||||
level = 5
|
||||
@@ -1508,7 +1508,7 @@ class Symbol(Spell):
|
||||
Each target must make a Wisdom saving throw and becomes frightened
|
||||
for 1 minute on a failed save. While frightened, the target drops whatever it is
|
||||
holding and must move at least 20 feet away from the glyph on each of ist
|
||||
turns, if able.
|
||||
turns, if able.
|
||||
|
||||
Hopelessness
|
||||
Each target must make a Charisma saving throw. On
|
||||
|
||||
@@ -47,3 +47,7 @@ class MarkdownTestCase(unittest.TestCase):
|
||||
def test_no_text(self):
|
||||
text = make_sheets.rst_to_latex(None)
|
||||
self.assertEqual(text, '')
|
||||
|
||||
def test_verbatim(self):
|
||||
text = make_sheets.rst_to_latex('``hello, world``')
|
||||
self.assertIn(r'\begin{verbatim}', text)
|
||||
|
||||
Reference in New Issue
Block a user