Typesetting TRPG Character Sheets #1407
-
First of all, I am really impressed by the effort put into SILE and it looks like a serious contender to replace my future LaTeX needs. Especially the cleaner syntax, Lua scripting options and XML support do fit my needs much better. I am trying to improve the quality of tabletop RPG character sheets. Typesetting in character sheets is usually pretty weak. Many sheets use form fileable text fields which produces very bad results. For my project I have a Python "character" class that includes all properties of the particular character. I want to run that into a PDF for print. Being able to feed SILE XML documents sounds like an amazing way to setup such a pipeline. Sadly, after reading the documentation and looked at the awesome packages from @Omikhleia I am very much in doubt if this is a possible thing to do. In LaTeX I am currently hacking together a sheet using tcbposterbox. This works reasonably well, but is hacky, and don't even get started about styling the boxes or laying out text within them. And if I figure this out, parsing it into .tex or LuaTex still sounds nightmarish. So I want to give SILE a try, potentially even writing my own class if that's what's needed to get the job done. The question is however how one would achieve placing boxes(if that's the correct terminology) in a grid like structure to then fill them with text. I guess @Omikhleia framebox could be a good start to actually typeset the individual "boxes" and to decorate them. My discussion is a bit broad, but I would like to pick your thoughts if this is something SILE can do already, or if not, if you believe it can be done with a new package or class? If it's something that can be created relatively elegant, I would consider actually implementing it. Other solutions (outside of SILE) would also be welcome. |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 2 replies
-
For clarification, this is how a typical character sheet looks. Being able to recreate this would be a major achievement: Note the complexities in a sheet like this for typesetting. A "simple" table wouldn't suffice. Some boxes contain multiple boxes, multiple lines, text at various positions etc... |
Beta Was this translation helpful? Give feedback.
-
I'll leave @Omikhleia to comment on the state of box drawing, I haven't even fully delved into his frame drawing package (although it is certainly in the SILE release timeline even if it may not make the next release which I'm pushing through soon). It's possible some adaptations there could get these boxes drawn (although the variations here lend weight to my suggest of moving the graphics bits out of the SILE package and into a Lua library so that they could be more easily iterated on). But besides that package I have two other things to suggest:
In any case writing a class for SILE is not a daunting task of last resort, it should be the first thing to consider when working on a project with unique needs like this one. It's no a book, it's not a letter, and it isn't plain: so write a class that has the frames you want, the commands you want to output consistent label typesetting, etc. A functional class in about 8 lines of Lua, then each command you add, each frame you add by default, etc. is just time saved from doing the same thing over and over later. That being said if you do experiment I recommend SILE's HEAD version because those 8 lines of class boiler plate are about to change between 0.12.x and 0.13.x and you might as well have a jump on the change. The consistency and documentation are already better in HEAD anyway. You can also use @Omikhleia's PR and compile from that branch for experiments. By the way is that sheet a final thing or just a template? As in does that get filled in with content or are you just looking form the template sheets like that? Does the layout over change? E.g. if there were more skills than fit in that frame would the frames all need to adjust to fit the content? Or would the content be made to fit the frame (i.e. shrink fonts until it fits or something like that)? |
Beta Was this translation helpful? Give feedback.
-
Wow, what an amazing answer.
The template linked is a blank sheet. The player would indeed fill information and change it during gameplay. Traditionally this would be done with a pencil and eraser (they are also sometimes called Pen and Paper RPGs). Nowadays, more and more players use digital tools (like D&DBeyond) to track their character, which can also output to (ugly typeset) PDF. These PDFs are not very customizable, only available in English, in one font and fontsize. Next to looks, having greater control over the output also helps with accesibility (translations, dyslexia friendly fonts, bigger fonts for visually impaired etc...). Text shrinking down to fit the box would be a huge plus. You never know how much information a player wants to write down. Changing the layout is a feature that would be the end-game for this project as that would allow for ultimate personalization. Taking this into account, your first suggestion might actually be the best way to go. I noticed SILE is fast enough to support such a pipeline. Then I have the best of both worlds (SILE for typesetting, IM for page layout). I think fitting such demanding layout requirements into any typesetting engine will never get me the elegance that I am trying to maintain by only picking one tool. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Once again the things that Omikhleia is able to do with SILE amazes me. :-) If I was trying to do this I would reach for frames straight away. This is exactly the sort of thing they were designed for - putting content into different boxes on different parts of the page where you know in advance their size and position relative to one another. Resizing text to fit into a box is something we can do already (in the fontproof package). I think with a little work you can have a SILE class which takes an XML description of a character's state and typesets it into a character sheet. My daughter and I are currently putting together our first D&D campaign, and so we might actually need this sort of thing ourselves. :-) |
Beta Was this translation helpful? Give feedback.
-
I followed @alerque advice on using ImageMagick which partially achieves my goal. A minimal working example.
Big drawback is that ImageMagick converts to a image format and therefore text is no longer searchable or selectable in the final PDF. I will have to have a look if there's a package that can achieve this while keeping PDF text, otherwise this is already a much better option then what I did before. |
Beta Was this translation helpful? Give feedback.
-
This only tangentially related to the original question, but as far as TRPG are concerned and SILE is used, I just came across these Mastodon posts by mere accident1 Digging quickly, I think this is @PietroCarrara on GitHub, with a related repository: a custom class with non-obvious page layout, some support packages and examples. Cool to see such attempts! 😻 Footnotes
|
Beta Was this translation helpful? Give feedback.
-
Yes, that's me! Getting the math to work on rotating the text was a pain, but I did hack something together. The more complex layouts, such as the attribute boxes, have been designed in inkscape. Then the lua code comes in, replaces some text and renders that into a png. I then insert this image into the output PDF. It does sound ugly (and is), but it's pretty versatile. self:registerCommand("attribute", function (opts, content)
local file = assert(io.open(SILE.resolveFile("svg/attribute.svg"), "r"))
local contents = file:read("a")
file:close()
if opts.name then
contents = contents:gsub("@NAME@", opts.name)
end
if opts.mod then
contents = contents:gsub("@MOD@", opts.mod)
end
if opts.condition then
contents = contents:gsub("@CONDITION@", opts.condition)
end
local svgfname = "/tmp/attribute.svg"
local svgfile = assert(io.open(svgfname, "w+"))
svgfile:write(contents)
svgfile:close()
local outfname = "/tmp/" .. tmpFileCounter .. ".png"
local infname = svgfname
tmpFileCounter = tmpFileCounter + 1
-- Very, VERY unsafe, but it's the best I've got
os.execute("inkscape \""..infname.."\" -o \""..outfname.."\" 2>/dev/null")
opts.src = outfname
SILE.call("fig", opts, content)
end) |
Beta Was this translation helpful? Give feedback.
Yes, that's me! Getting the math to work on rotating the text was a pain, but I did hack something together.
The more complex layouts, such as the attribute boxes, have been designed in inkscape. Then the lua code comes in, replaces some text and renders that into a png. I then insert this image into the output PDF. It does sound ugly (and is), but it's pretty versatile.