naturalcrit / homebrewery

Create authentic looking D&D homebrews using only markdown
https://homebrewery.naturalcrit.com
MIT License
1.1k stars 326 forks source link

Idea: More flexible styling of blockquotes and lists (e.g. for card templates) #348

Closed Rae2che5 closed 3 years ago

Rae2che5 commented 7 years ago

This is a suggestion inspired by #212 -- @ryantheleach's request for printable card templates in the Homebrewery. @wrdclark did some great work mocking up some styles for cards based on <div class='card'>, but unfortunately, as @vlos observed, deeply nested <div> tags tend to switch the markdown parser into HTML mode, and thus lose the ability to use nice markdown formatting.

Looking into this, I discovered @stolksdorf's cool trick of styling lists differently if they immediately follow a <hr>, and I couldn't help thinking that this would also be useful for cards, allowing us to nest their content in a <blockquote> and not a <div> and thus preserve markdown formatting.

Unfortunately, there's only one kind of <hr/> tag, and so we need something else to attach styling to. This is where we can exploit two facts: Firstly, <h6> are currently unstyled and hence almost definitely unused; secondly, marked (our Markdown parser) generates IDs for the <h6> tags based on the text of the heading. To make a long story short, here's a bit of markup:

###### card
> ### Goblin
>
> <img src="http://i.imgur.com/ET6Hp6D.png" style="height: 5cm;"/>
>___
>|STR|DEX|CON|INT|WIS|CHA|
>|:---:|:---:|:---:|:---:|:---:|:---:|
>|8 (-1)|14 (+2)|10 (+0)|10 (+0)|8 (-1)|8 (-1)|
>___
> <div class='descriptive'>
> - All markdown formatting works.
> - Even nested lists.
>   - And sublists.
> </div>
>

And here's how it could render: image.

The key trick is to write selectors that begin with h6[id|='card'] + blockquote, meaning "the blockquote immediately following the <h6> tag whose ID starts with card". In particular, this also allows different styles of card -- ###### card back could, for example, rotate the card by 180 degrees, so that you can simply fold to get a standee/tent.

For a more complete picture, including the CSS in its current form, please see this brew. (Full disclosure: Due to what seems like a Chrome bug, currently the rotated cards are not displayed in the PDF view in columns after the first (even to get them to render in the browser, I had to add the spurious translateZ(0) to the transform). Any suggestions for what may be going wrong would be very welcome.)

Once I got this far, I realized that this also has the potential of cutting down on some boilerplate. For example, when defining a spell, there's the spell kind plus four other properties that always appear in the same order. The current template includes them in the markdown that the user writes, but conceivably we could hide them in the stylesheet and simply require the user to enter the things that actually vary:

###### spell
#### Illusionary Transfiguration of the Babysitter
- 7th-level transmutation
- 1 action
- 60 feet
- M (discarded gum wrapper, a small doll, a crushed button worth at least 1cp)
- Instantaneous
- A flame, equivalent in brightness to a torch, springs from from an object that you touch. 
  The effect look like a regular flame, but it creates no heat and doesn't use oxygen. 
  A *continual flame* can be covered or hidden but not smothered or quenched.

For a stylesheet that makes this equivalent to the current spell snippet, see this brew. Similarly, when defining class features, there are sections on hit points and proficiencies that are very formulaic; see this brew for a possible way of condensing that.

It seems that using <h6> headings plus blockquotes or lists in this way allows us to style markdown in radically different ways without requiring too many contortions. What do you think?

stolksdorf commented 7 years ago

Thanks for the excellent write-up. Leveraging successive elements to trigger different styling gets very frustrating very fast. The current markup for Homebrewery uses this everywhere and creating consistent rules is difficult. For example, an <hr /> before some elements makes it 2 columns wide, for others it changes colors, and in some situations it actually behaves as a <hr />. The core issue is that there are more elements in the PHB than there are in Markdown. So if you stick to just straight Markdown, you'll always have to do lil tricks and any time to add or tweak something it has the opportunity of breaking something else to you didn't expect.

Secondly, parsing HTML nested in Markdown, or vice versa (or however nested you want to go) is very tricky. HTML is not a well defined spec and this allows users to write bad code that cascades errors down into other pages sometimes. Not closing tags properly can leave parts of the brew not rendering with not apparent explanation. It's even possible to bug out The Homebrewery itself, making the brew uneditable and undeletable.

So to solve all these issues, I am removing the ability to write HTML in brews in v3. I am adding a new Markdown syntax to the Homebrewery parser that allows the user to create simple, classed divs. eg.

