Added a test for bulleted list formatting.

This commit is contained in:
Mark Wolfman
2020-10-27 21:24:28 -05:00
parent d896e828e1
commit 839f684b02
5 changed files with 108 additions and 81 deletions
+54 -48
View File
@@ -25,13 +25,14 @@ class Archfey(SubClass):
class Fiend(SubClass):
"""You have made a pact with a fiend from the lower planes o f existence, a
being whose aims are evil, even if you strive against those aims. Such
beings desire the corruption or destruction of all things, ultimately
including you. Fiends powerful enough to forge a pact include demon lords
such as Demogorgon, Orcus, Fraz'Urb-luu, and Baphomet; archdevils such as
Asmodeus, Dispater, Mephistopheles, and Belial; pit fiends and balors that
are especially mighty; and ultroloths and other lords of the yugoloths
"""You have made a pact with a fiend from the lower planes of
existence, a being whose aims are evil, even if you strive against
those aims. Such beings desire the corruption or destruction of
all things, ultimately including you. Fiends powerful enough to
forge a pact include demon lords such as Demogorgon, Orcus,
Fraz'Urb-luu, and Baphomet; archdevils such as Asmodeus, Dispater,
Mephistopheles, and Belial; pit fiends and balors that are
especially mighty; and ultroloths and other lords of the yugoloths
"""
name = "The Fiend Patron"
@@ -43,13 +44,14 @@ class Fiend(SubClass):
class GreatOldOne(SubClass):
"""Your patron is a mysterious entity whose nature is utterly foreign to the
fabric of reality. It might come from the Far Realm, the space beyond
reality, or it could be one of the elder gods known only in legends. Its
motives are incomprehensible to mortals, and its knowledge so immense and
ancient that even the greatest libraries pale in comparison to the vast
secrets it holds. The Great Old One might be unaware of your existence or
entirely indifferent to you, but the secrets you have learned allow you to
"""Your patron is a mysterious entity whose nature is utterly foreign
to the fabric of reality. It might come from the Far Realm, the
space beyond reality, or it could be one of the elder gods known
only in legends. Its motives are incomprehensible to mortals, and
its knowledge so immense and ancient that even the greatest
libraries pale in comparison to the vast secrets it holds. The
Great Old One might be unaware of your existence or entirely
indifferent to you, but the secrets you have learned allow you to
draw your magic from it.
Entities of this type include Ghaunadar, called That Which Lurks;
@@ -67,17 +69,19 @@ class GreatOldOne(SubClass):
# SCAG
class Undying(SubClass):
"""Death holds no sway over your patron, who has un- locked the secrets of
everlasting life, although such a prize- like all power- comes at a
price. Once mortal, the Undying has seen mortal lifetimes pass like the
sea- sons, like the flicker of endless days and nights. It has the secrets
of the ages to share, secrets of life and death. Beings of this sort
include Vecna, Lord of the Hand and the Eye; the dread Iuz; the lich-queen
Vol; the Undying Court of Aerenal; Vlaakith, lich-queen of the githyanki;
and the deathless wizard Fistandantalus.
"""Death holds no sway over your patron, who has unlocked the secrets
of everlasting life, although such a prize -- like all power --
comes at a price. Once mortal, the Undying has seen mortal
lifetimes pass like the seasons, like the flicker of endless days
and nights. It has the secrets of the ages to share, secrets of
life and death. Beings of this sort include Vecna, Lord of the
Hand and the Eye; the dread Iuz; the lich-queen Vol; the Undying
Court of Aerenal; Vlaakith, lich-queen of the githyanki; and the
deathless wizard Fistandantalus.
In the Realms, Undying patrons include Larloch the Shadow King, legendary
master of Warlock's Crypt, and Gilgeam, the God-King of Unther
In the Realms, Undying patrons include Larloch the Shadow King,
legendary master of Warlock's Crypt, and Gilgeam, the God-King of
Unther
"""
name = "The Undying Patron"
@@ -90,19 +94,20 @@ class Undying(SubClass):
# XGTE
class Celestial(SubClass):
"""Your patron is a powerful being of the Upper Planes. You have bound yourself
to an ancient empyrean, solar, ki-rin, unicorn, or other entity that
resides in the planes of everlasting bliss. Your pact with that being
allows you to experience the barest touch of the holy light that illuminates
the multiverse.
"""Your patron is a powerful being of the Upper Planes. You have bound
yourself to an ancient empyrean, solar, kirin, unicorn, or other
entity that resides in the planes of everlasting bliss. Your pact
with that being allows you to experience the barest touch of the
holy light that illuminates the multiverse.
Being connected to such power can cause changes in your behavior and
beliefs. You might find yourself driven to annihilate the undead, to defeat
fiends, and to protect the innocent. At times, your heart might also be
filled with a longing for the celestial realm of your patron, and a desire
to wander that paradise for the rest of your days. But you know that your
mission is among mortals for now, and that your pact binds you to bring
light to the dark places of the world.
Being connected to such power can cause changes in your behavior
and beliefs. You might find yourself driven to annihilate the
undead, to defeat fiends, and to protect the innocent. At times,
your heart might also be filled with a longing for the celestial
realm of your patron, and a desire to wander that paradise for the
rest of your days. But you know that your mission is among mortals
for now, and that your pact binds you to bring light to the dark
places of the world.
"""
name = "The Celestial Patron"
@@ -115,19 +120,20 @@ class Celestial(SubClass):
class Hexblade(SubClass):
"""You have made your pact with a mysterious entity from the Shadowfell-a force
that manifests in sentient magic weapons carved from the stuff of
shadow. The mighty sword Blackrazor is the most notable of these weapons,
which have been spread across the multiverse over the ages. The shadowy
force behind these weapons can offer power to warlocks who form pacts with
it. Many hexhlade warlocks create weapons that emulate those formed in the
Shadowfell. Others forgo such arms, content to weave the dark magic of that
plane into their spellcasting.
"""You have made your pact with a mysterious entity from the
Shadowfell -- a force that manifests in sentient magic weapons
carved from the stuff of shadow. The mighty sword Blackrazor is
the most notable of these weapons, which have been spread across
the multiverse over the ages. The shadowy force behind these
weapons can offer power to warlocks who form pacts with it. Many
hexhlade warlocks create weapons that emulate those formed in the
Shadowfell. Others forgo such arms, content to weave the dark
magic of that plane into their spellcasting.
Because the Raven Queen is known to have forged the first of these weapons,
many sages speculate that she and the force are one and that the weapons,
along with hexblade warlocks, are tools she uses to manipulate events on
the Material Plane to her inscrutable ends
Because the Raven Queen is known to have forged the first of these
weapons, many sages speculate that she and the force are one and
that the weapons, along with hexblade warlocks, are tools she uses
to manipulate events on the Material Plane to her inscrutable ends
"""
name = "Hexblade Patron"
+6 -1
View File
@@ -32,10 +32,15 @@ dice_re = re.compile(r'`*(\d+d\d+(?:\s*\+\s*\d+)?)`*')
# - a blank line
# - one or more of the following
# - "- [a-z]"
# - an additional line of text (if multi-line bullets)
# - a blank line
# - a blank line
# - a non-list line or end of file
list_re = re.compile('^[ \t\r\f\v]*\n((?:\s*[-*+]\s+[^\n]*\n)+)', flags=re.MULTILINE)
# list_re = re.compile('^[ \t\r\f\v]*\n((?:\s*[-*+]\s+[^\n]*\n)+)', flags=re.MULTILINE)
list_re = re.compile('^[ \t\r\f\v]*\n' # A blank line
'((?:\s*[-*+]\s+[^\n]*\n)+)' # The first line of each list item
'',
flags=re.MULTILINE)
# What defines a list item in reST:
# - a line starting with "- " then some text
# - zero or more lines starting with anything other than "- "
+28 -24
View File
@@ -340,35 +340,38 @@ class AnimateDead(Spell):
class AnimateObjects(Spell):
"""Objects come to life at your command.
Choose up to ten nonmagical objects
within range that are not being worn or carried. Medium targets count as two
objects, Large targets count as four objects, Huge targets count as eight
objects. You can't animate any object larger than Huge. Each target animates and
becomes a creature under your control until the spell ends or until reduced to
0 hit points.
"""Objects come to life at your command. Choose up to ten nonmagical
objects within range that are not being worn or carried. Medium
targets count as two objects, Large targets count as four objects,
Huge targets count as eight objects. You can't animate any object
larger than Huge. Each target animates and becomes a creature
under your control until the spell ends or until reduced to 0 hit
points.
As a bonus action, you can mentally command any creature you
made with this spell if the creature is within 500 feet of you (if you control
multiple creatures, you can command any or all of them at the same time, issuing
the same command to each one). You decide what action the creature will take
and where it will move during its next turn, or you can issue a general command,
such as to guard a particular chamber or corridor. If you issue no commands,
the creature only defends itself against hostile creatures. Once given an order,
the creature continues to follow it until its task is complete.
As a bonus action, you can mentally command any creature you made
with this spell if the creature is within 500 feet of you (if you
control multiple creatures, you can command any or all of them at
the same time, issuing the same command to each one). You decide
what action the creature will take and where it will move during
its next turn, or you can issue a general command, such as to
guard a particular chamber or corridor. If you issue no commands,
the creature only defends itself against hostile creatures. Once
given an order, the creature continues to follow it until its task
is complete.
Animated
Object Statistics
Tiny HP: 20, AC: 18, Attack: +8 to hit, 1d4 + 4 damage,
Str: 4, Dex: 18
Small HP: 25, AC: 16, Attack: +6 to hit, 1d8 + 2 damage, Str:
Animated Object Statistics
--------------------------
- Tiny -- HP: 20, AC: 18, Attack: +8 to hit, 1d4 + 4 damage, Str:
4, Dex: 18
- Small -- HP: 25, AC: 16, Attack: +6 to hit, 1d8 + 2 damage, Str:
6, Dex: 14
Medium HP: 40, AC: 13, Attack: +5 to hit, 2d6 + 1 damage, Str:
- Medium HP: 40, AC: 13, Attack: +5 to hit, 2d6 + 1 damage, Str:
10, Dex: 12
Large HP: 50, AC: 10, Attack: +6 to hit, 2d10 + 2 damage, Str:
- Large HP: 50, AC: 10, Attack: +6 to hit, 2d10 + 2 damage, Str:
14, Dex: 10
Huge HP: 80, AC: 10, Attack: +8 to hit, 2d12 + 4 damage, Str: 18,
Dex: 6
- Huge HP: 80, AC: 10, Attack: +8 to hit, 2d12 + 4 damage, Str:
18, Dex: 6
An animated object is a construct with AC, hit points, attacks,
Strength, and Dexterity determine by its size. Its Constitution is 10 and its
@@ -389,6 +392,7 @@ class AnimateObjects(Spell):
At Higher
Levels: If you cast this spell using a spell slot of 6th level or higher, you
can animate two additional objects for each slot level above 5th.
"""
name = "Animate Objects"
level = 5
+1 -1
View File
@@ -81,7 +81,7 @@ or uses spells."""
# List of known spells
# Example: spells_prepared = ('magic missile', 'mage armor')
spells_prepared = ('acid splash', 'ray of frost', 'light', 'friends',
spells_prepared = ('acid splash', 'animate_objects', 'ray of frost', 'light', 'friends',
'disguise self', 'identify', 'jump',
'blur', 'knock', 'shatter',
'blink', 'fly', 'slow',
+13 -1
View File
@@ -89,7 +89,7 @@ class MarkdownTestCase(unittest.TestCase):
self.assertEqual(expected_tex, tex)
# A real list taken from a docstring
real_list = """
- Secondhand (you have heard of the target) +5
- Secondhand (you have heard of the target) - +5
- Firsthand (you have met the target) - +0
- Familiar (you know the target well) - -5
@@ -97,4 +97,16 @@ class MarkdownTestCase(unittest.TestCase):
tex = make_sheets.rst_to_latex(real_list)
self.assertIn("\\begin{itemize}", tex)
def test_multiline_bullet_list(self):
md_list = """
- Secondhand (you have heard
of the target) - +5
- Firsthand (you have met
the target) - +0
- Familiar (you know the target
well) - -5
"""
tex = make_sheets.rst_to_latex(md_list)
print(tex)
self.assertIn("\\begin{itemize}", tex)