Skip to content

Commit

Permalink
Use all RPGtex options for monster formatting
Browse files Browse the repository at this point in the history
When using the fancy feature pages, this patch changes the layout
of the text in the monster block. The patch adds a jinja filter to
parse the monster.__doc__ info and formats that info accordingly.
  • Loading branch information
PJBrs committed Jan 2, 2024
1 parent 2772346 commit 5cf362a
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 3 deletions.
2 changes: 1 addition & 1 deletion dungeonsheets/forms/companions_template.tex
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ \section*{Companions}
challenge = {[[ monster.challenge_rating ]] ([[ monster.challenge_rating | challenge_rating_to_xp ]] XP)},
]
%\DndMonsterSection{Actions}
[[ monster.__doc__ | rst_to_latex(top_heading_level=2) ]]
[[ monster.__doc__ | monsterdoc ]]
\end{DndMonster}
[% endfor %]

Expand Down
2 changes: 1 addition & 1 deletion dungeonsheets/forms/druid_shapes_template.tex
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ \section*{Known Beasts}
challenge = {[[ shape.challenge_rating ]]},
]
%\DndMonsterSection{Actions}
[[ shape.__doc__ | rst_to_latex(top_heading_level=2) ]]
[[ shape.__doc__ | monsterdoc ]]
\end{DndMonster}
[% endfor %]

Expand Down
2 changes: 1 addition & 1 deletion dungeonsheets/forms/monsters_template.tex
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ \section*{Monsters}
challenge = {[[ monster.challenge_rating ]] ([[ monster.challenge_rating | challenge_rating_to_xp ]] XP)},
]
%\DndMonsterSection{Actions}
[[ monster.__doc__ | rst_to_latex(top_heading_level=2) ]]
[[ monster.__doc__ | monsterdoc ]]
\end{DndMonster}
[% endfor %]

Expand Down
82 changes: 82 additions & 0 deletions dungeonsheets/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,3 +302,85 @@ def msavage_spell_info(char):
texT = texT + [slot_command_name, slot_command_prep]
tex3 = "\n".join(texT) + '\n'
return "\n".join([tex1, tex2, tex3])


def RPGtex_monster_info(char):
"""Generates the headings for the monster block info in the DND latex style"""
tex = """"""
# Counting sections here:
# 0: Feats
# 1: Actions and reactions
# 2: Legendary Actions
# 3: Other types of actions.
# Challenges: Some monsters only have feats, some only have actions.
sectiontype = 0
sectionlist = char.split(" # ") # Four spaces, a hash, and another space
for section in sectionlist:
# First find out what type of section we're dealing with, and
# set sectiontype accordingly;
# The first section is either feats or actions. Set sectiontype to
# actions (and format accordingly) if the first line matches
# actions or reactions
if re.match (r"^[re]*actions\n", section, re.IGNORECASE):
sectiontype = 1
elif re.match (r"^legendary actions\n", section, re.IGNORECASE):
sectiontype = 2
elif sectionlist.index(section) > 0: # Not the first section, nor does
sectiontype = 3 # it have any header we recognize

# Now we latex format each section according to type, applying
# rst_to_latex where it's convenient, and resorting to our own
# means where necessary. Goal is to make use of DND-5e-LaTeX-Template
# style as much as possible.
if sectiontype == 0 or sectiontype == 3:
# Use rst_to_latex first, because of easy itemization
section = rst_to_latex(section) # This somehow adds a newline at the start of the section
# Snip away begin and end description:
section = re.sub (r"\\[a-z]+{description}\n", "", section)
# Sub \item[{}] with \DndMonsterAction{} headers:
section = re.sub (r"\\item\[{(.+)\.}\]", r"\\DndMonsterAction{\1}", section)
if sectiontype == 3: # Add section header
section = re.sub(r"^\n(.*)\n", r"\\DndMonsterSection{\1}\n", section)
tex += section

if sectiontype == 1:
# Process the section line by line.
subsection = ""
lines = section.splitlines()
for line in lines:
if re.match (r"^\S", line):
line = re.sub(r"(.+)$", r"\n\n\\DndMonsterSection{\1}", line)
subsection += line
else:
# Italicize weapon type and hit, and remove six leading spaces
line = re.sub(r"^ {6}(.+)\:(.+)(Hit)\: (.+)", r"\\textit{\1:} \2\\textit{\3:} \4 ", line)
# Remove leading spaces from other lines
line = re.sub(r"^ {6}(.+)", r"\1 ", line)
# Add DndMonsterAction header for each action, and remove four leading spaces
line = re.sub(r"^ {4}(\S.+)\.$", r"\n\n\\DndMonsterAction{\1}\n", line)
subsection += line
subsection = re.sub(r" {6}", "\n\n", subsection)
# Dice
subsection = re.sub(r"\((\d+)d(\d+)\s*([+-]*)\s*(\d*)\)", r" (\\texttt{\1d\2\3\4}) ", subsection)
tex += subsection + "\n\n"

if sectiontype == 2:
# First process the section line by line to only get the legendary actions,
# then add section start, end and header.
subsection = ""
lines = section.splitlines()
for line in lines:
if re.match(r"^ {4}\S", line): # New subsubsection, remove leading spaces
line = re.sub(r"^ {4}(.+)\.$", r"\n\\DndMonsterLegendaryAction{\1}{}", line)
subsection += line
elif re.match(r"^ {6}\S", line):
# Remove leading spaces from other lines
line = re.sub(r"^ {6}(.+)", r"\1", line)
subsection += line
subsection = re.sub(r"}{(.*?)}([a-zA-Z].+)$", r"}{\1 \2}", subsection)
# Dice
subsection = re.sub(r"\((\d+)d(\d+)\s*([+-]*)\s*(\d*)\)", r" (\\texttt{\1d\2\3\4})", subsection)
# Add section header and DndMonsterLegendaryActions environment
section = ("\\DndMonsterSection{Legendary Actions}\n\\begin{DndMonsterLegendaryActions}" + subsection + "\n\\end{DndMonsterLegendaryActions}\n")
tex += section
return tex
1 change: 1 addition & 0 deletions dungeonsheets/make_sheets.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
jinja_env.filters["to_heading_id"] = epub.to_heading_id
jinja_env.filters["boxed"] = latex.rst_to_boxlatex
jinja_env.filters["spellsheetparser"] = latex.msavage_spell_info
jinja_env.filters["monsterdoc"] = latex.RPGtex_monster_info

# Custom types
File = Union[Path, str]
Expand Down

0 comments on commit 5cf362a

Please sign in to comment.