Added documentation, currently for writing character sheets only.

This commit is contained in:
Mark Wolfman
2018-10-15 00:14:48 -05:00
parent 0648a08d0c
commit 3c3d4be218
18 changed files with 942 additions and 8 deletions
+4
View File
@@ -7,6 +7,10 @@ A tool to create character sheets for Dungeons and Dragons.
.. image:: https://travis-ci.com/canismarko/dungeon-sheets.svg?branch=master
:target: https://travis-ci.com/canismarko/dungeon-sheets
.. image:: https://readthedocs.org/projects/dungeon-sheets/badge/?version=latest
:target: https://dungeon-sheets.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
Installation
============
+19
View File
@@ -0,0 +1,19 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+392
View File
@@ -0,0 +1,392 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>Character Files</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="character-files">
<h1 class="title">Character Files</h1>
<p>Dungeonsheets expects one file per character, with a <tt class="docutils literal">.dnd</tt>
extension. An older <em>python file</em> format is still supported, but not
recommended for security reasons. Details for this older style are
provided <a class="reference internal" href="#below">below</a>.</p>
<div class="section" id="old-python-character-files">
<span id="below"></span><h1>Old Python Character Files</h1>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">The mechanism described below is insecure since it involves
directly running python modules. Do not run files that you did not
write yourself and do not trust completely. Maliciously-crafted
files can run python code during import time.</p>
</div>
<p>Previous versions of this library used python files that are directly
imported to produce the appropriate values. The benefit is that this
allows much more versatile content, but at the expense of allowing
these files to run un-sanitized python code on your machine. This
behavior is still supported for now for backwards compatibility
reasons, but do so at your own risk.</p>
<p>An example of this syntax can be found in <a href="#id1"><span class="problematic" id="id2">:ref:`this wizard example&lt;Wizard Example (Python)&gt;`</span></a>.</p>
<div class="system-message" id="id1">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">character_files.rst</tt>, line 29); <em><a href="#id2">backlink</a></em></p>
Unknown interpreted text role &quot;ref&quot;.</div>
</div>
</div>
</body>
</html>
+215
View File
@@ -0,0 +1,215 @@
=================
Character Files
=================
.. warning::
Character files are python modules that are imported when
parsed. **NEVER parse a character file without inspecting it** to
verify that there are no unexpected consequences, especially a file
from someone you do not trust.
Dungeonsheets expects one file per character, with a ``.py``
extension. This file is a python module, most likely with a series of
variables set describing the character. They are roughly grouped into
sections, which are documented below. Additionally, some
:ref:`examples<examples>` may be useful.
Each character file must contain a line like::
dungeonsheets_version = "0.4.2"
Without this line, the `makesheets`_ command-line utility will ignore
the file. This is necessary to avoid importing non-D&D python files.
.. note::
Some proficiencies, character traits, abilities, etc.\ are the
result of the character's race and/or background. These **must
still be included** in the character file and will not be
automatically added if omitted.
Basic Info
==========
The character file will contain several basic information values that
are fairly self-evident. The values for ``character_class``,
``background``, ``race`` and ``alignment`` must match entries in the
standard 5e rules, and are case-insensitive. Refer to the D&D
`player's handbook`_ for more information.
.. code:: python
name = 'Inara Serradon'
character_class = 'wizard'
player_name = 'Mark'
background = "Acolyte"
race = "High-Elf"
level = 3
alignment = "Chaotic good"
xp = 2190
hp_max = 16
Ability Scores
==============
Ability scores are numeric scores for each ability, as described in
the `player's handbook`_.
.. code:: python
# Ability Scores
strength = 10
dexterity = 15
constitution = 14
intelligence = 16
wisdom = 12
charisma = 8
Proficiencies and Languages
===========================
This section may contain entries, one for ``skill_proficiencies`` and
one for ``languages``. ``skill_proficiencies`` must be an iterable of
case-insensitive strings matching skills described in the `player's
handbook`_. Languages is a standard string, since language proficiency
does not affect other areas of the character.
.. code:: python
# Proficiencies and languages
skill_proficiencies = [
'arcana',
'insight',
'investigation',
'perception',
'religion',
]
languages = "Common, Elvish, Draconic, Dwarvish, Goblin."
Inventory
=========
There are five entries for currencies, which must be
integers. ``weapons`` (iterable of strings), ``armor`` (string) and
``shield`` (string) must correspond to items available in the
`player's handbook`_. The ``equipment`` is a string that is rendered
as-is on the character sheet.
.. todo:: Allow custom weapons and armor to be specified in the
character file.
.. warning::
Not all weapons and armor have been entered into the
``dungeonsheets`` library. If you receive an ``AttributeError``
stating the item you entered is not defined despite being listed in
the `player's handbook`_, please submit an `issue`_.
.. code:: python
cp = 950
sp = 75
ep = 50
gp = 120
pp = 0
weapons = ('shortsword', 'shortbow')
armor = 'light leather armor'
shield = 'shield'
equipment = (
"""Shortsword, shortbow, 20 arrows, leather armor, thieves tools,
backpack, bell, 5 candles, crowbar, hammer, 10 pitons, 50 feet of
hempen rope, hooded lantern, 2 flasks of oil, 5 days rations,
tinderbox, waterskin, crowbar, set of dark common clothes
including a hood, pouch.""")
Spells
======
Two entries are available for spell-casting, and only if the class
supports spells. Both are lists of case-insensitive strings that must
correspond to spells described in the `player's handbook`_.
.. todo:: Allow custom spells to be specified in the character file.
.. warning::
Not all spells have been entered into the ``dungeonsheets``
library. If you receive a ``UserWarning`` stating the spell you
entered is not defined despite being listed in the `player's
handbook`_, please submit an `issue`_.
.. code:: python
# List of known spells
spells = ('blindness deafness', 'burning hands', 'detect magic',
'false life', 'mage armor', 'mage hand', 'magic missile',
'prestidigitation', 'ray of frost', 'ray of sickness', 'shield',
'shocking grasp', 'sleep',)
# Which spells have been prepared (not including cantrips)
spells_prepared = ('blindness deafness', 'false life', 'mage armor',
'ray of sickness', 'shield', 'sleep',)
Personality and Backstory
=========================
This section contains string that describe the nature and backstory of
the character. They will be printed as-is on the character
sheet. Triple-quoted string and parenthesis may make the character's
source file more readable, but are not required.
.. code:: python
# Backstory
personality_traits = """I use polysyllabic words that convey the impression of
erudition. Also, Ive spent so long in the temple that I have little
experience dealing with people on a casual basis."""
ideals = """Knowledge. The path to power and self-improvement is through
knowledge."""
bonds = """The tome I carry with me is the record of my lifes work so far,
and no vault is secure enough to keep it safe."""
flaws = """Ill do just about anything to uncover historical secrets that
would add to my research."""
features_and_traits = (
"""Spellcasting Ability: Intelligence is your spellcasting ability for
your spells. The saving throw DC to resist a spell you cast is
13. Your attack bonus when you make an attack with a spell is
+5. See the rulebook for rules on casting your spells.
Arcane Recovery: You can regain some of your magical energy by
studying your spellbook. Once per day during a short rest, you can
choose to recover expended spell slots with a combined level equal
to or less than half your wizard level (rounded up).
Darkvision: You see in dim light within a 60-foot radius of you as
if it were bright light, and in darkness in that radius as if it
were dim light. You cant discern color in darkness, only shades
of gray.
Fey Ancestry: You have advantage on saving throws against being
charmed, and magic cant put you to sleep.
Trance: Elves dont need to sleep. They meditate deeply, remaining
semiconscious, for 4 hours a day and gain the same benefit a human
does from 8 hours of sleep.
Shelter of the Faithful: As a servant of Oghma, you command the
respect of those who share your faith, and you can perform the
rites of Oghma. You and your companions can expect to receive free
healing and care at a temple, shrine, or other established
presence of Oghmas faith. Those who share your religion will
support you (and only you) at a modest lifestyle. You also have
ties to the temple of Oghma in Neverwinter, where you have a
residence. When you are in Neverwinter, you can call upon the
priests there for assistance that wont endanger them.""")
.. _player's handbook: http://dnd.wizards.com/products/tabletop-games/rpg-products/rpg_playershandbook
.. _issue: https://github.com/canismarko/dungeon-sheets/issues
+186
View File
@@ -0,0 +1,186 @@
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'dungeonsheets'
copyright = '2018, Mark Wolfman'
author = 'Mark Wolfman'
# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = '0.4.2'
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.autosectionlabel',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# 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
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'nature'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# 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']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'dungeonsheetsdoc'
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'dungeonsheets.tex', 'dungeonsheets Documentation',
'Mark Wolfman', 'manual'),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'dungeonsheets', 'dungeonsheets Documentation',
[author], 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'dungeonsheets', 'dungeonsheets Documentation',
author, 'dungeonsheets', 'One line description of project.',
'Miscellaneous'),
]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# -- Extension configuration -------------------------------------------------
# -- Options for todo extension ----------------------------------------------
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
+20
View File
@@ -0,0 +1,20 @@
==========
Examples
==========
.. contents:: :local:
Wizard
======
.. literalinclude:: ../examples/wizard.py
Warlock
=======
.. literalinclude:: ../examples/warlock.py
Rogue
=====
.. literalinclude:: ../examples/rogue.py
+26
View File
@@ -0,0 +1,26 @@
.. dungeonsheets documentation master file, created by
sphinx-quickstart on Sun Oct 14 18:07:48 2018.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Dungeonsheets's documentation!
=========================================
.. toctree::
:maxdepth: 2
:caption: Contents:
character_files
examples
To-Do Tasks
===========
.. todolist::
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
+35
View File
@@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd
+4 -2
View File
@@ -106,7 +106,9 @@ class Character():
"""Bulk setting of attributes. Useful for loading a character from a
dictionary."""
for attr, val in attrs.items():
if attr == 'weapons':
if attr == 'dungeonsheets_version':
pass # Maybe we'll verify this later?
elif attr == 'weapons':
# Treat weapons specially
for weap in val:
self.wield_weapon(weap)
@@ -249,7 +251,7 @@ class Character():
try:
NewWeapon = findattr(weapons, weapon)
except AttributeError:
raise AttributeError(f'Weapon {weapon} is not defined')
raise AttributeError(f'Weapon "{weapon}" is not defined')
weapon_ = NewWeapon()
# Set weapon attributes based on character
if weapon_.is_finesse:
+3
View File
@@ -1,3 +1,6 @@
class CharacterFileFormatError(ValueError):
"""The given file is not a valid Dungeons and Dragons file."""
class DiceError(ValueError):
"""Improper formatting for a dice string."""
+23 -1
View File
@@ -7,6 +7,7 @@ import importlib.util
import os
import subprocess
import warnings
import re
from fdfgen import forge_fdf
@@ -43,6 +44,19 @@ def load_character_file(filename):
module_name, ext = os.path.splitext(fname)
if ext != '.py':
raise ValueError(f"Character definition {filename} is not a python file.")
# Check if this file contains the version string
version_re = re.compile('dungeonsheets_version\s*=\s*[\'"]([0-4.]+)[\'"]')
with open(filename, mode='r') as f:
version = None
for line in f:
match = version_re.match(line)
if match:
version = match.group(1)
break
if version is None:
# Not a valid DND character file
raise exceptions.CharacterFileFormatError(
"No ``dungeonsheets_version = `` entry.")
# Import the module to extract the information
spec = importlib.util.spec_from_file_location('module', filename)
module = importlib.util.module_from_spec(spec)
@@ -265,7 +279,10 @@ def create_character_pdf(character, basename, flatten=False):
}
# Add skill proficienies
for skill in character.skill_proficiencies:
fields.append((skill_boxes[skill.replace(' ', '_')], 'Yes'))
try:
fields.append((skill_boxes[skill.replace(' ', '_').lower()], 'Yes'))
except KeyError:
raise KeyError(f"Unknown skill: '{skill}'")
# Add weapons
weapon_fields = [('Wpn Name', 'Wpn1 AtkBonus', 'Wpn1 Damage'),
('Wpn Name 2', 'Wpn2 AtkBonus ', 'Wpn2 Damage '),
@@ -368,6 +385,11 @@ def main():
print(f"Processing {os.path.splitext(filename)[0]}...", end='')
try:
make_sheet(character_file=filename, flatten=(not args.editable))
except exceptions.CharacterFileFormatError as e:
# Only raise the failed exception if this file is explicitly given
print('invalid')
if args.filename:
raise
except Exception as e:
print('failed')
raise
Binary file not shown.
+3
View File
@@ -1,3 +1,6 @@
dungeonsheets_version = "0.4.2"
# Basic information
name = 'Mr. Stabby'
character_class = 'rogue'
player_name = 'Mike'
Binary file not shown.
+3
View File
@@ -1,3 +1,6 @@
dungeonsheets_version = "0.4.2"
# Basic information
name = 'Sid Istick'
character_class = 'Warlock'
player_name = 'Mark'
Binary file not shown.
+6 -3
View File
@@ -1,3 +1,6 @@
dungeonsheets_version = "0.4.2"
# Basic information
name = 'Inara Serradon'
character_class = 'wizard'
player_name = 'Mark'
@@ -15,6 +18,8 @@ constitution = 14
intelligence = 16
wisdom = 12
charisma = 8
# Proficiencies and languages
skill_proficiencies = [
'arcana',
'insight',
@@ -22,8 +27,6 @@ skill_proficiencies = [
'perception',
'religion',
]
# Proficiencies and languages
languages = "Common, Elvish, Draconic, Dwarvish, Goblin."
# Inventory
@@ -42,7 +45,7 @@ equipment = (
# List of known spells
spells = ('blindness deafness', 'burning hands', 'detect magic',
'false life', 'mage armor', 'mage hand', 'magic missile',
'falsee life', 'mage armor', 'mage hand', 'magic missile',
'prestidigitation', 'ray of frost', 'ray of sickness', 'shield',
'shocking grasp', 'sleep',)
# Which spells have been prepared (not including cantrips)
+1
View File
@@ -3,3 +3,4 @@ fdfgen>=0.16
npyscreen
jinja2
pytest
sphinx