Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/character_files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Each character file must contain a line like::

dungeonsheets_version = "0.4.2"

Without this line, the :ref:`makesheets` command-line utility will ignore
Without this line, the :ref:`makesheets<Usage>` command-line utility will ignore
the file. This is necessary to avoid importing non-D&D python files.

.. note::
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = 'en'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
Expand All @@ -90,7 +90,7 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
#html_static_path = ['_static']

# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
Expand Down
26 changes: 1 addition & 25 deletions dungeonsheets/character.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,32 +451,10 @@ def other_weapon_proficiencies_text(self):
@property
def features(self):
fts = set(self.custom_features)
fighting_style_defined = False
set_of_fighting_styles = {
"Fighting Style (Archery)",
"Fighting Style (Defense)",
"Fighting Style (Dueling)",
"Fighting Style (Great Weapon Fighting)",
"Fighting Style (Protection)",
"Fighting Style (Two-Weapon Fighting)",
}
for temp_feature in fts:
fighting_style_defined = temp_feature.name in set_of_fighting_styles
if fighting_style_defined:
break

if not self.has_class:
return fts
for c in self.class_list:
fts |= set(c.features)
for feature in fts:
if (
fighting_style_defined
and feature.name == "Fighting Style (Select One)"
):
temp_feature = feature
fts.remove(temp_feature)
break
if self.race is not None:
fts |= set(getattr(self.race, "features", ()))
# some races have level-based features (Ex: Aasimar)
Expand Down Expand Up @@ -578,7 +556,7 @@ def spells_prepared(self):
spells |= set(f.spells_prepared)
for c in self.spellcasting_classes:
spells |= set(c.spells_prepared)
return sorted(tuple(spells), key=(lambda x: x.name))
return spells

def set_attrs(self, **attrs):
"""
Expand Down Expand Up @@ -654,8 +632,6 @@ def set_attrs(self, **attrs):
warning_message=msg,
)
_spells.append(ThisSpell)
# Sort by name
_spells.sort(key=lambda spell: spell.name)
# Save list of spells to character atribute
if attr == "spells":
# Instantiate them all for the spells list
Expand Down
2 changes: 1 addition & 1 deletion dungeonsheets/fill_pdf_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def spell_level(x):
# Determine which sheet to use (caster or half-caster).
# Prefer caster, unless we have no spells > 5th level and
# would overflow the caster sheet, then use half-caster.
only_low_level = all((character.spell_slots(level) == 0 for level in range(6, 10)))
only_low_level = not any(spell.level > 5 for spell in character.spells)
would_overflow_fullcaster = any(
(
len([spl for spl in character.spells if spl.level == level])
Expand Down
4 changes: 3 additions & 1 deletion dungeonsheets/forms/preamble.tex
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@
[% raw %]
\usepackage{longtable,ltcaption,array}
\setlength{\extrarowheight}{2pt}
\newlength{\DUtablewidth} % internal use in tables
% internal use in tables
\newlength{\DUtablewidth}
\newcommand{\DUcolumnwidth}[1]{\dimexpr#1\DUtablewidth-2\tabcolsep\relax}
% admonition (specially marked topic)
\providecommand{\DUadmonition}[2][class-arg]{%
% try \DUadmonition#1{#2}:
Expand Down
12 changes: 5 additions & 7 deletions dungeonsheets/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ def latex_parts(
"input_encoding": input_encoding,
"doctitle_xform": doctitle,
"initial_header_level": initial_header_level,
"use_latex_citations": True,
"legacy_column_widths": False,
}
writer = LatexWriter()
parts = core.publish_parts(
Expand Down Expand Up @@ -232,11 +234,9 @@ def rst_to_latex(rst, top_heading_level: int=0, format_dice: bool = True, use_dn
transformed_header = header
for width in colwidths:
# Transform the column width by dividing it by the initial table width
transformed_width = round( float(width) / tablewidth, 3)
# Subtract the table column separation spaces from the transformed column width
transformed_width = r"\\dimexpr " + str(transformed_width) + r"\\DUtablewidth -2\\tabcolsep"
transformed_width = str(round( float(width) / tablewidth, 3))
# Replace the original width with the transformed width
transformed_header = re.sub(width + r"\\DUtablewidth",
transformed_header = re.sub(width,
transformed_width,
transformed_header)
# Replace the original table header with the transformed one
Expand All @@ -248,7 +248,6 @@ def rst_to_latex(rst, top_heading_level: int=0, format_dice: bool = True, use_dn
# Next, take the first table row and define it as the first page table header:
tex = re.sub(r"(begin{DndLongTable}\[header=.*?)\](.*?)\n(.*?\\\\)\n\n",
r"\1,firsthead={\3 }]\2\n", tex, flags=re.M|re.DOTALL)

return tex


Expand Down Expand Up @@ -323,9 +322,8 @@ def msavage_spell_info(char):
# Only use halfcaster when we have no spells > 5th level and
# would overflow the fullcaster sheet.
# Keep the same sheet for overflow pages, if any.
only_low_level = all((char.spell_slots(level) == 0 for level in range(6, 10)))
if (any(len(spellList[key]) > fullcaster_sheet_spaces[key] for key in spellList.keys())
and only_low_level):
and not any(name in spellList.keys() for name in level_names[6:10])):
fullcaster = False

def AddSpellPage(fullcaster = True):
Expand Down
3 changes: 0 additions & 3 deletions dungeonsheets/make_sheets.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,6 @@ def make_character_sheet(
char_base = basename + "_char"
person_base = basename + "_person"
sheets = [char_base + ".pdf"]
pages = []
# Prepare the tex/html content
content_suffix = format_suffixes[output_format]
# Create a list of features and magic items
Expand All @@ -609,13 +608,11 @@ def make_character_sheet(
char_pdf = create_character_pdf_template(
character=character, basename=char_base, flatten=flatten
)
pages.append(char_pdf)
person_pdf = create_personality_pdf_template(
character=character,
basename=person_base,
flatten=flatten,
)
pages.append(person_pdf)
if character.is_spellcaster and not (use_tex_template):
# Create spell sheet
spell_base = "{:s}_spells".format(basename)
Expand Down
7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ authors = [
]
description = "Dungeons and Dragons 5e Character Tools"
readme = "README.rst"
license = {"file"= "LICENSE"}
license = "GPL-3.0-or-later"
license-files = ["LICENSE"]
requires-python = ">=3.9"
classifiers = [
"Development Status :: 3 - Alpha",
"Environment :: Console",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Natural Language :: English",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand All @@ -39,7 +39,8 @@ Homepage = "https://github.com/canismarko/dungeon-sheets"

[tool.setuptools.package-data]
dungeonsheets = [
"forms/*pdf",
"forms/*.html",
"forms/*.pdf",
"forms/*.tex",
"forms/*.txt",
"modules/DND-5e-LaTeX-Template/*",
Expand Down