{{classTable,wide
....
}}

Creates a wide class table.

{{note,alt,teal
....
}}

Create a note with the alternative border and background of teal.

I really like the idea of monster cards and your design. I'll add it to the todo list of things to add. With this new syntax those cards could be added by going, {{card ...

Rae2che5 commented 7 years ago

Thanks for the response. Indeed, I noticed the overloaded use of <hr/>, and how it potentially makes some things confusing. The idea of ###### label followed by a blockquote is basically a way of getting an arbitrarily annotatable block element out of ordinary markdown. This would allow us to capture the variety of elements in the PHB just by marking blockquotes with different headings.

I'm intrigued by your plans for making this stuff more explicit -- that always tends to be better than implicit conventions. I haven't seen the proposed syntax elsewhere, though. Is it a standard Markdown extension, or something you're thinking about purely in the context of the Homebrewery?

Is your work towards v3 pushed as a branch somewhere? I'd be very curious to play with it.

stolksdorf commented 7 years ago

The proposed syntax is just for Homebrewery. I've written a modification to the markdown parser which allows it.

There's a v3 branch on this repo, but don't expect it to work, be up to date, or be stable.

calculuschild commented 7 years ago

@Rae2che5 The flipped cards not printing correctly seems to be related to the phb class "overflow:hidden". Changing it to <style>.phb {overflow:visible}</style> fixes the issue, and I don't actually see any bad repercussions from changing it, although there must be some reason it was set to hidden in the first place.

Rae2che5 commented 7 years ago

@calculuschild -- hah, perfect. Indeed that does fix it! If you don't mind me asking, how did you figure it out? I wasn't seeing anything relevant in the dom inspection/combined style tools, though I was looking at the images directly rather than at .phb.

I suspect the reason for overflow:hidden on .phb in general is to ensure that nothing renders "off-page"; we're building up fake A4 pages here. It shouldn't hurt, if I manually break pages as appropriate.

calculuschild commented 7 years ago

well, i first tried duplicating your cards offline by hand and they were working totally fine, so i figured there must be something in the css causing issues. Theres a bundled css file somewhere on this github that I downloaded, and proceeded to strip down to bare bones. Then I literally just started deleting large chunks until the error was gone and eventually zeroed in on that phb class and found the line that was causing it. With it rendering fine in the browser I had no idea what would cause printing to be broken so that seemed the quickest way to do it. :P

Rae2che5 commented 7 years ago

Makes sense. I think I looked for print-based special cases, since it was rendering fine in the browser window (and I still don't quite understand why the print view looks different). Should have tried the elimination approach...

Rae2che5 commented 6 years ago

@stolksdorf I was thinking about this again. I've had reasonable success with the kind of style sheet described in the original post, but have indeed run into a few cases where the selectors would get quite complex, and having nested containers would be really handy.

Are you still planning to work on the v3 branch? What's the status there, and is there anything in particular you need help with?

Regarding the syntax you proposed, it's worth noting that fenced divs have recently been added to Pandoc, and the same syntax has been implemented as a markdown-it plugin. Is it perhaps worth considering adopting that syntax before introducing a custin {{..}}-based thing?

The examples you gave would look as follows:

::: {.classTable .wide }
markdown-content
::::::::::::::

::::::: { .note .alt .teal }
::: { .note-table}
| nested-note-table |
::::::
:::::::::
calculuschild commented 3 years ago

Added to the V3 changelog finally. Closing.

ryantheleach commented 3 years ago

I've read the changelog, but 4 years onwards it's not enough to jump in and use the feature as an end user and not a developer.

This could likely be fixed by some decent examples, if they don't already exist.

calculuschild commented 3 years ago

@ryantheleach The core issue here was resolved (more flexible styling) and you can see several examples by looking at the Snippets available in V3, as well as taking a look at the V3 welcome page here: https://homebrewery.naturalcrit.com/v3_preview

We have not officially created a card layout if that is what you are looking for, but that may be something we add in the future, and you can certainly ask around on the subreddit https://www.reddit.com/r/homebrewery because I know some people have done things like that before.

Gazook89 commented 3 years ago

@ryantheleach if you are looking for MtG cards, here is a brew I put together after lots of experimenting. However, this is pre-v3 which isn't really a problem because we kept the Legacy renderer as well. I do have other brew documents that are different attempts to make cards (such as this, and this) as well.

I'm not going to say it's 100% straightforward, but it is an option and does demonstrate the flexibility of homebrewery (even before v3).

That said, further development can happen for different layouts in the future as @calculuschild says and hopefully it just gets easier.